mirror of
https://github.com/tiger1103/gfast.git
synced 2026-09-21 10:12:59 +00:00
整合casbin添加adapter处理器
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
*.js linguist-language=GO
|
||||||
|
*.css linguist-language=GO
|
||||||
|
*.html linguist-language=GO
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
.buildpath
|
||||||
|
.hgignore.swp
|
||||||
|
.project
|
||||||
|
.orig
|
||||||
|
.swp
|
||||||
|
.idea/
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
vender/
|
||||||
|
log/
|
||||||
|
composer.lock
|
||||||
|
gitpush.sh
|
||||||
|
pkg/
|
||||||
|
bin/
|
||||||
|
cbuild
|
||||||
|
*/.DS_Store
|
||||||
|
config/config.toml
|
||||||
|
main
|
||||||
|
.vscode
|
||||||
|
go.sum
|
||||||
|
*.exe
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package hello
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/net/ghttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Hello World
|
||||||
|
func Handler(r *ghttp.Request) {
|
||||||
|
r.Response.Writeln("Hello World!")
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gfast/app/service/user"
|
||||||
|
"gfast/library/response"
|
||||||
|
"github.com/gogf/gf/net/ghttp"
|
||||||
|
"github.com/gogf/gf/util/gvalid"
|
||||||
|
)
|
||||||
|
|
||||||
|
//用户API管理对象
|
||||||
|
type Controller struct {}
|
||||||
|
|
||||||
|
//用户注册接口
|
||||||
|
func (c Controller) SignUp(r *ghttp.Request) {
|
||||||
|
if err:=user.SignUp(r.GetPostMapStrStr());err!=nil{
|
||||||
|
response.Json(r, 1, err.Error())
|
||||||
|
}else{
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 用户登录接口
|
||||||
|
func (c *Controller) SignIn(r *ghttp.Request) {
|
||||||
|
data := r.GetPostMapStrStr()
|
||||||
|
rules := map[string]string{
|
||||||
|
"passport": "required",
|
||||||
|
"password": "required",
|
||||||
|
}
|
||||||
|
msgs := map[string]interface{}{
|
||||||
|
"passport": "账号不能为空",
|
||||||
|
"password": "密码不能为空",
|
||||||
|
}
|
||||||
|
if e := gvalid.CheckMap(data, rules, msgs); e != nil {
|
||||||
|
response.Json(r, 1, e.String())
|
||||||
|
}
|
||||||
|
if err := user.SignIn(data["passport"], data["password"], r.Session); err != nil {
|
||||||
|
response.Json(r, 1, err.Error())
|
||||||
|
} else {
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断用户是否已经登录
|
||||||
|
func (c *Controller) IsSignedIn(r *ghttp.Request) {
|
||||||
|
if user.IsSignedIn(r.Session) {
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
} else {
|
||||||
|
response.Json(r, 1, "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户注销/退出接口
|
||||||
|
func (c *Controller) SignOut(r *ghttp.Request) {
|
||||||
|
user.SignOut(r.Session)
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测用户账号接口(唯一性校验)
|
||||||
|
func (c *Controller) CheckPassport(r *ghttp.Request) {
|
||||||
|
passport := r.GetString("passport")
|
||||||
|
if e := gvalid.Check(passport, "required", "请输入账号"); e != nil {
|
||||||
|
response.Json(r, 1, e.String())
|
||||||
|
}
|
||||||
|
if user.CheckPassport(passport) {
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
}
|
||||||
|
response.Json(r, 1, "账号已经存在")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检测用户昵称接口(唯一性校验)
|
||||||
|
func (c *Controller) CheckNickName(r *ghttp.Request) {
|
||||||
|
nickname := r.Get("nickname")
|
||||||
|
if e := gvalid.Check(nickname, "required", "请输入昵称"); e != nil {
|
||||||
|
response.Json(r, 1, e.String())
|
||||||
|
}
|
||||||
|
if user.CheckNickName(r.GetString("nickname")) {
|
||||||
|
response.Json(r, 0, "ok")
|
||||||
|
}
|
||||||
|
response.Json(r, 1, "昵称已经存在")
|
||||||
|
}
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/gogf/gf/frame/g"
|
||||||
|
"github.com/gogf/gf/net/ghttp"
|
||||||
|
"github.com/gogf/gf/os/gtime"
|
||||||
|
"github.com/gogf/gf/util/gvalid"
|
||||||
|
)
|
||||||
|
|
||||||
|
const USER_SESSION_MARK = "user_info"
|
||||||
|
|
||||||
|
var (
|
||||||
|
//表对象
|
||||||
|
table = g.DB().Table("user").Safe()
|
||||||
|
)
|
||||||
|
|
||||||
|
//用户注册
|
||||||
|
func SignUp(data g.MapStrStr)error{
|
||||||
|
//数据校验
|
||||||
|
rules:=[]string{
|
||||||
|
"passport @required|length:6,16#账号不能为空|账号长度应在:min到:max之间",
|
||||||
|
"password2@required|length:6,16#请输入确认密码|密码长度应当在:min到:max之间",
|
||||||
|
"password @required|length:6,16|same:password2#密码不能为空|密码长度应当在:min到:max之间|两次密码输入不相等",
|
||||||
|
}
|
||||||
|
if err:=gvalid.CheckMap(data,rules);err!=nil{
|
||||||
|
return errors.New(err.String())
|
||||||
|
}
|
||||||
|
if _, ok := data["nickname"]; !ok {
|
||||||
|
data["nickname"] = data["passport"]
|
||||||
|
}
|
||||||
|
// 唯一性数据检查
|
||||||
|
if !CheckPassport(data["passport"]) {
|
||||||
|
return errors.New(fmt.Sprintf("账号 %s 已经存在", data["passport"]))
|
||||||
|
}
|
||||||
|
if !CheckNickName(data["nickname"]) {
|
||||||
|
return errors.New(fmt.Sprintf("昵称 %s 已经存在", data["nickname"]))
|
||||||
|
}
|
||||||
|
// 记录账号创建/注册时间
|
||||||
|
if _, ok := data["create_time"]; !ok {
|
||||||
|
data["create_time"] = gtime.Now().String()
|
||||||
|
}
|
||||||
|
if _, err := table.Filter().Data(data).Save(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断用户是否已经登录
|
||||||
|
func IsSignedIn(session *ghttp.Session) bool {
|
||||||
|
return session.Contains(USER_SESSION_MARK)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户登录,成功返回用户信息,否则返回nil; passport应当会md5值字符串
|
||||||
|
func SignIn(passport, password string, session *ghttp.Session) error {
|
||||||
|
record, err := table.Where("passport=? and password=?", passport, password).One()
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if record == nil {
|
||||||
|
return errors.New("账号或密码错误")
|
||||||
|
}
|
||||||
|
session.Set(USER_SESSION_MARK, record)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户注销
|
||||||
|
func SignOut(session *ghttp.Session) {
|
||||||
|
session.Remove(USER_SESSION_MARK)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 检查账号是否符合规范(目前仅检查唯一性),存在返回false,否则true
|
||||||
|
func CheckPassport(passport string) bool {
|
||||||
|
if i, err := table.Where("passport", passport).Count(); err != nil && err != sql.ErrNoRows {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return i == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查昵称是否符合规范(目前仅检查唯一性),存在返回false,否则true
|
||||||
|
func CheckNickName(nickname string) bool {
|
||||||
|
if i, err := table.Where("nickname", nickname).Count(); err != nil && err != sql.ErrNoRows {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return i == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package boot
|
||||||
|
|
||||||
|
import "github.com/gogf/gf/frame/g"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
g.Server().SetPort(8200)
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
module gfast
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/casbin/casbin/v2 v2.1.2
|
||||||
|
github.com/gogf/gf v1.10.0
|
||||||
|
google.golang.org/appengine v1.6.5 // indirect
|
||||||
|
)
|
||||||
|
|
||||||
|
go 1.13
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package response
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/frame/g"
|
||||||
|
"github.com/gogf/gf/net/ghttp"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 标准返回结果数据结构封装。
|
||||||
|
// 返回固定数据结构的JSON:
|
||||||
|
// err: 错误码(0:成功, 1:失败, >1:错误码);
|
||||||
|
// msg: 请求结果信息;
|
||||||
|
// data: 请求结果,根据不同接口返回结果的数据结构不同;
|
||||||
|
func Json(r *ghttp.Request, err int, msg string, data ...interface{}) {
|
||||||
|
responseData := interface{}(nil)
|
||||||
|
if len(data) > 0 {
|
||||||
|
responseData = data[0]
|
||||||
|
}
|
||||||
|
r.Response.WriteJson(g.Map{
|
||||||
|
"err": err,
|
||||||
|
"msg": msg,
|
||||||
|
"data": responseData,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回JSON数据并退出当前HTTP执行函数。
|
||||||
|
func JsonExit(r *ghttp.Request, err int, msg string, data ...interface{}) {
|
||||||
|
Json(r, err, msg, data...)
|
||||||
|
r.Exit()
|
||||||
|
}
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/casbin/casbin/v2/model"
|
||||||
|
"github.com/casbin/casbin/v2/persist"
|
||||||
|
"github.com/gogf/gf/database/gdb"
|
||||||
|
"runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CasbinRule struct {
|
||||||
|
PType string `json:"ptype"`
|
||||||
|
V0 string `json:"v0"`
|
||||||
|
V1 string `json:"v1"`
|
||||||
|
V2 string `json:"v2"`
|
||||||
|
V3 string `json:"v3"`
|
||||||
|
V4 string `json:"v4"`
|
||||||
|
V5 string `json:"v5"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adapter represents the gdb adapter for policy storage.
|
||||||
|
type Adapter struct {
|
||||||
|
DriverName string
|
||||||
|
DataSourceName string
|
||||||
|
TableName string
|
||||||
|
Db gdb.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
// finalizer is the destructor for Adapter.
|
||||||
|
func finalizer(a *Adapter) {
|
||||||
|
// 注意不用的时候不需要使用Close方法关闭数据库连接(并且gdb也没有提供Close方法),
|
||||||
|
// 数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭
|
||||||
|
a.Db = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAdapter is the constructor for Adapter.
|
||||||
|
func NewAdapter(driverName string, dataSourceName string) (*Adapter, error) {
|
||||||
|
a := &Adapter{}
|
||||||
|
a.DriverName = driverName
|
||||||
|
a.DataSourceName = dataSourceName
|
||||||
|
a.TableName = "casbin_rule"
|
||||||
|
|
||||||
|
// Open the DB, create it if not existed.
|
||||||
|
err := a.open()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call the destructor when the object is released.
|
||||||
|
runtime.SetFinalizer(a, finalizer)
|
||||||
|
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewAdapterFromOptions is the constructor for Adapter with existed connection
|
||||||
|
func NewAdapterFromOptions(adapter *Adapter) (*Adapter, error) {
|
||||||
|
|
||||||
|
if adapter.TableName == "" {
|
||||||
|
adapter.TableName = "casbin_rule"
|
||||||
|
}
|
||||||
|
if adapter.Db == nil {
|
||||||
|
err := adapter.open()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
runtime.SetFinalizer(adapter, finalizer)
|
||||||
|
}
|
||||||
|
return adapter, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Adapter) open() error {
|
||||||
|
var err error
|
||||||
|
var db gdb.DB
|
||||||
|
|
||||||
|
gdb.SetConfig(gdb.Config{
|
||||||
|
"casbin": gdb.ConfigGroup{
|
||||||
|
gdb.ConfigNode{
|
||||||
|
Type: a.DriverName,
|
||||||
|
LinkInfo: a.DataSourceName,
|
||||||
|
Role: "master",
|
||||||
|
Weight: 100,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
db, err = gdb.New("casbin")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a.Db = db
|
||||||
|
|
||||||
|
return a.createTable()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Adapter) close() error {
|
||||||
|
// 注意不用的时候不需要使用Close方法关闭数据库连接(并且gdb也没有提供Close方法),
|
||||||
|
// 数据库引擎底层采用了链接池设计,当链接不再使用时会自动关闭
|
||||||
|
a.Db = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Adapter) createTable() error {
|
||||||
|
_, err := a.Db.Exec(fmt.Sprintf("CREATE TABLE IF NOT EXISTS %s (ptype VARCHAR(10), v0 VARCHAR(256), v1 VARCHAR(256), v2 VARCHAR(256), v3 VARCHAR(256), v4 VARCHAR(256), v5 VARCHAR(256))", a.TableName))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Adapter) dropTable() error {
|
||||||
|
_, err := a.Db.Exec(fmt.Sprintf("DROP TABLE %s", a.TableName))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadPolicyLine(line CasbinRule, model model.Model) {
|
||||||
|
lineText := line.PType
|
||||||
|
if line.V0 != "" {
|
||||||
|
lineText += ", " + line.V0
|
||||||
|
}
|
||||||
|
if line.V1 != "" {
|
||||||
|
lineText += ", " + line.V1
|
||||||
|
}
|
||||||
|
if line.V2 != "" {
|
||||||
|
lineText += ", " + line.V2
|
||||||
|
}
|
||||||
|
if line.V3 != "" {
|
||||||
|
lineText += ", " + line.V3
|
||||||
|
}
|
||||||
|
if line.V4 != "" {
|
||||||
|
lineText += ", " + line.V4
|
||||||
|
}
|
||||||
|
if line.V5 != "" {
|
||||||
|
lineText += ", " + line.V5
|
||||||
|
}
|
||||||
|
|
||||||
|
persist.LoadPolicyLine(lineText, model)
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadPolicy loads policy from database.
|
||||||
|
func (a *Adapter) LoadPolicy(model model.Model) error {
|
||||||
|
var lines []CasbinRule
|
||||||
|
|
||||||
|
if err := a.Db.Table(a.TableName).Scan(&lines); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, line := range lines {
|
||||||
|
loadPolicyLine(line, model)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func savePolicyLine(ptype string, rule []string) CasbinRule {
|
||||||
|
line := CasbinRule{}
|
||||||
|
|
||||||
|
line.PType = ptype
|
||||||
|
if len(rule) > 0 {
|
||||||
|
line.V0 = rule[0]
|
||||||
|
}
|
||||||
|
if len(rule) > 1 {
|
||||||
|
line.V1 = rule[1]
|
||||||
|
}
|
||||||
|
if len(rule) > 2 {
|
||||||
|
line.V2 = rule[2]
|
||||||
|
}
|
||||||
|
if len(rule) > 3 {
|
||||||
|
line.V3 = rule[3]
|
||||||
|
}
|
||||||
|
if len(rule) > 4 {
|
||||||
|
line.V4 = rule[4]
|
||||||
|
}
|
||||||
|
if len(rule) > 5 {
|
||||||
|
line.V5 = rule[5]
|
||||||
|
}
|
||||||
|
|
||||||
|
return line
|
||||||
|
}
|
||||||
|
|
||||||
|
// SavePolicy saves policy to database.
|
||||||
|
func (a *Adapter) SavePolicy(model model.Model) error {
|
||||||
|
err := a.dropTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = a.createTable()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for ptype, ast := range model["p"] {
|
||||||
|
for _, rule := range ast.Policy {
|
||||||
|
line := savePolicyLine(ptype, rule)
|
||||||
|
_, err := a.Db.Table(a.TableName).Data(&line).Insert()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for ptype, ast := range model["g"] {
|
||||||
|
for _, rule := range ast.Policy {
|
||||||
|
line := savePolicyLine(ptype, rule)
|
||||||
|
_, err := a.Db.Table(a.TableName).Data(&line).Insert()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddPolicy adds a policy rule to the storage.
|
||||||
|
func (a *Adapter) AddPolicy(sec string, ptype string, rule []string) error {
|
||||||
|
line := savePolicyLine(ptype, rule)
|
||||||
|
_, err := a.Db.Table(a.TableName).Data(&line).Insert()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemovePolicy removes a policy rule from the storage.
|
||||||
|
func (a *Adapter) RemovePolicy(sec string, ptype string, rule []string) error {
|
||||||
|
line := savePolicyLine(ptype, rule)
|
||||||
|
err := rawDelete(a, line)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveFilteredPolicy removes policy rules that match the filter from the storage.
|
||||||
|
func (a *Adapter) RemoveFilteredPolicy(sec string, ptype string, fieldIndex int, fieldValues ...string) error {
|
||||||
|
line := CasbinRule{}
|
||||||
|
|
||||||
|
line.PType = ptype
|
||||||
|
if fieldIndex <= 0 && 0 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V0 = fieldValues[0-fieldIndex]
|
||||||
|
}
|
||||||
|
if fieldIndex <= 1 && 1 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V1 = fieldValues[1-fieldIndex]
|
||||||
|
}
|
||||||
|
if fieldIndex <= 2 && 2 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V2 = fieldValues[2-fieldIndex]
|
||||||
|
}
|
||||||
|
if fieldIndex <= 3 && 3 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V3 = fieldValues[3-fieldIndex]
|
||||||
|
}
|
||||||
|
if fieldIndex <= 4 && 4 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V4 = fieldValues[4-fieldIndex]
|
||||||
|
}
|
||||||
|
if fieldIndex <= 5 && 5 < fieldIndex+len(fieldValues) {
|
||||||
|
line.V5 = fieldValues[5-fieldIndex]
|
||||||
|
}
|
||||||
|
err := rawDelete(a, line)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func rawDelete(a *Adapter, line CasbinRule) error {
|
||||||
|
db := a.Db.Table(a.TableName)
|
||||||
|
|
||||||
|
db.Where("ptype = ?", line.PType)
|
||||||
|
if line.V0 != "" {
|
||||||
|
db.Where("v0 = ?", line.V0)
|
||||||
|
}
|
||||||
|
if line.V1 != "" {
|
||||||
|
db.Where("v1 = ?", line.V1)
|
||||||
|
}
|
||||||
|
if line.V2 != "" {
|
||||||
|
db.Where("v2 = ?", line.V2)
|
||||||
|
}
|
||||||
|
if line.V3 != "" {
|
||||||
|
db.Where("v3 = ?", line.V3)
|
||||||
|
}
|
||||||
|
if line.V4 != "" {
|
||||||
|
db.Where("v4 = ?", line.V4)
|
||||||
|
}
|
||||||
|
if line.V5 != "" {
|
||||||
|
db.Where("v5 = ?", line.V5)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := db.Delete()
|
||||||
|
return err
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import(
|
||||||
|
_ "gfast/boot"
|
||||||
|
_ "gfast/router"
|
||||||
|
"github.com/gogf/gf/frame/g"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
g.Server().Run()
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/gogf/gf/frame/g"
|
||||||
|
"github.com/gogf/gf/net/ghttp"
|
||||||
|
"github.com/gogf/gf/os/glog"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 基本事件回调使用
|
||||||
|
p := "/:name/info/{uid}"
|
||||||
|
s := g.Server()
|
||||||
|
s.BindHookHandlerByMap(p, map[string]ghttp.HandlerFunc{
|
||||||
|
ghttp.HOOK_BEFORE_SERVE : func(r *ghttp.Request){ glog.Println(ghttp.HOOK_BEFORE_SERVE) },
|
||||||
|
ghttp.HOOK_AFTER_SERVE : func(r *ghttp.Request){ glog.Println(ghttp.HOOK_AFTER_SERVE) },
|
||||||
|
ghttp.HOOK_BEFORE_OUTPUT : func(r *ghttp.Request){ glog.Println(ghttp.HOOK_BEFORE_OUTPUT) },
|
||||||
|
ghttp.HOOK_AFTER_OUTPUT : func(r *ghttp.Request){ glog.Println(ghttp.HOOK_AFTER_OUTPUT) },
|
||||||
|
})
|
||||||
|
s.BindHandler(p, func(r *ghttp.Request) {
|
||||||
|
r.Response.Write("用户:", r.Get("name"), ", uid:", r.Get("uid"))
|
||||||
|
})
|
||||||
|
s.SetPort(8199)
|
||||||
|
s.Run()
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package router
|
||||||
|
|
||||||
|
import (
|
||||||
|
"gfast/app/api/hello"
|
||||||
|
"gfast/app/api/user"
|
||||||
|
"github.com/gogf/gf/frame/g"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 统一路由注册.
|
||||||
|
func init() {
|
||||||
|
g.Server().BindHandler("/", hello.Handler)
|
||||||
|
g.Server().BindObject("/user", new(user.Controller))
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
# Request definition
|
||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
# Policy definition
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act
|
||||||
|
|
||||||
|
# Policy effect
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
# Matchers
|
||||||
|
[matchers]
|
||||||
|
m = r.sub == p.sub && r.obj == p.obj && r.act == p.act
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
p, alice, data1, read
|
||||||
|
p, bob, data2, write
|
||||||
|
@@ -0,0 +1,14 @@
|
|||||||
|
[request_definition]
|
||||||
|
r = sub, obj, act
|
||||||
|
|
||||||
|
[policy_definition]
|
||||||
|
p = sub, obj, act
|
||||||
|
|
||||||
|
[role_definition]
|
||||||
|
g = _, _
|
||||||
|
|
||||||
|
[policy_effect]
|
||||||
|
e = some(where (p.eft == allow))
|
||||||
|
|
||||||
|
[matchers]
|
||||||
|
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
p, alice, data1, read
|
||||||
|
p, bob, data2, write
|
||||||
|
p, data2_admin, data2, read
|
||||||
|
p, data2_admin, data2, write
|
||||||
|
g, alice, data2_admin
|
||||||
|
@@ -0,0 +1,170 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gfast/library/utils"
|
||||||
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casbin/casbin/v2/util"
|
||||||
|
"github.com/gogf/gf/os/glog"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDemo(t *testing.T){
|
||||||
|
//t.Run("demo1" ,Demo1)
|
||||||
|
t.Run("Adapters_test", Adapters)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Demo1(t *testing.T){
|
||||||
|
e,err:=casbin.NewEnforcer("casbin_conf/model.conf","casbin_conf/policy.csv")
|
||||||
|
if err!=nil{
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
sub := "alice" // the user that wants to access a resource. 对象
|
||||||
|
obj := "data1" // the resource that is going to be accessed. 资源
|
||||||
|
act := "write" // the operation that the user performs on the resource. 操作
|
||||||
|
ok, err := e.Enforce(sub, obj, act)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("验证失败",err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok == true {
|
||||||
|
fmt.Println("权限通过")
|
||||||
|
} else {
|
||||||
|
fmt.Println("没有权限")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Adapters(t *testing.T) {
|
||||||
|
a := initAdapter(t, "mysql", "root:123456@tcp(127.0.0.1:3306)/test2")
|
||||||
|
testAutoSave(t, a)
|
||||||
|
testSaveLoad(t, a)
|
||||||
|
|
||||||
|
a = initAdapterFormOptions(t, &utils.Adapter{
|
||||||
|
DriverName: "mysql",
|
||||||
|
DataSourceName: "root:123456@tcp(127.0.0.1:3306)/test2",
|
||||||
|
})
|
||||||
|
testAutoSave(t, a)
|
||||||
|
testSaveLoad(t, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initAdapterFormOptions(t *testing.T, adapter *utils.Adapter) *utils.Adapter {
|
||||||
|
// Create an adapter
|
||||||
|
a, _ := utils.NewAdapterFromOptions(adapter)
|
||||||
|
// Initialize some policy in DB.
|
||||||
|
initPolicy(t, a)
|
||||||
|
// Now the DB has policy, so we can provide a normal use case.
|
||||||
|
// Note: you don't need to look at the above code
|
||||||
|
// if you already have a working DB with policy inside.
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func initPolicy(t *testing.T, a *utils.Adapter) {
|
||||||
|
// Because the DB is empty at first,
|
||||||
|
// so we need to load the policy from the file adapter (.CSV) first.
|
||||||
|
e, err := casbin.NewEnforcer("casbin_conf/rbac_model.conf", "casbin_conf/rbac_policy.csv")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a trick to save the current policy to the DB.
|
||||||
|
// We can't call e.SavePolicy() because the adapter in the enforcer is still the file adapter.
|
||||||
|
// The current policy means the policy in the Casbin enforcer (aka in memory).
|
||||||
|
err = a.SavePolicy(e.GetModel())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear the current policy.
|
||||||
|
e.ClearPolicy()
|
||||||
|
testGetPolicy(t, e, [][]string{})
|
||||||
|
|
||||||
|
// Load the policy from DB.
|
||||||
|
err = a.LoadPolicy(e.GetModel())
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGetPolicy(t *testing.T, e *casbin.Enforcer, res [][]string) {
|
||||||
|
myRes := e.GetPolicy()
|
||||||
|
glog.Info("Policy: ", myRes)
|
||||||
|
|
||||||
|
if !util.Array2DEquals(res, myRes) {
|
||||||
|
t.Error("Policy: ", myRes, ", supposed to be ", res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func initAdapter(t *testing.T, driverName string, dataSourceName string) *utils.Adapter {
|
||||||
|
// Create an adapter
|
||||||
|
a, err := utils.NewAdapter(driverName, dataSourceName)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize some policy in DB.
|
||||||
|
initPolicy(t, a)
|
||||||
|
// Now the DB has policy, so we can provide a normal use case.
|
||||||
|
// Note: you don't need to look at the above code
|
||||||
|
// if you already have a working DB with policy inside.
|
||||||
|
|
||||||
|
return a
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAutoSave(t *testing.T, a *utils.Adapter) {
|
||||||
|
|
||||||
|
// NewEnforcer() will load the policy automatically.
|
||||||
|
e, err := casbin.NewEnforcer("casbin_conf/rbac_model.conf", a)
|
||||||
|
if err!=nil{
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
// AutoSave is enabled by default.
|
||||||
|
// Now we disable it.
|
||||||
|
e.EnableAutoSave(false)
|
||||||
|
|
||||||
|
// Because AutoSave is disabled, the policy change only affects the policy in Casbin enforcer,
|
||||||
|
// it doesn't affect the policy in the storage.
|
||||||
|
e.AddPolicy("alice", "data1", "write")
|
||||||
|
// Reload the policy from the storage to see the effect.
|
||||||
|
e.LoadPolicy()
|
||||||
|
// This is still the original policy.
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}})
|
||||||
|
|
||||||
|
// Now we enable the AutoSave.
|
||||||
|
e.EnableAutoSave(true)
|
||||||
|
|
||||||
|
// Because AutoSave is enabled, the policy change not only affects the policy in Casbin enforcer,
|
||||||
|
// but also affects the policy in the storage.
|
||||||
|
e.AddPolicy("alice", "data1", "write")
|
||||||
|
// Reload the policy from the storage to see the effect.
|
||||||
|
e.LoadPolicy()
|
||||||
|
// The policy has a new rule: {"alice", "data1", "write"}.
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}, {"alice", "data1", "write"}})
|
||||||
|
|
||||||
|
// Remove the added rule.
|
||||||
|
e.RemovePolicy("alice", "data1", "write")
|
||||||
|
e.LoadPolicy()
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}})
|
||||||
|
|
||||||
|
// Remove "data2_admin" related policy rules via a filter.
|
||||||
|
// Two rules: {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"} are deleted.
|
||||||
|
e.RemoveFilteredPolicy(0, "data2_admin")
|
||||||
|
e.LoadPolicy()
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testSaveLoad(t *testing.T, a *utils.Adapter) {
|
||||||
|
// Initialize some policy in DB.
|
||||||
|
initPolicy(t, a)
|
||||||
|
// Note: you don't need to look at the above code
|
||||||
|
// if you already have a working DB with policy inside.
|
||||||
|
|
||||||
|
// Now the DB has policy, so we can provide a normal use case.
|
||||||
|
// Create an adapter and an enforcer.
|
||||||
|
// NewEnforcer() will load the policy automatically.
|
||||||
|
|
||||||
|
e, _ := casbin.NewEnforcer("casbin_conf/rbac_model.conf", a)
|
||||||
|
testGetPolicy(t, e, [][]string{{"alice", "data1", "read"}, {"bob", "data2", "write"}, {"data2_admin", "data2", "read"}, {"data2_admin", "data2", "write"}})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user