This commit is contained in:
zhangkun9038@dingtalk.com 2025-02-16 20:28:47 +08:00
parent ae75582d11
commit 3cc2b18081
16 changed files with 413 additions and 128 deletions

View File

@ -5,12 +5,20 @@ import (
"strconv"
)
type DBConfig struct {
Host string
Port int
User string
Password string
Name string
}
func (db *DBConfig) DSN() string {
return db.User + ":" + db.Password + "@tcp(" + db.Host + ":" + strconv.Itoa(db.Port) + ")/" + db.Name + "?charset=utf8mb4&parseTime=True&loc=Local"
}
type Config struct {
DBHost string
DBPort int
DBUser string
DBPassword string
DBName string
DB DBConfig
JWTSecret string
RedisHost string
RedisPort int
@ -21,11 +29,13 @@ var AppConfig Config
func Init() {
AppConfig = Config{
DBHost: getEnv("DB_HOST", "localhost"),
DBPort: getEnvAsInt("DB_PORT", 3306),
DBUser: getEnv("DB_USER", "root"),
DBPassword: getEnv("DB_PASSWORD", ""),
DBName: getEnv("DB_NAME", "rbac"),
DB: DBConfig{
Host: getEnv("DB_HOST", "localhost"),
Port: getEnvAsInt("DB_PORT", 3306),
User: getEnv("DB_USER", "root"),
Password: getEnv("DB_PASSWORD", ""),
Name: getEnv("DB_NAME", "rbac"),
},
JWTSecret: getEnv("JWT_SECRET", "secret"),
RedisHost: getEnv("REDIS_HOST", "localhost"),
RedisPort: getEnvAsInt("REDIS_PORT", 6379),

View File

@ -3,6 +3,7 @@ package controllers
import (
"gitea.zjmud.xyz/phyer/rbac/services"
"github.com/gin-gonic/gin"
"strconv"
)
// CreateRole 创建新角色
@ -93,6 +94,63 @@ func AssignPermissionToRole(c *gin.Context) {
c.JSON(200, gin.H{"message": "Permission assigned successfully"})
}
// GetPermission 获取单个权限
func GetPermission(c *gin.Context) {
id := c.Param("id")
permissionID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid permission ID"})
return
}
permission, err := services.GetPermissionByID(uint(permissionID))
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, permission)
}
// UpdatePermission 更新权限
func UpdatePermission(c *gin.Context) {
id := c.Param("id")
permissionID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid permission ID"})
return
}
var updateData map[string]interface{}
if err := c.ShouldBindJSON(&updateData); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
permission, err := services.UpdatePermission(uint(permissionID), updateData)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, permission)
}
// DeletePermission 删除权限
func DeletePermission(c *gin.Context) {
id := c.Param("id")
permissionID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid permission ID"})
return
}
err = services.DeletePermission(uint(permissionID))
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"message": "Permission deleted successfully"})
}
// GetPermissions 获取所有权限
func GetPermissions(c *gin.Context) {
permissions, err := services.GetAllPermissions()
@ -102,3 +160,60 @@ func GetPermissions(c *gin.Context) {
}
c.JSON(200, permissions)
}
// GetRole 获取单个角色
func GetRole(c *gin.Context) {
id := c.Param("id")
roleID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid role ID"})
return
}
role, err := services.GetRoleByID(uint(roleID))
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, role)
}
// UpdateRole 更新角色
func UpdateRole(c *gin.Context) {
id := c.Param("id")
roleID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid role ID"})
return
}
var updateData map[string]interface{}
if err := c.ShouldBindJSON(&updateData); err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
role, err := services.UpdateRole(uint(roleID), updateData)
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, role)
}
// DeleteRole 删除角色
func DeleteRole(c *gin.Context) {
id := c.Param("id")
roleID, err := strconv.ParseUint(id, 10, 64)
if err != nil {
c.JSON(400, gin.H{"error": "Invalid role ID"})
return
}
err = services.DeleteRole(uint(roleID))
if err != nil {
c.JSON(500, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"message": "Role deleted successfully"})
}

18
main.go
View File

@ -1,3 +1,4 @@
<<<<<<< HEAD
package main
import (
@ -13,6 +14,23 @@ func main() {
api.SetupRoutes(r)
r.Run(":8080")
}
=======
package main
import (
"gitea.zjmud.xyz/phyer/rbac/api"
"gitea.zjmud.xyz/phyer/rbac/config"
"gitea.zjmud.xyz/phyer/rbac/server"
)
func main() {
config.Init()
server.InitDB()
r := server.NewServer()
api.SetupRoutes(r)
r.Run(":8080")
}
>>>>>>> Snippet
// package main
//

View File

@ -5,6 +5,11 @@ import (
"github.com/gin-gonic/gin"
)
// JWTAuth is an alias for AuthMiddleware
func JWTAuth() gin.HandlerFunc {
return AuthMiddleware()
}
func AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
token := c.GetHeader("Authorization")

View File

@ -1,11 +1,12 @@
package models
import (
"gorm.io/gorm"
"time"
)
type User struct {
ID string `json:"id" gorm:"primaryKey"`
gorm.Model
Username string `json:"username" gorm:"uniqueIndex;not null"`
Password string `json:"-" gorm:"not null"`
Email string `json:"email" gorm:"uniqueIndex;not null"`

BIN
rbac Executable file

Binary file not shown.

View File

@ -2,15 +2,17 @@ package repositories
import (
"gitea.zjmud.xyz/phyer/rbac/config"
"gitea.zjmud.xyz/phyer/rbac/models"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"strconv"
)
var db *gorm.DB
func InitDB() error {
var err error
dsn := config.AppConfig.DBUser + ":" + config.AppConfig.DBPassword + "@tcp(" + config.AppConfig.DBHost + ":" + strconv.Itoa(config.AppConfig.DBPort) + ")/" + config.AppConfig.DBName + "?charset=utf8mb4&parseTime=True&loc=Local"
dsn := config.AppConfig.DB.User + ":" + config.AppConfig.DB.Password + "@tcp(" + config.AppConfig.DB.Host + ":" + strconv.Itoa(config.AppConfig.DB.Port) + ")/" + config.AppConfig.DB.Name + "?charset=utf8mb4&parseTime=True&loc=Local"
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
return err

View File

@ -1,87 +1,55 @@
package repositories
import (
"gitea.zjmud.xyz/phyer/rbac/models"
"gorm.io/gorm"
"gitea.zjmud.xyz/phyer/rbac/models"
"gorm.io/gorm"
)
func CreatePermission(permission *models.Permission) (*models.Permission, error) {
result := db.Create(permission)
return permission, result.Error
}
func GetPermissionByID(id uint) (*models.Permission, error) {
var permission models.Permission
result := db.First(&permission, id)
return &permission, result.Error
var permission models.Permission
result := db.First(&permission, id)
return &permission, result.Error
}
func GetPermissions() ([]models.Permission, error) {
var permissions []models.Permission
result := db.Find(&permissions)
return permissions, result.Error
var permissions []models.Permission
result := db.Find(&permissions)
return permissions, result.Error
}
func UpdatePermission(id uint, updateData map[string]interface{}) (*models.Permission, error) {
var permission models.Permission
result := db.Model(&permission).Where("id = ?", id).Updates(updateData)
if result.Error != nil {
return nil, result.Error
}
return GetPermissionByID(id)
var permission models.Permission
result := db.Model(&permission).Where("id = ?", id).Updates(updateData)
if result.Error != nil {
return nil, result.Error
}
return GetPermissionByID(id)
}
func DeletePermission(id uint) error {
result := db.Delete(&models.Permission{}, id)
return result.Error
}
func CheckPermissionExists(name string) (bool, error) {
var count int64
result := db.Model(&models.Permission{}).Where("name = ?", name).Count(&count)
return count > 0, result.Error
}
package repositories
import (
"gitea.zjmud.xyz/phyer/rbac/models"
"gorm.io/gorm"
)
func CreatePermission(permission *models.Permission) (*models.Permission, error) {
result := db.Create(permission)
return permission, result.Error
}
func GetPermissionByID(id uint) (*models.Permission, error) {
var permission models.Permission
result := db.First(&permission, id)
return &permission, result.Error
}
func GetPermissions() ([]models.Permission, error) {
var permissions []models.Permission
result := db.Find(&permissions)
return permissions, result.Error
}
func UpdatePermission(id uint, updateData map[string]interface{}) (*models.Permission, error) {
var permission models.Permission
result := db.Model(&permission).Where("id = ?", id).Updates(updateData)
if result.Error != nil {
return nil, result.Error
}
return GetPermissionByID(id)
result := db.Create(permission)
return permission, result.Error
}
func DeletePermission(id uint) error {
result := db.Delete(&models.Permission{}, id)
return result.Error
result := db.Delete(&models.Permission{}, id)
return result.Error
}
func CheckPermissionExists(name string) (bool, error) {
var count int64
result := db.Model(&models.Permission{}).Where("name = ?", name).Count(&count)
return count > 0, result.Error
var count int64
result := db.Model(&models.Permission{}).Where("name = ?", name).Count(&count)
return count > 0, result.Error
}
func AssignRoleToUser(userID uint, roleID uint) error {
user := &models.User{Model: gorm.Model{ID: userID}}
role := &models.Role{Model: gorm.Model{ID: roleID}}
return db.Model(user).Association("Roles").Append(role)
}
func RemoveRoleFromUser(userID uint, roleID uint) error {
user := &models.User{Model: gorm.Model{ID: userID}}
role := &models.Role{Model: gorm.Model{ID: roleID}}
return db.Model(user).Association("Roles").Delete(role)
}

View File

@ -10,12 +10,30 @@ func CreateRole(role *models.Role) (*models.Role, error) {
return role, result.Error
}
func GetAllRoles() ([]models.Role, error) {
var roles []models.Role
result := db.Find(&roles)
return roles, result.Error
}
func GetRoleByID(id uint) (*models.Role, error) {
var role models.Role
result := db.Preload("Permissions").First(&role, id)
result := db.First(&role, id)
return &role, result.Error
}
func CheckRoleExists(name string) (bool, error) {
var count int64
result := db.Model(&models.Role{}).Where("name = ?", name).Count(&count)
return count > 0, result.Error
}
func AddPermissionToRole(roleID, permissionID uint) error {
role := &models.Role{Model: gorm.Model{ID: roleID}}
permission := &models.Permission{Model: gorm.Model{ID: permissionID}}
return db.Model(role).Association("Permissions").Append(permission)
}
func GetRoles() ([]models.Role, error) {
var roles []models.Role
result := db.Preload("Permissions").Find(&roles)
@ -36,16 +54,6 @@ func DeleteRole(id uint) error {
return result.Error
}
func CheckRoleExists(name string) (bool, error) {
var count int64
result := db.Model(&models.Role{}).Where("name = ?", name).Count(&count)
return count > 0, result.Error
}
func AddPermissionToRole(roleID uint, permissionID uint) error {
return db.Model(&models.Role{Model: gorm.Model{ID: roleID}}).Association("Permissions").Append(&models.Permission{Model: gorm.Model{ID: permissionID}})
}
func RemovePermissionFromRole(roleID uint, permissionID uint) error {
return db.Model(&models.Role{Model: gorm.Model{ID: roleID}}).Association("Permissions").Delete(&models.Permission{Model: gorm.Model{ID: permissionID}})
}

View File

@ -1,20 +1,25 @@
package repositories
import (
"gitea.zjmud.xyz/phyer/rbac/config"
"gitea.zjmud.xyz/phyer/rbac/models"
"gorm.io/gorm"
// "gorm.io/gorm"
)
var db *gorm.DB
func InitDB() error {
var err error
db, err = gorm.Open(mysql.Open(config.GetDSN()), &gorm.Config{})
if err != nil {
return err
func CheckUserPermission(userID string, permission string) (bool, error) {
var user models.User
result := db.Preload("Roles.Permissions").Where("id = ?", userID).First(&user)
if result.Error != nil {
return false, result.Error
}
return db.AutoMigrate(&models.User{})
for _, role := range user.Roles {
for _, perm := range role.Permissions {
if perm.Name == permission {
return true, nil
}
}
}
return false, nil
}
func GetAllUsers() ([]models.User, error) {

View File

@ -2,9 +2,30 @@ package server
import (
"gitea.zjmud.xyz/phyer/rbac/api"
"gitea.zjmud.xyz/phyer/rbac/config"
"github.com/gin-gonic/gin"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
var db *gorm.DB
// InitDB initializes the database connection
func InitDB() {
var err error
dsn := config.AppConfig.DB.DSN()
db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}
}
// NewServer creates and returns a new Gin server
func NewServer() *gin.Engine {
r := gin.Default()
return r
}
func Start() {
r := gin.Default()

View File

@ -2,10 +2,11 @@ package services
import (
"errors"
"gitea.zjmud.xyz/phyer/rbac/models"
// "gitea.zjmud.xyz/phyer/rbac/models"
"gitea.zjmud.xyz/phyer/rbac/repositories"
"gitea.zjmud.xyz/phyer/rbac/utils"
"golang.org/x/crypto/bcrypt"
"strconv"
)
func Login(username, password string) (string, error) {
@ -17,7 +18,7 @@ func Login(username, password string) (string, error) {
if err != nil {
return "", errors.New("invalid credentials")
}
token, err := utils.GenerateJWT(user.ID)
token, err := utils.GenerateJWT(strconv.FormatUint(uint64(user.ID), 10))
if err != nil {
return "", err
}

View File

@ -4,12 +4,13 @@ import (
"errors"
"gitea.zjmud.xyz/phyer/rbac/models"
"gitea.zjmud.xyz/phyer/rbac/repositories"
"strconv"
)
// AssignRoleToUser 为用户分配角色
func AssignRoleToUser(userID string, roleID uint) error {
func AssignRoleToUser(userID uint, roleID uint) error {
// 检查用户是否存在
user, err := repositories.GetUserByID(userID)
user, err := repositories.GetUserByID(strconv.FormatUint(uint64(userID), 10))
if err != nil {
return errors.New("user not found")
}
@ -25,9 +26,9 @@ func AssignRoleToUser(userID string, roleID uint) error {
}
// RemoveRoleFromUser 移除用户的角色
func RemoveRoleFromUser(userID string, roleID uint) error {
func RemoveRoleFromUser(userID uint, roleID uint) error {
// 检查用户是否存在
user, err := repositories.GetUserByID(userID)
user, err := repositories.GetUserByID(strconv.FormatUint(uint64(userID), 10))
if err != nil {
return errors.New("user not found")
}
@ -71,6 +72,131 @@ func CreateRoleWithPermissions(roleName string, permissionIDs []uint) (*models.R
return role, nil
}
// CreateRole 创建新角色
func CreateRole(name, description string) (*models.Role, error) {
// 检查角色是否已存在
exists, err := repositories.CheckRoleExists(name)
if err != nil {
return nil, err
}
if exists {
return nil, errors.New("role already exists")
}
// 创建角色
role := &models.Role{
Name: name,
}
return repositories.CreateRole(role)
}
// GetAllRoles 获取所有角色
func GetAllRoles() ([]models.Role, error) {
return repositories.GetAllRoles()
}
// CreatePermission 创建新权限
func CreatePermission(name, description, resource, action string) (*models.Permission, error) {
// 检查权限是否已存在
exists, err := repositories.CheckPermissionExists(name)
if err != nil {
return nil, err
}
if exists {
return nil, errors.New("permission already exists")
}
// 创建权限
permission := &models.Permission{
Name: name,
Resource: resource,
Action: action,
}
return repositories.CreatePermission(permission)
}
// AssignPermissionToRole 为角色分配权限
func AssignPermissionToRole(roleID, permissionID uint) error {
// 检查角色是否存在
_, err := repositories.GetRoleByID(roleID)
if err != nil {
return errors.New("role not found")
}
// 检查权限是否存在
_, err = repositories.GetPermissionByID(permissionID)
if err != nil {
return errors.New("permission not found")
}
// 分配权限
return repositories.AddPermissionToRole(roleID, permissionID)
}
// GetAllPermissions 获取所有权限
func GetAllPermissions() ([]models.Permission, error) {
return repositories.GetPermissions()
}
// GetRoleByID 根据ID获取角色
func GetRoleByID(roleID uint) (*models.Role, error) {
return repositories.GetRoleByID(roleID)
}
// UpdateRole 更新角色
func UpdateRole(roleID uint, updateData map[string]interface{}) (*models.Role, error) {
// 检查角色是否存在
_, err := repositories.GetRoleByID(roleID)
if err != nil {
return nil, errors.New("role not found")
}
// 更新角色
return repositories.UpdateRole(roleID, updateData)
}
// DeleteRole 删除角色
func DeleteRole(roleID uint) error {
// 检查角色是否存在
_, err := repositories.GetRoleByID(roleID)
if err != nil {
return errors.New("role not found")
}
// 删除角色
return repositories.DeleteRole(roleID)
}
// GetPermissionByID 根据ID获取权限
func GetPermissionByID(permissionID uint) (*models.Permission, error) {
return repositories.GetPermissionByID(permissionID)
}
// UpdatePermission 更新权限
func UpdatePermission(permissionID uint, updateData map[string]interface{}) (*models.Permission, error) {
// 检查权限是否存在
_, err := repositories.GetPermissionByID(permissionID)
if err != nil {
return nil, errors.New("permission not found")
}
// 更新权限
return repositories.UpdatePermission(permissionID, updateData)
}
// DeletePermission 删除权限
func DeletePermission(permissionID uint) error {
// 检查权限是否存在
_, err := repositories.GetPermissionByID(permissionID)
if err != nil {
return errors.New("permission not found")
}
// 删除权限
return repositories.DeletePermission(permissionID)
}
// CheckUserPermission 检查用户是否具有特定权限
// CheckUserPermission 检查用户是否具有特定权限
func CheckUserPermission(userID string, permission string) (bool, error) {
// 获取用户的所有角色

View File

@ -3,7 +3,7 @@ package services
import (
"gitea.zjmud.xyz/phyer/rbac/models"
"gitea.zjmud.xyz/phyer/rbac/repositories"
"gitea.zjmud.xyz/phyer/rbac/utils"
// "gitea.zjmud.xyz/phyer/rbac/utils"
"golang.org/x/crypto/bcrypt"
)

View File

@ -1,37 +1,41 @@
.
├── api
└── routes.go
   └── routes.go
├── config
└── config.go
   └── config.go
├── controllers
├── auth.go
├── rbac.go
└── user.go
   ├── auth.go
   ├── rbac.go
   └── user.go
├── go.mod
├── go.sum
├── main.go
├── middleware
├── auth.go
└── rbac.go
   ├── auth.go
   └── rbac.go
├── models
│ ├── permission.go
│ ├── role.go
│ ├── user.go
│ └── user_group.go
│   ├── permission.go
│   ├── role.go
│   ├── user.go
│   └── user_group.go
├── rbac
├── repositories
│ ├── permission.go
│ ├── role.go
│ ├── user.go
│ └── user_group.go
│   ├── db.go
│   ├── permission.go
│   ├── role.go
│   ├── user.go
│   └── user_group.go
├── server
└── server.go
   └── server.go
├── services
│ ├── auth.go
│ ├── rbac.go
│ └── user.go
├── utils
│ ├── jwt.go
│ ├── redis.go
│ └── response.go
│   ├── auth.go
│   ├── rbac.go
│   └── user.go
├── sug.md
└── tree.txt
├── tree.txt
└── utils
├── jwt.go
├── redis.go
└── response.go
10 directories, 29 files

View File

@ -1,6 +1,7 @@
package utils
import (
"errors"
"gitea.zjmud.xyz/phyer/rbac/config"
"github.com/golang-jwt/jwt/v5"
"time"