parent
114a7c3dab
commit
103d765735
|
@ -0,0 +1,3 @@
|
||||||
|
tmp
|
||||||
|
logs
|
||||||
|
public/static/dist
|
|
@ -1,4 +1,4 @@
|
||||||
name: build
|
name: build and push binary to release
|
||||||
|
|
||||||
on:
|
on:
|
||||||
release:
|
release:
|
||||||
|
@ -16,6 +16,8 @@ jobs:
|
||||||
goos: windows
|
goos: windows
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
- run: |
|
||||||
|
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
|
||||||
- uses: wangyoucao577/go-release-action@v1
|
- uses: wangyoucao577/go-release-action@v1
|
||||||
with:
|
with:
|
||||||
github_token: ${{ secrets.GITHUB_TOKEN }} # 一个默认的变量,用来实现往 Release 中添加文件
|
github_token: ${{ secrets.GITHUB_TOKEN }} # 一个默认的变量,用来实现往 Release 中添加文件
|
||||||
|
@ -23,4 +25,4 @@ jobs:
|
||||||
goarch: ${{ matrix.goarch }}
|
goarch: ${{ matrix.goarch }}
|
||||||
goversion: 1.18 # 可以指定编译使用的 Golang 版本
|
goversion: 1.18 # 可以指定编译使用的 Golang 版本
|
||||||
binary_name: "go-ldap-admin" # 可以指定二进制文件的名称
|
binary_name: "go-ldap-admin" # 可以指定二进制文件的名称
|
||||||
extra_files: LICENSE config.yml go-ldap-admin-priv.pem go-ldap-admin-pub.pem rbac_model.conf README.md # 需要包含的额外文件
|
extra_files: LICENSE config.yml README.md # 需要包含的额外文件
|
|
@ -11,16 +11,20 @@ jobs:
|
||||||
with:
|
with:
|
||||||
go-version: 1.18
|
go-version: 1.18
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
- run: |
|
||||||
|
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v3
|
||||||
with:
|
with:
|
||||||
version: v1.47.3
|
version: v1.57.2
|
||||||
args: --timeout=5m --skip-files="public/client/feishu/feishu.go"
|
args: --timeout=5m --skip-files="public/client/feishu/feishu.go"
|
||||||
build:
|
build:
|
||||||
name: go-build
|
name: go-build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
|
- run: |
|
||||||
|
release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v3
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
|
@ -24,3 +24,4 @@ go-ldap-admin.db
|
||||||
# vendor/
|
# vendor/
|
||||||
tmp
|
tmp
|
||||||
docs/docker-compose/data
|
docs/docker-compose/data
|
||||||
|
dist
|
40
Dockerfile
40
Dockerfile
|
@ -1,39 +1,29 @@
|
||||||
FROM golang:1.18.10-alpine3.16 AS builder
|
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/golang:1.18.10-alpine3.17 AS builder
|
||||||
|
|
||||||
# ENV GOPROXY https://goproxy.io
|
|
||||||
|
|
||||||
RUN mkdir /app && apk add --no-cache --virtual .build-deps \
|
|
||||||
ca-certificates \
|
|
||||||
gcc \
|
|
||||||
g++
|
|
||||||
|
|
||||||
ADD . /app/
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN sed -i "s/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g" /etc/apk/repositories \
|
||||||
|
&& apk upgrade && apk add --no-cache --virtual .build-deps \
|
||||||
|
ca-certificates gcc g++ curl
|
||||||
|
|
||||||
|
ADD . .
|
||||||
|
|
||||||
|
RUN release_url=$(curl -s https://api.github.com/repos/eryajf/go-ldap-admin-ui/releases/latest | grep "browser_download_url" | grep -v 'dist.zip.md5' | cut -d '"' -f 4); wget $release_url && unzip dist.zip && rm dist.zip && mv dist public/static
|
||||||
|
|
||||||
RUN sed -i 's@localhost:389@openldap:389@g' /app/config.yml \
|
RUN sed -i 's@localhost:389@openldap:389@g' /app/config.yml \
|
||||||
&& sed -i 's@host: localhost@host: mysql@g' /app/config.yml && go build -o go-ldap-admin .
|
&& sed -i 's@host: localhost@host: mysql@g' /app/config.yml && go build -o go-ldap-admin .
|
||||||
|
|
||||||
### build final image
|
### build final image
|
||||||
FROM alpine:3.16
|
FROM registry.cn-hangzhou.aliyuncs.com/ali_eryajf/alpine:3.19
|
||||||
|
|
||||||
# we set the timezone `Asia/Shanghai` by default, you can be modified
|
LABEL maintainer eryajf@163.com
|
||||||
# by `docker build --build-arg="TZ=Other_Timezone ..."`
|
|
||||||
ARG TZ="Asia/Shanghai"
|
|
||||||
|
|
||||||
ENV TZ ${TZ}
|
|
||||||
|
|
||||||
RUN mkdir /app
|
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=builder /app/ .
|
COPY --from=builder /app/wait .
|
||||||
|
COPY --from=builder /app/LICENSE .
|
||||||
|
COPY --from=builder /app/config.yml .
|
||||||
RUN apk upgrade \
|
COPY --from=builder /app/go-ldap-admin .
|
||||||
&& apk add bash tzdata sqlite vim \
|
|
||||||
&& ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime \
|
|
||||||
&& echo ${TZ} > /etc/timezone
|
|
||||||
|
|
||||||
RUN chmod +x wait go-ldap-admin
|
RUN chmod +x wait go-ldap-admin
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,6 @@ system:
|
||||||
port: 8888
|
port: 8888
|
||||||
# 是否初始化数据(没有初始数据时使用, 已发布正式版改为false)
|
# 是否初始化数据(没有初始数据时使用, 已发布正式版改为false)
|
||||||
init-data: true
|
init-data: true
|
||||||
# rsa公钥文件路径(config.yml相对路径, 也可以填绝对路径)
|
|
||||||
rsa-public-key: go-ldap-admin-pub.pem
|
|
||||||
# rsa私钥文件路径(config.yml相对路径, 也可以填绝对路径)
|
|
||||||
rsa-private-key: go-ldap-admin-priv.pem
|
|
||||||
|
|
||||||
logs:
|
logs:
|
||||||
# 日志等级(-1:Debug, 0:Info, 1:Warn, 2:Error, 3:DPanic, 4:Panic, 5:Fatal, -1<=level<=5, 参照zap.level源码)
|
# 日志等级(-1:Debug, 0:Info, 1:Warn, 2:Error, 3:DPanic, 4:Panic, 5:Fatal, -1<=level<=5, 参照zap.level源码)
|
||||||
|
@ -55,11 +51,6 @@ mysql:
|
||||||
# 字符集(utf8mb4_general_ci速度比utf8mb4_unicode_ci快些)
|
# 字符集(utf8mb4_general_ci速度比utf8mb4_unicode_ci快些)
|
||||||
collation: utf8mb4_general_ci
|
collation: utf8mb4_general_ci
|
||||||
|
|
||||||
# casbin配置
|
|
||||||
casbin:
|
|
||||||
# 模型配置文件, config.yml相对路径
|
|
||||||
model-path: 'rbac_model.conf'
|
|
||||||
|
|
||||||
# jwt配置
|
# jwt配置
|
||||||
jwt:
|
jwt:
|
||||||
# jwt标识
|
# jwt标识
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -15,12 +16,18 @@ import (
|
||||||
// 全局配置变量
|
// 全局配置变量
|
||||||
var Conf = new(config)
|
var Conf = new(config)
|
||||||
|
|
||||||
|
//go:embed go-ldap-admin-priv.pem
|
||||||
|
var priv []byte
|
||||||
|
|
||||||
|
//go:embed go-ldap-admin-pub.pem
|
||||||
|
var pub []byte
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
System *SystemConfig `mapstructure:"system" json:"system"`
|
System *SystemConfig `mapstructure:"system" json:"system"`
|
||||||
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
|
Logs *LogsConfig `mapstructure:"logs" json:"logs"`
|
||||||
Database *Database `mapstructure:"database" json:"database"`
|
Database *Database `mapstructure:"database" json:"database"`
|
||||||
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
|
Mysql *MysqlConfig `mapstructure:"mysql" json:"mysql"`
|
||||||
Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
|
// Casbin *CasbinConfig `mapstructure:"casbin" json:"casbin"`
|
||||||
Jwt *JwtConfig `mapstructure:"jwt" json:"jwt"`
|
Jwt *JwtConfig `mapstructure:"jwt" json:"jwt"`
|
||||||
RateLimit *RateLimitConfig `mapstructure:"rate-limit" json:"rateLimit"`
|
RateLimit *RateLimitConfig `mapstructure:"rate-limit" json:"rateLimit"`
|
||||||
Ldap *LdapConfig `mapstructure:"ldap" json:"ldap"`
|
Ldap *LdapConfig `mapstructure:"ldap" json:"ldap"`
|
||||||
|
@ -50,8 +57,8 @@ func InitConfig() {
|
||||||
panic(fmt.Errorf("初始化配置文件失败:%s", err))
|
panic(fmt.Errorf("初始化配置文件失败:%s", err))
|
||||||
}
|
}
|
||||||
// 读取rsa key
|
// 读取rsa key
|
||||||
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
|
Conf.System.RSAPublicBytes = pub
|
||||||
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)
|
Conf.System.RSAPrivateBytes = priv
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -62,36 +69,16 @@ func InitConfig() {
|
||||||
panic(fmt.Errorf("初始化配置文件失败:%s", err))
|
panic(fmt.Errorf("初始化配置文件失败:%s", err))
|
||||||
}
|
}
|
||||||
// 读取rsa key
|
// 读取rsa key
|
||||||
Conf.System.RSAPublicBytes = RSAReadKeyFromFile(Conf.System.RSAPublicKey)
|
Conf.System.RSAPublicBytes = pub
|
||||||
Conf.System.RSAPrivateBytes = RSAReadKeyFromFile(Conf.System.RSAPrivateKey)
|
Conf.System.RSAPrivateBytes = priv
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 从文件中读取RSA key
|
|
||||||
func RSAReadKeyFromFile(filename string) []byte {
|
|
||||||
f, err := os.Open(filename)
|
|
||||||
var b []byte
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
defer f.Close()
|
|
||||||
fileInfo, _ := f.Stat()
|
|
||||||
b = make([]byte, fileInfo.Size())
|
|
||||||
_, err = f.Read(b)
|
|
||||||
if err != nil {
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
return b
|
|
||||||
}
|
|
||||||
|
|
||||||
type SystemConfig struct {
|
type SystemConfig struct {
|
||||||
Mode string `mapstructure:"mode" json:"mode"`
|
Mode string `mapstructure:"mode" json:"mode"`
|
||||||
UrlPathPrefix string `mapstructure:"url-path-prefix" json:"urlPathPrefix"`
|
UrlPathPrefix string `mapstructure:"url-path-prefix" json:"urlPathPrefix"`
|
||||||
Port int `mapstructure:"port" json:"port"`
|
Port int `mapstructure:"port" json:"port"`
|
||||||
InitData bool `mapstructure:"init-data" json:"initData"`
|
InitData bool `mapstructure:"init-data" json:"initData"`
|
||||||
RSAPublicKey string `mapstructure:"rsa-public-key" json:"rsaPublicKey"`
|
|
||||||
RSAPrivateKey string `mapstructure:"rsa-private-key" json:"rsaPrivateKey"`
|
|
||||||
RSAPublicBytes []byte `mapstructure:"-" json:"-"`
|
RSAPublicBytes []byte `mapstructure:"-" json:"-"`
|
||||||
RSAPrivateBytes []byte `mapstructure:"-" json:"-"`
|
RSAPrivateBytes []byte `mapstructure:"-" json:"-"`
|
||||||
}
|
}
|
||||||
|
@ -123,9 +110,9 @@ type MysqlConfig struct {
|
||||||
Collation string `mapstructure:"collation" json:"collation"`
|
Collation string `mapstructure:"collation" json:"collation"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CasbinConfig struct {
|
// type CasbinConfig struct {
|
||||||
ModelPath string `mapstructure:"model-path" json:"modelPath"`
|
// ModelPath string `mapstructure:"model-path" json:"modelPath"`
|
||||||
}
|
// }
|
||||||
|
|
||||||
type JwtConfig struct {
|
type JwtConfig struct {
|
||||||
Realm string `mapstructure:"realm" json:"realm"`
|
Realm string `mapstructure:"realm" json:"realm"`
|
||||||
|
|
|
@ -72,7 +72,6 @@ services:
|
||||||
hostname: go-ldap-admin-server
|
hostname: go-ldap-admin-server
|
||||||
restart: always
|
restart: always
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
|
||||||
WAIT_HOSTS: mysql:3306, openldap:389
|
WAIT_HOSTS: mysql:3306, openldap:389
|
||||||
ports:
|
ports:
|
||||||
- 8888:8888
|
- 8888:8888
|
||||||
|
@ -86,19 +85,3 @@ services:
|
||||||
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
|
- openldap:go-ldap-admin-openldap # ldap容器的 service_name:container_name
|
||||||
networks:
|
networks:
|
||||||
- go-ldap-admin
|
- go-ldap-admin
|
||||||
|
|
||||||
go-ldap-admin-ui:
|
|
||||||
image: registry.cn-hangzhou.aliyuncs.com/ali_eryajf/go-ldap-admin-ui
|
|
||||||
container_name: go-ldap-admin-ui
|
|
||||||
hostname: go-ldap-admin-ui
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
ports:
|
|
||||||
- 8090:80
|
|
||||||
depends_on:
|
|
||||||
- go-ldap-admin-server
|
|
||||||
links:
|
|
||||||
- go-ldap-admin-server:go-ldap-admin-server
|
|
||||||
networks:
|
|
||||||
- go-ldap-admin
|
|
2
main.go
2
main.go
|
@ -68,7 +68,7 @@ func main() {
|
||||||
// 启动定时任务
|
// 启动定时任务
|
||||||
logic.InitCron()
|
logic.InitCron()
|
||||||
|
|
||||||
common.Log.Info(fmt.Sprintf("Server is running at %s:%d/%s", host, port, config.Conf.System.UrlPathPrefix))
|
common.Log.Info(fmt.Sprintf("Server is running at http://%s:%d", host, port))
|
||||||
|
|
||||||
// Wait for interrupt signal to gracefully shutdown the server with
|
// Wait for interrupt signal to gracefully shutdown the server with
|
||||||
// a timeout of 5 seconds.
|
// a timeout of 5 seconds.
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
const INDEX = "index.html"
|
||||||
|
|
||||||
|
type ServeFileSystem interface {
|
||||||
|
http.FileSystem
|
||||||
|
Exists(prefix string, path string) bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type localFileSystem struct {
|
||||||
|
http.FileSystem
|
||||||
|
root string
|
||||||
|
indexes bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func LocalFile(root string, indexes bool) *localFileSystem {
|
||||||
|
return &localFileSystem{
|
||||||
|
FileSystem: gin.Dir(root, indexes),
|
||||||
|
root: root,
|
||||||
|
indexes: indexes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *localFileSystem) Exists(prefix string, filepath string) bool {
|
||||||
|
if p := strings.TrimPrefix(filepath, prefix); len(p) < len(filepath) {
|
||||||
|
name := path.Join(l.root, p)
|
||||||
|
stats, err := os.Stat(name)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if stats.IsDir() {
|
||||||
|
if !l.indexes {
|
||||||
|
index := path.Join(name, INDEX)
|
||||||
|
_, err := os.Stat(index)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ServeRoot(urlPrefix, root string) gin.HandlerFunc {
|
||||||
|
return Serve(urlPrefix, LocalFile(root, false))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static returns a middleware handler that serves static files in the given directory.
|
||||||
|
func Serve(urlPrefix string, fs ServeFileSystem) gin.HandlerFunc {
|
||||||
|
fileserver := http.FileServer(fs)
|
||||||
|
if urlPrefix != "" {
|
||||||
|
fileserver = http.StripPrefix(urlPrefix, fileserver)
|
||||||
|
}
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
if fs.Exists(urlPrefix, c.Request.URL.Path) {
|
||||||
|
fileserver.ServeHTTP(c.Writer, c.Request)
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type embedFileSystem struct {
|
||||||
|
http.FileSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e embedFileSystem) Exists(prefix string, path string) bool {
|
||||||
|
_, err := e.Open(path)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func EmbedFolder(fsEmbed embed.FS, targetPath string) ServeFileSystem {
|
||||||
|
fsys, err := fs.Sub(fsEmbed, targetPath)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return embedFileSystem{
|
||||||
|
FileSystem: http.FS(fsys),
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,9 +3,8 @@ package common
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/eryajf/go-ldap-admin/config"
|
|
||||||
|
|
||||||
"github.com/casbin/casbin/v2"
|
"github.com/casbin/casbin/v2"
|
||||||
|
"github.com/casbin/casbin/v2/model"
|
||||||
gormadapter "github.com/casbin/gorm-adapter/v3"
|
gormadapter "github.com/casbin/gorm-adapter/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,12 +23,33 @@ func InitCasbinEnforcer() {
|
||||||
Log.Info("初始化Casbin完成!")
|
Log.Info("初始化Casbin完成!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var casbinModel = `
|
||||||
|
[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 = r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && (r.act == p.act || p.act == "*")
|
||||||
|
`
|
||||||
|
|
||||||
func mysqlCasbin() (*casbin.Enforcer, error) {
|
func mysqlCasbin() (*casbin.Enforcer, error) {
|
||||||
a, err := gormadapter.NewAdapterByDB(DB)
|
a, err := gormadapter.NewAdapterByDB(DB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
e, err := casbin.NewEnforcer(config.Conf.Casbin.ModelPath, a)
|
m, err := model.NewModelFromString(casbinModel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
e, err := casbin.NewEnforcer(m, a)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package static
|
||||||
|
|
||||||
|
import "embed"
|
||||||
|
|
||||||
|
//go:embed all:dist
|
||||||
|
var Static embed.FS
|
|
@ -1,14 +0,0 @@
|
||||||
[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 = r.sub == p.sub && (keyMatch2(r.obj, p.obj) || keyMatch(r.obj, p.obj)) && (r.act == p.act || p.act == "*")
|
|
|
@ -2,11 +2,13 @@ package routes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/eryajf/go-ldap-admin/config"
|
"github.com/eryajf/go-ldap-admin/config"
|
||||||
"github.com/eryajf/go-ldap-admin/middleware"
|
"github.com/eryajf/go-ldap-admin/middleware"
|
||||||
"github.com/eryajf/go-ldap-admin/public/common"
|
"github.com/eryajf/go-ldap-admin/public/common"
|
||||||
|
"github.com/eryajf/go-ldap-admin/public/static"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
@ -23,6 +25,16 @@ func InitRoutes() *gin.Engine {
|
||||||
// r := gin.New()
|
// r := gin.New()
|
||||||
// r.Use(gin.Recovery())
|
// r.Use(gin.Recovery())
|
||||||
|
|
||||||
|
r.Use(middleware.Serve("/", middleware.EmbedFolder(static.Static, "dist")))
|
||||||
|
r.NoRoute(func(c *gin.Context) {
|
||||||
|
data, err := static.Static.ReadFile("dist/index.html")
|
||||||
|
if err != nil {
|
||||||
|
_ = c.AbortWithError(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Data(http.StatusOK, "text/html; charset=utf-8", data)
|
||||||
|
})
|
||||||
|
|
||||||
// 启用限流中间件
|
// 启用限流中间件
|
||||||
// 默认每50毫秒填充一个令牌,最多填充200个
|
// 默认每50毫秒填充一个令牌,最多填充200个
|
||||||
fillInterval := time.Duration(config.Conf.RateLimit.FillInterval)
|
fillInterval := time.Duration(config.Conf.RateLimit.FillInterval)
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
|
|
||||||
> 因为一些测试场景需要依赖配置的初始化,因此这里单独一个目录放类似的测试
|
|
|
@ -1 +0,0 @@
|
||||||
../config.yml
|
|
|
@ -1 +0,0 @@
|
||||||
../go-ldap-admin-priv.pem
|
|
|
@ -1 +0,0 @@
|
||||||
../go-ldap-admin-pub.pem
|
|
|
@ -1,46 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/eryajf/go-ldap-admin/config"
|
|
||||||
"github.com/eryajf/go-ldap-admin/public/common"
|
|
||||||
"github.com/eryajf/go-ldap-admin/public/tools"
|
|
||||||
"github.com/eryajf/go-ldap-admin/service/isql"
|
|
||||||
)
|
|
||||||
|
|
||||||
func InitConfig() {
|
|
||||||
// 加载配置文件到全局配置结构体
|
|
||||||
config.InitConfig()
|
|
||||||
|
|
||||||
// 初始化日志
|
|
||||||
common.InitLogger()
|
|
||||||
|
|
||||||
// 初始化数据库(mysql)
|
|
||||||
common.InitDB()
|
|
||||||
|
|
||||||
// 初始化ldap连接
|
|
||||||
common.InitLDAP()
|
|
||||||
|
|
||||||
// 初始化casbin策略管理器
|
|
||||||
common.InitCasbinEnforcer()
|
|
||||||
|
|
||||||
// 初始化Validator数据校验
|
|
||||||
common.InitValidate()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUserExist(t *testing.T) {
|
|
||||||
InitConfig()
|
|
||||||
|
|
||||||
var u isql.UserService
|
|
||||||
filter := tools.H{
|
|
||||||
"id": "111",
|
|
||||||
}
|
|
||||||
|
|
||||||
if u.Exist(filter) {
|
|
||||||
fmt.Println("用户名已存在")
|
|
||||||
} else {
|
|
||||||
fmt.Println("用户名不存在")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../rbac_model.conf
|
|
|
@ -1,21 +0,0 @@
|
||||||
package test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/eryajf/go-ldap-admin/config"
|
|
||||||
"github.com/eryajf/go-ldap-admin/public/tools"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestUnGenPassword(t *testing.T) {
|
|
||||||
InitConfig()
|
|
||||||
pass := "$2a$10$FlzrnJeE3Ad8uokvSAl/gunkRZsdREwlFZZqPcwfkekXOc9oAa9KS"
|
|
||||||
fmt.Printf("秘钥为:%s\n", config.Conf.System.RSAPrivateBytes)
|
|
||||||
// 密码通过RSA解密
|
|
||||||
decodeData, err := tools.RSADecrypt([]byte(pass), config.Conf.System.RSAPrivateBytes)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Printf("密码解密失败:%s\n", err)
|
|
||||||
}
|
|
||||||
fmt.Printf("密码解密后为:%s\n", string(decodeData))
|
|
||||||
}
|
|
Loading…
Reference in New Issue