From 0e1604300e7679d15da3fe37ee37ed14b22b4e96 Mon Sep 17 00:00:00 2001 From: gunzhibin <1804979851@qq.com> Date: Fri, 23 May 2025 16:22:49 +0800 Subject: [PATCH] feat commit some permission code --- cmd/root.go | 2 +- go.mod | 11 ++- go.sum | 32 +++++-- internal/bootstrap/data/data.go | 2 + internal/bootstrap/data/dev.go | 9 +- internal/bootstrap/data/permission.go | 50 ++++++++++ internal/bootstrap/data/role.go | 47 ++++++++++ internal/bootstrap/data/user.go | 12 ++- internal/db/db.go | 3 +- internal/db/permission.go | 53 +++++++++++ internal/db/role.go | 53 +++++++++++ internal/db/user.go | 11 ++- internal/model/permission.go | 128 ++++++++++++++++++++++++++ internal/model/role.go | 49 ++++++++++ internal/model/user.go | 73 ++++++++++++--- internal/op/permission.go | 30 ++++++ internal/op/role.go | 50 ++++++++++ internal/op/user.go | 6 +- server/handles/auth.go | 37 +++++++- server/handles/ldap_login.go | 5 +- server/handles/permission.go | 69 ++++++++++++++ server/handles/role.go | 87 +++++++++++++++++ server/handles/ssologin.go | 7 +- server/handles/task.go | 2 +- server/handles/user.go | 4 +- server/router.go | 14 +++ 26 files changed, 799 insertions(+), 47 deletions(-) create mode 100644 internal/bootstrap/data/permission.go create mode 100644 internal/bootstrap/data/role.go create mode 100644 internal/db/permission.go create mode 100644 internal/db/role.go create mode 100644 internal/model/permission.go create mode 100644 internal/model/role.go create mode 100644 internal/op/permission.go create mode 100644 internal/op/role.go create mode 100644 server/handles/permission.go create mode 100644 server/handles/role.go diff --git a/cmd/root.go b/cmd/root.go index 59eb989c..35f773be 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -27,7 +27,7 @@ func Execute() { } func init() { - RootCmd.PersistentFlags().StringVar(&flags.DataDir, "data", "data", "data folder") + RootCmd.PersistentFlags().StringVar(&flags.DataDir, "data", "/data", "data folder") RootCmd.PersistentFlags().BoolVar(&flags.Debug, "debug", false, "start with debug mode") RootCmd.PersistentFlags().BoolVar(&flags.NoPrefix, "no-prefix", false, "disable env prefix") RootCmd.PersistentFlags().BoolVar(&flags.Dev, "dev", false, "start with dev mode") diff --git a/go.mod b/go.mod index e8afe0e7..4ecbbcf4 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/alist-org/alist/v3 go 1.23.4 require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 + github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 github.com/KirCute/ftpserverlib-pasvportmap v1.25.0 github.com/KirCute/sftpd-alist v0.0.12 github.com/ProtonMail/go-crypto v1.0.0 @@ -73,6 +75,7 @@ require ( golang.org/x/time v0.8.0 google.golang.org/appengine v1.6.8 gopkg.in/ldap.v3 v3.1.0 + gorm.io/datatypes v1.2.5 gorm.io/driver/mysql v1.5.7 gorm.io/driver/postgres v1.5.9 gorm.io/driver/sqlite v1.5.6 @@ -80,9 +83,8 @@ require ( ) require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect + filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 // indirect ) require ( @@ -109,7 +111,6 @@ require ( github.com/ipfs/boxo v0.12.0 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect github.com/klauspost/pgzip v1.2.6 // indirect - github.com/kr/text v0.2.0 // indirect github.com/matoous/go-nanoid/v2 v2.1.0 // indirect github.com/microcosm-cc/bluemonday v1.0.27 github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78 @@ -167,7 +168,7 @@ require ( github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect - github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/go-webauthn/x v0.1.12 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect @@ -181,7 +182,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/go-cid v0.4.1 github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect github.com/jackc/pgx/v5 v5.5.5 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect diff --git a/go.sum b/go.sum index 6fbaeb2b..bdc1a143 100644 --- a/go.sum +++ b/go.sum @@ -19,12 +19,20 @@ cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0/go.mod h1:oDrbWx4ewMylP7xHivfgixbfGBT6APAwsSoHRKotnIc= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 h1:UXT0o77lXQrikd1kgwIPQOUect7EoR/+sbP4wQKdzxM= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0/go.mod h1:cTvi54pg19DoT07ekoeMgE/taAwNtCShVeZqA+Iv2xI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= @@ -172,7 +180,6 @@ github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03V github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -245,8 +252,9 @@ github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBEx github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= github.com/go-resty/resty/v2 v2.14.0 h1:/rhkzsAqGQkozwfKS5aFAbb6TyKd3zyFRWcdRXLPCAU= github.com/go-resty/resty/v2 v2.14.0/go.mod h1:IW6mekUOsElt9C7oWr0XRt9BNSD6D5rr9mhk6NjmNHg= -github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-webauthn/webauthn v0.11.1 h1:5G/+dg91/VcaJHTtJUfwIlNJkLwbJCcnUc4W8VtkpzA= github.com/go-webauthn/webauthn v0.11.1/go.mod h1:YXRm1WG0OtUyDFaVAgB5KG7kVqW+6dYCJ7FTQH4SxEE= github.com/go-webauthn/x v0.1.12 h1:RjQ5cvApzyU/xLCiP+rub0PE4HBZsLggbxGR5ZpUf/A= @@ -259,6 +267,10 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo= github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -347,8 +359,8 @@ github.com/ipfs/go-ipfs-api v0.7.0 h1:CMBNCUl0b45coC+lQCXEVpMhwoqjiaCwUIrM+coYW2 github.com/ipfs/go-ipfs-api v0.7.0/go.mod h1:AIxsTNB0+ZhkqIfTZpdZ0VR/cpX5zrXjATa3prSay3g= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= -github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA= +github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= @@ -398,6 +410,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/larksuite/oapi-sdk-go/v3 v3.3.1 h1:DLQQEgHUAGZB6RVlceB1f6A94O206exxW2RIMH+gMUc= github.com/larksuite/oapi-sdk-go/v3 v3.3.1/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= @@ -436,6 +450,8 @@ github.com/mholt/archives v0.1.0 h1:FacgJyrjiuyomTuNA92X5GyRBRZjE43Y/lrzKIlF35Q= github.com/mholt/archives v0.1.0/go.mod h1:j/Ire/jm42GN7h90F5kzj6hf6ZFzEH66de+hmjEKu+I= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA= +github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA= +github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/minio/sio v0.4.0 h1:u4SWVEm5lXSqU42ZWawV0D9I5AZ5YMmo2RXpEQ/kRhc= @@ -492,6 +508,8 @@ github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6 github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -739,8 +757,6 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -946,12 +962,16 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/datatypes v1.2.5 h1:9UogU3jkydFVW1bIVVeoYsTpLRgwDVW3rHfJG6/Ek9I= +gorm.io/datatypes v1.2.5/go.mod h1:I5FUdlKpLb5PMqeMQhm30CQ6jXP8Rj89xkTeCSAaAD4= gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8= gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= gorm.io/driver/sqlite v1.5.6 h1:fO/X46qn5NUEEOZtnjJRWRzZMe8nqJiQ9E+0hi+hKQE= gorm.io/driver/sqlite v1.5.6/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= +gorm.io/driver/sqlserver v1.5.4 h1:xA+Y1KDNspv79q43bPyjDMUgHoYHLhXYmdFcYPobg8g= +gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g= gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= diff --git a/internal/bootstrap/data/data.go b/internal/bootstrap/data/data.go index c2170d2f..16ed8b6c 100644 --- a/internal/bootstrap/data/data.go +++ b/internal/bootstrap/data/data.go @@ -6,6 +6,8 @@ func InitData() { initUser() initSettings() initTasks() + initPermissions() + initRoles() if flags.Dev { initDevData() initDevDo() diff --git a/internal/bootstrap/data/dev.go b/internal/bootstrap/data/dev.go index f6296c9e..5342651e 100644 --- a/internal/bootstrap/data/dev.go +++ b/internal/bootstrap/data/dev.go @@ -23,10 +23,11 @@ func initDevData() { log.Fatalf("failed to create storage: %+v", err) } err = db.CreateUser(&model.User{ - Username: "Noah", - Password: "hsu", - BasePath: "/data", - Role: 0, + Username: "Noah", + Password: "hsu", + BasePath: "/data", + //Role: []int{0}, + RoleInfo: []uint{0}, Permission: 512, }) if err != nil { diff --git a/internal/bootstrap/data/permission.go b/internal/bootstrap/data/permission.go new file mode 100644 index 00000000..79ac5062 --- /dev/null +++ b/internal/bootstrap/data/permission.go @@ -0,0 +1,50 @@ +package data + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/pkg/utils" + "github.com/pkg/errors" + "gorm.io/gorm" + "time" +) + +func initPermissions() { + _, err := op.GetPermissionByName("guest") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + pg := &model.Permission{ + Name: "guest", + Permission: 0x4000, // 14 bit(can access dir) + PathPattern: "*", + AllowOpInfo: []string{"upload", "download", "delete"}, + CreateTime: time.Now(), + UpdateTime: time.Now(), + } + if err := op.CreatePermission(pg); err != nil { + panic(err) + } else { + utils.Log.Infof("Successfully created the guest permission ") + } + } + } + + _, err = op.GetPermissionByName("admin") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + pa := &model.Permission{ + Name: "admin", + Permission: 0x70FF, // 0、1、2、3、4、5、6、7、12、13、14 bit + PathPattern: "", + AllowOpInfo: []string{"upload", "download", "delete"}, + CreateTime: time.Now(), + UpdateTime: time.Now(), + } + if err := op.CreatePermission(pa); err != nil { + panic(err) + } else { + utils.Log.Infof("Successfully created the admin permission ") + } + } + } +} diff --git a/internal/bootstrap/data/role.go b/internal/bootstrap/data/role.go new file mode 100644 index 00000000..032eebb2 --- /dev/null +++ b/internal/bootstrap/data/role.go @@ -0,0 +1,47 @@ +package data + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/pkg/utils" + "github.com/pkg/errors" + "gorm.io/gorm" + "time" +) + +func initRoles() { + _, err := op.GetRoleByName("guest") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + roleGuest := &model.Role{ + Name: "guest", + PermissionInfo: []uint{1}, + CreateTime: time.Time{}, + UpdateTime: time.Time{}, + } + if err := op.CreateRole(roleGuest); err != nil { + panic(err) + } else { + utils.Log.Infof("Successfully created the guest role ") + } + } + } + + _, err = op.GetRoleByName("admin") + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + roleAdmin := &model.Role{ + Name: "admin", + PermissionInfo: []uint{2}, + CreateTime: time.Time{}, + UpdateTime: time.Time{}, + } + if err := op.CreateRole(roleAdmin); err != nil { + panic(err) + } else { + utils.Log.Infof("Successfully created the admin role ") + } + } + } + +} diff --git a/internal/bootstrap/data/user.go b/internal/bootstrap/data/user.go index 9c3f8962..e7ceaf70 100644 --- a/internal/bootstrap/data/user.go +++ b/internal/bootstrap/data/user.go @@ -29,7 +29,8 @@ func initUser() { Username: "admin", Salt: salt, PwdHash: model.TwoHashPwd(adminPassword, salt), - Role: model.ADMIN, + //Role: []int{model.ADMIN}, + RoleInfo: []uint{model.ADMIN}, BasePath: "/", Authn: "[]", // 0(can see hidden) - 7(can remove) & 12(can read archives) - 13(can decompress archives) @@ -49,10 +50,11 @@ func initUser() { if errors.Is(err, gorm.ErrRecordNotFound) { salt := random.String(16) guest = &model.User{ - Username: "guest", - PwdHash: model.TwoHashPwd("guest", salt), - Salt: salt, - Role: model.GUEST, + Username: "guest", + PwdHash: model.TwoHashPwd("guest", salt), + Salt: salt, + //Role: []int{model.GUEST}, + RoleInfo: []uint{model.GUEST}, BasePath: "/", Permission: 0, Disabled: true, diff --git a/internal/db/db.go b/internal/db/db.go index 2cd18050..a9d6629f 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -12,7 +12,8 @@ var db *gorm.DB func Init(d *gorm.DB) { db = d - err := AutoMigrate(new(model.Storage), new(model.User), new(model.Meta), new(model.SettingItem), new(model.SearchNode), new(model.TaskItem), new(model.SSHPublicKey)) + err := AutoMigrate(new(model.Storage), new(model.User), new(model.Meta), new(model.SettingItem), new(model.SearchNode), new(model.TaskItem), new(model.SSHPublicKey), + new(model.Permission), new(model.Role)) if err != nil { log.Fatalf("failed migrate database: %s", err.Error()) } diff --git a/internal/db/permission.go b/internal/db/permission.go new file mode 100644 index 00000000..556fd738 --- /dev/null +++ b/internal/db/permission.go @@ -0,0 +1,53 @@ +package db + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/pkg/errors" +) + +func CreatePermission(p *model.Permission) error { + return errors.WithStack(db.Create(p).Error) +} + +func UpdatePermission(p *model.Permission) error { + return errors.WithStack(db.Save(p).Error) +} + +func GetPermissions(pageIndex, pageSize int) (permissions []model.Permission, count int64, err error) { + permissionDB := db.Model(&model.Permission{}) + if err := permissionDB.Count(&count).Error; err != nil { + return nil, 0, errors.Wrapf(err, "failed get permissions count") + } + if err := permissionDB.Order(columnName("id")).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&permissions).Error; err != nil { + return nil, 0, errors.Wrapf(err, "failed get find permissions") + } + return permissions, count, nil +} + +func DeletePermissionById(id uint) error { + return errors.WithStack(db.Delete(&model.Permission{}, id).Error) +} + +func GetPermissionById(id uint) (*model.Permission, error) { + var p model.Permission + if err := db.First(&p, id).Error; err != nil { + return nil, errors.Wrapf(err, "failed get permission by id %d", id) + } + return &p, nil +} + +func GetPermissionByIds(ids []uint) ([]model.Permission, error) { + var p []model.Permission + if err := db.Where("id in (?)", ids).First(&p).Error; err != nil { + return nil, errors.Wrapf(err, "failed get permission by ids %v", ids) + } + return p, nil +} + +func GetPermissionByName(name string) (*model.Permission, error) { + var p model.Permission + if err := db.Where("name = ?", name).First(&p).Error; err != nil { + return nil, errors.Wrapf(err, "failed get permission by name %v", name) + } + return &p, nil +} diff --git a/internal/db/role.go b/internal/db/role.go new file mode 100644 index 00000000..187330b1 --- /dev/null +++ b/internal/db/role.go @@ -0,0 +1,53 @@ +package db + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/pkg/errors" +) + +func CreateRole(r *model.Role) error { + return errors.WithStack(db.Create(r).Error) +} + +func UpdateRole(r *model.Role) error { + return errors.WithStack(db.Save(r).Error) +} + +func GetRoles(pageIndex, pageSize int) (roles []model.Role, count int64, err error) { + roleDB := db.Model(&model.Role{}) + if err := roleDB.Count(&count).Error; err != nil { + return nil, 0, errors.Wrapf(err, "failed get roles count") + } + if err := roleDB.Order(columnName("id")).Offset((pageIndex - 1) * pageSize).Limit(pageSize).Find(&roles).Error; err != nil { + return nil, 0, errors.Wrapf(err, "failed get find roles") + } + return roles, count, nil +} + +func DeleteRoleById(id uint) error { + return errors.WithStack(db.Delete(&model.Role{}, id).Error) +} + +func GetRoleById(id uint) (*model.Role, error) { + var r model.Role + if err := db.First(&r, id).Error; err != nil { + return nil, errors.Wrapf(err, "failed get role") + } + return &r, nil +} + +func GetRoleByIds(ids []uint) ([]model.Role, error) { + var r []model.Role + if err := db.Where("id in (?)", ids).Find(&r).Error; err != nil { + return nil, errors.Wrapf(err, "failed get roles by ids: %v", ids) + } + return r, nil +} + +func GetRoleByName(name string) (*model.Role, error) { + var r model.Role + if err := db.Where("name = ?", name).First(&r).Error; err != nil { + return nil, errors.Wrapf(err, "failed get role by name %v", name) + } + return &r, nil +} diff --git a/internal/db/user.go b/internal/db/user.go index 8c9641b2..7a843cf6 100644 --- a/internal/db/user.go +++ b/internal/db/user.go @@ -2,6 +2,7 @@ package db import ( "encoding/base64" + "gorm.io/datatypes" "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/pkg/utils" @@ -9,10 +10,16 @@ import ( "github.com/pkg/errors" ) -func GetUserByRole(role int) (*model.User, error) { - user := model.User{Role: role} +func GetUserByRole(role []int) (*model.User, error) { + var user model.User + /*user := model.User{Role: role} if err := db.Where(user).Take(&user).Error; err != nil { return nil, err + }*/ + cond := datatypes.JSONArrayQuery("role").Contains(role) + err := db.Where(cond).Take(&user).Error + if err != nil { + return nil, err } return &user, nil } diff --git a/internal/model/permission.go b/internal/model/permission.go new file mode 100644 index 00000000..69ecc110 --- /dev/null +++ b/internal/model/permission.go @@ -0,0 +1,128 @@ +package model + +import ( + "encoding/json" + "gorm.io/datatypes" + "gorm.io/gorm" + "time" +) + +type Permission struct { + ID uint `json:"id" gorm:"primaryKey"` //权限唯一主键 + Name string `json:"name"` //权限名称 + // Determine permissions by bit + // 0: can see hidden files + // 1: can access without password + // 2: can add offline download tasks + // 3: can mkdir and upload + // 4: can rename + // 5: can move + // 6: can copy + // 7: can remove + // 8: webdav read + // 9: webdav write + // 10: ftp/sftp login and read + // 11: ftp/sftp write + // 12: can read archives + // 13: can decompress archives + // 14: dir access control + Permission int32 `json:"permission"` + PathPattern string `json:"path_pattern"` // 目录路径模式 + AllowOp datatypes.JSON `gorm:"type:json;column:allow_op" json:"allow_op"` //允许的操作upload/download/delete等 + AllowOpInfo AllowOpSlice `gorm:"-" json:"allow_op_info"` + CreateTime time.Time `json:"create_time"` //创建时间 + UpdateTime time.Time `json:"update_time"` //修改时间 +} + +type AllowOpSlice []string + +func (p *Permission) BeforeCreate(db *gorm.DB) (err error) { + if p.AllowOpInfo != nil { + p.AllowOp, err = json.Marshal(p.AllowOpInfo) + if err != nil { + return + } + } + return nil +} + +func (p *Permission) BeforeUpdate(db *gorm.DB) (err error) { + if p.AllowOpInfo != nil { + p.AllowOp, err = json.Marshal(p.AllowOpInfo) + if err != nil { + return + } + } + return nil +} + +func (p *Permission) AfterFind(db *gorm.DB) (err error) { + p.AllowOpInfo = AllowOpSlice{} + if len(p.AllowOp) > 0 { + err = json.Unmarshal(p.AllowOp, &p.AllowOpInfo) + if err != nil { + return + } + } + return nil +} + +func (p *Permission) CanSeeHides() bool { + return p.Permission&1 == 1 +} + +func (p *Permission) CanAccessWithoutPassword() bool { + return (p.Permission>>1)&1 == 1 +} + +func (p *Permission) CanAddOfflineDownloadTasks() bool { + return (p.Permission>>2)&1 == 1 +} + +func (p *Permission) CanWrite() bool { + return (p.Permission>>3)&1 == 1 +} + +func (p *Permission) CanRename() bool { + return (p.Permission>>4)&1 == 1 +} + +func (p *Permission) CanMove() bool { + return (p.Permission>>5)&1 == 1 +} + +func (p *Permission) CanCopy() bool { + return (p.Permission>>6)&1 == 1 +} + +func (p *Permission) CanRemove() bool { + return (p.Permission>>7)&1 == 1 +} + +func (p *Permission) CanWebdavRead() bool { + return (p.Permission>>8)&1 == 1 +} + +func (p *Permission) CanWebdavManage() bool { + return (p.Permission>>9)&1 == 1 +} + +func (p *Permission) CanFTPAccess() bool { + return (p.Permission>>10)&1 == 1 +} + +func (p *Permission) CanFTPManage() bool { + return (p.Permission>>11)&1 == 1 +} + +func (p *Permission) CanReadArchives() bool { + return (p.Permission>>12)&1 == 1 +} + +func (p *Permission) CanDecompress() bool { + return (p.Permission>>13)&1 == 1 +} + +func (p *Permission) CanAccessDir() bool { + return (p.Permission>>14)&1 == 1 +} diff --git a/internal/model/role.go b/internal/model/role.go new file mode 100644 index 00000000..7381f1b9 --- /dev/null +++ b/internal/model/role.go @@ -0,0 +1,49 @@ +package model + +import ( + "encoding/json" + "gorm.io/datatypes" + "gorm.io/gorm" + "time" +) + +type Role struct { + ID uint `json:"id" gorm:"primaryKey"` //角色唯一主键 + Name string `json:"name"` //角色名称 + Permissions datatypes.JSON `gorm:"type:json;column:permissions" json:"permissions"` //权限id + PermissionInfo PermissionIdSlice `gorm:"-" json:"permission_info"` + CreateTime time.Time `json:"create_time"` //创建时间 + UpdateTime time.Time `json:"update_time"` //修改时间 +} +type PermissionIdSlice []uint + +func (r *Role) BeforeCreate(db *gorm.DB) (err error) { + if r.PermissionInfo != nil { + r.Permissions, err = json.Marshal(r.PermissionInfo) + if err != nil { + return + } + } + return nil +} + +func (r *Role) BeforeUpdate(db *gorm.DB) (err error) { + if r.PermissionInfo != nil { + r.Permissions, err = json.Marshal(r.PermissionInfo) + if err != nil { + return + } + } + return nil +} + +func (r *Role) AfterFind(db *gorm.DB) (err error) { + r.PermissionInfo = PermissionIdSlice{} + if len(r.Permissions) > 0 { + err = json.Unmarshal(r.Permissions, &r.PermissionInfo) + if err != nil { + return + } + } + return nil +} diff --git a/internal/model/user.go b/internal/model/user.go index eaa0fed9..37334e5d 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -4,6 +4,8 @@ import ( "encoding/binary" "encoding/json" "fmt" + "gorm.io/datatypes" + "gorm.io/gorm" "time" "github.com/alist-org/alist/v3/internal/errs" @@ -22,15 +24,16 @@ const ( const StaticHashSalt = "https://github.com/alist-org/alist" type User struct { - ID uint `json:"id" gorm:"primaryKey"` // unique key - Username string `json:"username" gorm:"unique" binding:"required"` // username - PwdHash string `json:"-"` // password hash - PwdTS int64 `json:"-"` // password timestamp - Salt string `json:"-"` // unique salt - Password string `json:"password"` // password - BasePath string `json:"base_path"` // base path - Role int `json:"role"` // user's role - Disabled bool `json:"disabled"` + ID uint `json:"id" gorm:"primaryKey"` // unique key + Username string `json:"username" gorm:"unique" binding:"required"` // username + PwdHash string `json:"-"` // password hash + PwdTS int64 `json:"-"` // password timestamp + Salt string `json:"-"` // unique salt + Password string `json:"password"` // password + BasePath string `json:"base_path"` // base path + Role datatypes.JSON `gorm:"type:json;column:role" json:"role"` // user's role + RoleInfo RoleIdSlice `gorm:"-" json:"role_info"` + Disabled bool `json:"disabled"` // Determine permissions by bit // 0: can see hidden files // 1: can access without password @@ -52,12 +55,60 @@ type User struct { Authn string `gorm:"type:text" json:"-"` } +type RoleIdSlice []uint + +func (u *User) BeforeCreate(db *gorm.DB) (err error) { + if u.RoleInfo != nil { + u.Role, err = json.Marshal(u.RoleInfo) + if err != nil { + return + } + } + return nil +} + +func (u *User) BeforeUpdate(db *gorm.DB) (err error) { + if u.RoleInfo != nil { + u.Role, err = json.Marshal(u.RoleInfo) + if err != nil { + return + } + } + return nil +} + +func (u *User) AfterFind(db *gorm.DB) (err error) { + u.RoleInfo = RoleIdSlice{} + if len(u.Role) > 0 { + err = json.Unmarshal(u.Role, &u.RoleInfo) + if err != nil { + return + } + } + return nil +} + func (u *User) IsGuest() bool { - return u.Role == GUEST + isGuest := true + for _, role := range u.Role { + if role != GUEST { + isGuest = false + break + } + } + return isGuest + //return u.Role == GUEST } func (u *User) IsAdmin() bool { - return u.Role == ADMIN + isAdmin := true + for _, role := range u.Role { + if role != ADMIN { + isAdmin = false + } + } + return isAdmin + //return u.Role == ADMIN } func (u *User) ValidateRawPassword(password string) error { diff --git a/internal/op/permission.go b/internal/op/permission.go new file mode 100644 index 00000000..83a86156 --- /dev/null +++ b/internal/op/permission.go @@ -0,0 +1,30 @@ +package op + +import ( + "github.com/alist-org/alist/v3/internal/db" + "github.com/alist-org/alist/v3/internal/model" +) + +func CreatePermission(p *model.Permission) error { + return db.CreatePermission(p) +} + +func GetPermissions(pageIndex, pageSize int) (permissions []model.Permission, count int64, err error) { + return db.GetPermissions(pageIndex, pageSize) +} + +func GetPermissionById(id uint) (*model.Permission, error) { + return db.GetPermissionById(id) +} + +func UpdatePermission(p *model.Permission) error { + return db.UpdatePermission(p) +} + +func DeletePermissionById(id uint) error { + return db.DeletePermissionById(id) +} + +func GetPermissionByName(name string) (*model.Permission, error) { + return db.GetPermissionByName(name) +} diff --git a/internal/op/role.go b/internal/op/role.go new file mode 100644 index 00000000..01fa7e3b --- /dev/null +++ b/internal/op/role.go @@ -0,0 +1,50 @@ +package op + +import ( + "github.com/alist-org/alist/v3/internal/db" + "github.com/alist-org/alist/v3/internal/model" +) + +func CreateRole(r *model.Role) error { + return db.CreateRole(r) +} + +func GetRoles(pageIndex, pageSize int) (roles []model.Role, count int64, err error) { + return db.GetRoles(pageIndex, pageSize) +} + +func GetRoleById(id uint) (*model.Role, error) { + return db.GetRoleById(id) +} + +func GetRoleByIds(ids []uint) ([]model.Role, error) { + return db.GetRoleByIds(ids) +} + +func UpdateRole(r *model.Role) error { + return db.UpdateRole(r) +} + +func DeleteRoleById(id uint) error { + return db.DeleteRoleById(id) +} + +func GetPermissionByRoleIds(ids []uint) ([]model.Permission, error) { + roles, err := db.GetRoleByIds(ids) + if err != nil { + return nil, err + } + perIds := make([]uint, 0) + for _, v := range roles { + perIds = append(perIds, v.PermissionInfo...) + } + permissions, err := db.GetPermissionByIds(perIds) + if err != nil { + return nil, err + } + return permissions, nil +} + +func GetRoleByName(name string) (*model.Role, error) { + return db.GetRoleByName(name) +} diff --git a/internal/op/user.go b/internal/op/user.go index 79e73db8..9f2d55fe 100644 --- a/internal/op/user.go +++ b/internal/op/user.go @@ -18,7 +18,7 @@ var adminUser *model.User func GetAdmin() (*model.User, error) { if adminUser == nil { - user, err := db.GetUserByRole(model.ADMIN) + user, err := db.GetUserByRole([]int{model.ADMIN}) if err != nil { return nil, err } @@ -29,7 +29,7 @@ func GetAdmin() (*model.User, error) { func GetGuest() (*model.User, error) { if guestUser == nil { - user, err := db.GetUserByRole(model.GUEST) + user, err := db.GetUserByRole([]int{model.GUEST}) if err != nil { return nil, err } @@ -38,7 +38,7 @@ func GetGuest() (*model.User, error) { return guestUser, nil } -func GetUserByRole(role int) (*model.User, error) { +func GetUserByRole(role []int) (*model.User, error) { return db.GetUserByRole(role) } diff --git a/server/handles/auth.go b/server/handles/auth.go index 7a2c0fb5..eeb7253c 100644 --- a/server/handles/auth.go +++ b/server/handles/auth.go @@ -89,7 +89,10 @@ func loginHash(c *gin.Context, req *LoginReq) { type UserResp struct { model.User - Otp bool `json:"otp"` + Otp bool `json:"otp"` + Permission int32 `json:"permission"` + PathPattern []string `json:"path_pattern"` // 目录路径模式,当Permission第14bit位为1时用到 + AllowOpInfo model.AllowOpSlice `json:"allow_op_info"` } // CurrentUser get current user by token @@ -103,9 +106,41 @@ func CurrentUser(c *gin.Context) { if userResp.OtpSecret != "" { userResp.Otp = true } + permissions, err := op.GetPermissionByRoleIds(user.RoleInfo) + if err != nil || len(permissions) == 0 { + common.ErrorResp(c, err, 400) + } + if len(permissions) == 1 { + userResp.Permission = permissions[0].Permission + userResp.PathPattern = append(userResp.PathPattern, permissions[0].PathPattern) + userResp.AllowOpInfo = permissions[0].AllowOpInfo + } else { + var per int32 + for _, perm := range permissions { + per |= perm.Permission + userResp.PathPattern = append(userResp.PathPattern, perm.PathPattern) + userResp.AllowOpInfo = append(userResp.AllowOpInfo, perm.AllowOpInfo...) + } + userResp.PathPattern = uniqStr(userResp.PathPattern) + userResp.AllowOpInfo = uniqStr(userResp.AllowOpInfo) + userResp.Permission = per + } common.SuccessResp(c, userResp) } +func uniqStr(str []string) []string { + seen := make(map[string]int) + j := 0 + for i, v := range str { + if _, ok := seen[v]; !ok { + str[j] = str[i] + seen[v] = j + j++ + } + } + return str[:j] +} + func UpdateCurrent(c *gin.Context) { var req model.User if err := c.ShouldBind(&req); err != nil { diff --git a/server/handles/ldap_login.go b/server/handles/ldap_login.go index cf314829..0c81576c 100644 --- a/server/handles/ldap_login.go +++ b/server/handles/ldap_login.go @@ -131,8 +131,9 @@ func ladpRegister(username string) (*model.User, error) { Password: random.String(16), Permission: int32(setting.GetInt(conf.LdapDefaultPermission, 0)), BasePath: setting.GetStr(conf.LdapDefaultDir), - Role: 0, - Disabled: false, + //Role: []int{0}, + RoleInfo: []uint{0}, + Disabled: false, } if err := db.CreateUser(user); err != nil { return nil, err diff --git a/server/handles/permission.go b/server/handles/permission.go new file mode 100644 index 00000000..f345d554 --- /dev/null +++ b/server/handles/permission.go @@ -0,0 +1,69 @@ +package handles + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/server/common" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + "strconv" +) + +func CreatePermission(c *gin.Context) { + var req model.Permission + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.CreatePermission(&req); err != nil { + common.ErrorResp(c, err, 500, true) + } else { + common.SuccessResp(c) + } +} + +func ListPermissions(c *gin.Context) { + var req model.PageReq + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + req.Validate() + log.Debugf("%+v", req) + permissions, total, err := op.GetPermissions(req.Page, req.PerPage) + if err != nil { + common.ErrorResp(c, err, 500, true) + return + } + common.SuccessResp(c, common.PageResp{ + Content: permissions, + Total: total, + }) +} + +func UpdatePermission(c *gin.Context) { + var req model.Permission + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.UpdatePermission(&req); err != nil { + common.ErrorResp(c, err, 500) + } else { + common.SuccessResp(c) + } +} + +func DeletePermission(c *gin.Context) { + idStr := c.Query("id") + id, err := strconv.Atoi(idStr) + if err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.DeletePermissionById(uint(id)); err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c) +} diff --git a/server/handles/role.go b/server/handles/role.go new file mode 100644 index 00000000..776185ca --- /dev/null +++ b/server/handles/role.go @@ -0,0 +1,87 @@ +package handles + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/server/common" + "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" + "strconv" +) + +func CreateRole(c *gin.Context) { + var req model.Role + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.CreateRole(&req); err != nil { + common.ErrorResp(c, err, 500, true) + } else { + common.SuccessResp(c) + } +} + +func ListRoles(c *gin.Context) { + var req model.PageReq + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + req.Validate() + log.Debugf("%+v", req) + permissions, total, err := op.GetRoles(req.Page, req.PerPage) + if err != nil { + common.ErrorResp(c, err, 500, true) + return + } + common.SuccessResp(c, common.PageResp{ + Content: permissions, + Total: total, + }) +} + +func UpdateRole(c *gin.Context) { + var req model.Role + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.UpdateRole(&req); err != nil { + common.ErrorResp(c, err, 500) + } else { + common.SuccessResp(c) + } +} + +func DeleteRole(c *gin.Context) { + idStr := c.Query("id") + id, err := strconv.Atoi(idStr) + if err != nil { + common.ErrorResp(c, err, 400) + return + } + if err := op.DeleteRoleById(uint(id)); err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c) +} + +type GetPermissionByRoleIdsReq struct { + Ids []uint `json:"ids"` +} + +func GetPermissionByRoleIds(c *gin.Context) { + var req GetPermissionByRoleIdsReq + if err := c.ShouldBind(&req); err != nil { + common.ErrorResp(c, err, 400) + return + } + permissions, err := op.GetPermissionByRoleIds(req.Ids) + if err != nil { + common.ErrorResp(c, err, 500) + return + } + common.SuccessResp(c, permissions) +} diff --git a/server/handles/ssologin.go b/server/handles/ssologin.go index 62bd4aaa..d0fc8836 100644 --- a/server/handles/ssologin.go +++ b/server/handles/ssologin.go @@ -154,9 +154,10 @@ func autoRegister(username, userID string, err error) (*model.User, error) { Password: random.String(16), Permission: int32(setting.GetInt(conf.SSODefaultPermission, 0)), BasePath: setting.GetStr(conf.SSODefaultDir), - Role: 0, - Disabled: false, - SsoID: userID, + //Role: []int{0}, + RoleInfo: []uint{0}, + Disabled: false, + SsoID: userID, } if err = db.CreateUser(user); err != nil { if strings.HasPrefix(err.Error(), "UNIQUE constraint failed") && strings.HasSuffix(err.Error(), "username") { diff --git a/server/handles/task.go b/server/handles/task.go index af7974a9..710a9911 100644 --- a/server/handles/task.go +++ b/server/handles/task.go @@ -42,7 +42,7 @@ func getTaskInfo[T task.TaskExtensionInfo](task T) TaskInfo { creatorRole := -1 if task.GetCreator() != nil { creatorName = task.GetCreator().Username - creatorRole = task.GetCreator().Role + creatorRole = int(task.GetCreator().RoleInfo[0]) } return TaskInfo{ ID: task.GetID(), diff --git a/server/handles/user.go b/server/handles/user.go index 4d404a4c..3adf7970 100644 --- a/server/handles/user.go +++ b/server/handles/user.go @@ -60,10 +60,10 @@ func UpdateUser(c *gin.Context) { common.ErrorResp(c, err, 500) return } - if user.Role != req.Role { + /*if !reflect.DeepEqual(user.Role, req.Role) { common.ErrorStrResp(c, "role can not be changed", 400) return - } + }*/ if req.Password == "" { req.PwdHash = user.PwdHash req.Salt = user.Salt diff --git a/server/router.go b/server/router.go index 09a0bb44..a9cd080c 100644 --- a/server/router.go +++ b/server/router.go @@ -161,6 +161,20 @@ func admin(g *gin.RouterGroup) { index.POST("/stop", middlewares.SearchIndex, handles.StopIndex) index.POST("/clear", middlewares.SearchIndex, handles.ClearIndex) index.GET("/progress", middlewares.SearchIndex, handles.GetProgress) + + permission := g.Group("/permission") + permission.POST("/create", handles.CreatePermission) + permission.GET("/list", handles.ListPermissions) + permission.POST("/update", handles.UpdatePermission) + permission.POST("/delete", handles.DeletePermission) + + role := g.Group("/role") + role.POST("/create", handles.CreateRole) + role.GET("/list", handles.ListRoles) + role.POST("/update", handles.UpdateRole) + role.POST("/delete", handles.DeleteRole) + role.GET("/get_permission", handles.GetPermissionByRoleIds) + } func _fs(g *gin.RouterGroup) {