mirror of https://github.com/Xhofe/alist
feat: add user registration endpoint and role-based default settings (#9277)
* feat(setting): add role-based default and registration settings (closed #feat/register-and-statistics) - Added `AllowRegister` and `DefaultRole` settings to site configuration. - Integrated dynamic role options for `DefaultRole` using `op.GetRoles`. - Updated `setting.go` handlers to manage `DefaultRole` options dynamically. - Modified `const.go` to include new site settings constants. - Updated dependencies in `go.mod` and `go.sum` to support new functionality. * feat(register-and-statistics): add user registration endpoint - Added `POST /auth/register` endpoint to support user registration. - Implemented registration logic in `auth.go` with dynamic role assignment. - Integrated settings `AllowRegister` and `DefaultRole` for registration flow. - Updated imports to include new modules: `conf`, `setting`. - Adjusted user creation logic to use `DefaultRole` setting dynamically. * feat(register-and-statistics): add user registration endpoint (#register-and-statistics) - Added `POST /auth/register` endpoint to support user registration. - Implemented registration logic in `auth.go` with dynamic role assignment. - Integrated `AllowRegister` and `DefaultRole` settings for registration flow. - Updated imports to include new modules: `conf`, `setting`. - Adjusted user creation logic to use `DefaultRole` dynamically. * feat(register-and-statistics): enhance role management logic (#register-and-statistics) - Refactored CreateRole and UpdateRole functions to handle default role. - Added dynamic role assignment logic in 'role.go' using conf settings. - Improved request handling in 'handles/role.go' with structured data. - Implemented default role logic in 'db/role.go' to update non-default roles. - Modified 'model/role.go' to include a 'Default' field for role management. * feat(register-and-statistics): enhance role management logic - Refactor CreateRole and UpdateRole to handle default roles. - Add dynamic role assignment using conf settings in 'role.go'. - Improve request handling with structured data in 'handles/role.go'. - Implement default role logic in 'db/role.go' for non-default roles. - Modify 'model/role.go' to include 'Default' field for role management. * feat(register-and-statistics): improve role handling logic - Switch from role names to role IDs for better consistency. - Update logic to prioritize "guest" for default role ID. - Adjust `DefaultRole` setting to use role IDs. - Refactor `getRoleOptions` to return role IDs as a comma-separated string. * feat(register-and-statistics): improve role handling logicmain
parent
97d4f79b96
commit
eca500861a
9
go.mod
9
go.mod
|
@ -3,6 +3,8 @@ module github.com/alist-org/alist/v3
|
||||||
go 1.23.4
|
go 1.23.4
|
||||||
|
|
||||||
require (
|
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/ftpserverlib-pasvportmap v1.25.0
|
||||||
github.com/KirCute/sftpd-alist v0.0.12
|
github.com/KirCute/sftpd-alist v0.0.12
|
||||||
github.com/ProtonMail/go-crypto v1.0.0
|
github.com/ProtonMail/go-crypto v1.0.0
|
||||||
|
@ -79,11 +81,7 @@ require (
|
||||||
gorm.io/gorm v1.25.11
|
gorm.io/gorm v1.25.11
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.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 (
|
require (
|
||||||
github.com/STARRY-S/zip v0.2.1 // indirect
|
github.com/STARRY-S/zip v0.2.1 // indirect
|
||||||
|
@ -109,7 +107,6 @@ require (
|
||||||
github.com/ipfs/boxo v0.12.0 // indirect
|
github.com/ipfs/boxo v0.12.0 // indirect
|
||||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||||
github.com/klauspost/pgzip v1.2.6 // 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/matoous/go-nanoid/v2 v2.1.0 // indirect
|
||||||
github.com/microcosm-cc/bluemonday v1.0.27
|
github.com/microcosm-cc/bluemonday v1.0.27
|
||||||
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78
|
github.com/nwaples/rardecode/v2 v2.0.0-beta.4.0.20241112120701-034e449c6e78
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -21,10 +21,16 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||||
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 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/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 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/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 h1:UXT0o77lXQrikd1kgwIPQOUect7EoR/+sbP4wQKdzxM=
|
||||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0/go.mod h1:cTvi54pg19DoT07ekoeMgE/taAwNtCShVeZqA+Iv2xI=
|
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 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
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=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
|
@ -172,7 +178,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/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 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg=
|
||||||
github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE=
|
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.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.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||||
|
@ -398,6 +403,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.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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
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 h1:DLQQEgHUAGZB6RVlceB1f6A94O206exxW2RIMH+gMUc=
|
||||||
github.com/larksuite/oapi-sdk-go/v3 v3.3.1/go.mod h1:ZEplY+kwuIrj/nqw5uSCINNATcH3KdxSN7y+UxYY5fI=
|
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=
|
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||||
|
@ -492,6 +499,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/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 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
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.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -739,8 +748,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.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
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.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 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
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=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
|
|
@ -2,6 +2,7 @@ package data
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/cmd/flags"
|
"github.com/alist-org/alist/v3/cmd/flags"
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
|
@ -91,6 +92,21 @@ func InitialSettings() []model.SettingItem {
|
||||||
} else {
|
} else {
|
||||||
token = random.Token()
|
token = random.Token()
|
||||||
}
|
}
|
||||||
|
roles, _, err := op.GetRoles(1, model.MaxInt)
|
||||||
|
if err != nil {
|
||||||
|
utils.Log.Fatalf("failed get roles: %+v", err)
|
||||||
|
}
|
||||||
|
roleNames := make([]string, len(roles))
|
||||||
|
defaultRoleID := ""
|
||||||
|
for i, role := range roles {
|
||||||
|
roleNames[i] = role.Name
|
||||||
|
if role.Name == "guest" {
|
||||||
|
defaultRoleID = strconv.Itoa(int(role.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if defaultRoleID == "" && len(roles) > 0 {
|
||||||
|
defaultRoleID = strconv.Itoa(int(roles[0].ID))
|
||||||
|
}
|
||||||
initialSettingItems = []model.SettingItem{
|
initialSettingItems = []model.SettingItem{
|
||||||
// site settings
|
// site settings
|
||||||
{Key: conf.VERSION, Value: conf.Version, Type: conf.TypeString, Group: model.SITE, Flag: model.READONLY},
|
{Key: conf.VERSION, Value: conf.Version, Type: conf.TypeString, Group: model.SITE, Flag: model.READONLY},
|
||||||
|
@ -103,6 +119,8 @@ func InitialSettings() []model.SettingItem {
|
||||||
{Key: conf.AllowIndexed, Value: "false", Type: conf.TypeBool, Group: model.SITE},
|
{Key: conf.AllowIndexed, Value: "false", Type: conf.TypeBool, Group: model.SITE},
|
||||||
{Key: conf.AllowMounted, Value: "true", Type: conf.TypeBool, Group: model.SITE},
|
{Key: conf.AllowMounted, Value: "true", Type: conf.TypeBool, Group: model.SITE},
|
||||||
{Key: conf.RobotsTxt, Value: "User-agent: *\nAllow: /", Type: conf.TypeText, Group: model.SITE},
|
{Key: conf.RobotsTxt, Value: "User-agent: *\nAllow: /", Type: conf.TypeText, Group: model.SITE},
|
||||||
|
{Key: conf.AllowRegister, Value: "false", Type: conf.TypeBool, Group: model.SITE},
|
||||||
|
{Key: conf.DefaultRole, Value: defaultRoleID, Type: conf.TypeSelect, Options: strings.Join(roleNames, ","), Group: model.SITE},
|
||||||
// newui settings
|
// newui settings
|
||||||
{Key: conf.UseNewui, Value: "false", Type: conf.TypeBool, Group: model.SITE},
|
{Key: conf.UseNewui, Value: "false", Type: conf.TypeBool, Group: model.SITE},
|
||||||
// style settings
|
// style settings
|
||||||
|
|
|
@ -16,6 +16,8 @@ const (
|
||||||
AllowIndexed = "allow_indexed"
|
AllowIndexed = "allow_indexed"
|
||||||
AllowMounted = "allow_mounted"
|
AllowMounted = "allow_mounted"
|
||||||
RobotsTxt = "robots_txt"
|
RobotsTxt = "robots_txt"
|
||||||
|
AllowRegister = "allow_register"
|
||||||
|
DefaultRole = "default_role"
|
||||||
UseNewui = "use_newui"
|
UseNewui = "use_newui"
|
||||||
|
|
||||||
Logo = "logo"
|
Logo = "logo"
|
||||||
|
|
|
@ -35,11 +35,27 @@ func GetRoles(pageIndex, pageSize int) (roles []model.Role, count int64, err err
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateRole(r *model.Role) error {
|
func CreateRole(r *model.Role) error {
|
||||||
return errors.WithStack(db.Create(r).Error)
|
if err := db.Create(r).Error; err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
if r.Default {
|
||||||
|
if err := db.Model(&model.Role{}).Where("id <> ?", r.ID).Update("default", false).Error; err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateRole(r *model.Role) error {
|
func UpdateRole(r *model.Role) error {
|
||||||
return errors.WithStack(db.Save(r).Error)
|
if err := db.Save(r).Error; err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
if r.Default {
|
||||||
|
if err := db.Model(&model.Role{}).Where("id <> ?", r.ID).Update("default", false).Error; err != nil {
|
||||||
|
return errors.WithStack(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteRole(id uint) error {
|
func DeleteRole(id uint) error {
|
||||||
|
|
|
@ -17,6 +17,7 @@ type Role struct {
|
||||||
ID uint `json:"id" gorm:"primaryKey"`
|
ID uint `json:"id" gorm:"primaryKey"`
|
||||||
Name string `json:"name" gorm:"unique" binding:"required"`
|
Name string `json:"name" gorm:"unique" binding:"required"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
|
Default bool `json:"default" gorm:"default:false"`
|
||||||
// PermissionScopes stores structured permission list and is ignored by gorm.
|
// PermissionScopes stores structured permission list and is ignored by gorm.
|
||||||
PermissionScopes []PermissionEntry `json:"permission_scopes" gorm:"-"`
|
PermissionScopes []PermissionEntry `json:"permission_scopes" gorm:"-"`
|
||||||
// RawPermission is the JSON representation of PermissionScopes stored in DB.
|
// RawPermission is the JSON representation of PermissionScopes stored in DB.
|
||||||
|
|
|
@ -2,6 +2,7 @@ package op
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/alist-org/alist/v3/internal/conf"
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
|
@ -82,6 +83,18 @@ var settingItemHooks = map[string]SettingItemHook{
|
||||||
conf.SlicesMap[conf.IgnoreDirectLinkParams] = strings.Split(item.Value, ",")
|
conf.SlicesMap[conf.IgnoreDirectLinkParams] = strings.Split(item.Value, ",")
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
conf.DefaultRole: func(item *model.SettingItem) error {
|
||||||
|
v := strings.TrimSpace(item.Value)
|
||||||
|
if v == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
r, err := GetRoleByName(v)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.Value = strconv.Itoa(int(r.ID))
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func RegisterSettingItemHook(key string, hook SettingItemHook) {
|
func RegisterSettingItemHook(key string, hook SettingItemHook) {
|
||||||
|
|
|
@ -2,9 +2,11 @@ package op
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Xhofe/go-cache"
|
"github.com/Xhofe/go-cache"
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/db"
|
"github.com/alist-org/alist/v3/internal/db"
|
||||||
"github.com/alist-org/alist/v3/internal/errs"
|
"github.com/alist-org/alist/v3/internal/errs"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
|
@ -50,6 +52,23 @@ func GetRoleByName(name string) (*model.Role, error) {
|
||||||
return r, err
|
return r, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetDefaultRoleID() int {
|
||||||
|
item, err := GetSettingItemByKey(conf.DefaultRole)
|
||||||
|
if err == nil && item != nil && item.Value != "" {
|
||||||
|
if id, err := strconv.Atoi(item.Value); err == nil && id != 0 {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
if r, err := db.GetRoleByName(item.Value); err == nil {
|
||||||
|
return int(r.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var r model.Role
|
||||||
|
if err := db.GetDb().Where("`default` = ?", true).First(&r).Error; err == nil {
|
||||||
|
return int(r.ID)
|
||||||
|
}
|
||||||
|
return int(model.GUEST)
|
||||||
|
}
|
||||||
|
|
||||||
func GetRolesByUserID(userID uint) ([]model.Role, error) {
|
func GetRolesByUserID(userID uint) ([]model.Role, error) {
|
||||||
user, err := GetUserById(userID)
|
user, err := GetUserById(userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -92,7 +111,21 @@ func CreateRole(r *model.Role) error {
|
||||||
}
|
}
|
||||||
roleCache.Del(fmt.Sprint(r.ID))
|
roleCache.Del(fmt.Sprint(r.ID))
|
||||||
roleCache.Del(r.Name)
|
roleCache.Del(r.Name)
|
||||||
return db.CreateRole(r)
|
if err := db.CreateRole(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if r.Default {
|
||||||
|
roleCache.Clear()
|
||||||
|
item, err := GetSettingItemByKey(conf.DefaultRole)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.Value = strconv.Itoa(int(r.ID))
|
||||||
|
if err := SaveSettingItem(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateRole(r *model.Role) error {
|
func UpdateRole(r *model.Role) error {
|
||||||
|
@ -131,7 +164,21 @@ func UpdateRole(r *model.Role) error {
|
||||||
//}
|
//}
|
||||||
roleCache.Del(fmt.Sprint(r.ID))
|
roleCache.Del(fmt.Sprint(r.ID))
|
||||||
roleCache.Del(r.Name)
|
roleCache.Del(r.Name)
|
||||||
return db.UpdateRole(r)
|
if err := db.UpdateRole(r); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if r.Default {
|
||||||
|
roleCache.Clear()
|
||||||
|
item, err := GetSettingItemByKey(conf.DefaultRole)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
item.Value = strconv.Itoa(int(r.ID))
|
||||||
|
if err := SaveSettingItem(item); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func DeleteRole(id uint) error {
|
func DeleteRole(id uint) error {
|
||||||
|
|
|
@ -9,8 +9,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Xhofe/go-cache"
|
"github.com/Xhofe/go-cache"
|
||||||
|
"github.com/alist-org/alist/v3/internal/conf"
|
||||||
"github.com/alist-org/alist/v3/internal/model"
|
"github.com/alist-org/alist/v3/internal/model"
|
||||||
"github.com/alist-org/alist/v3/internal/op"
|
"github.com/alist-org/alist/v3/internal/op"
|
||||||
|
"github.com/alist-org/alist/v3/internal/setting"
|
||||||
"github.com/alist-org/alist/v3/server/common"
|
"github.com/alist-org/alist/v3/server/common"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pquerna/otp/totp"
|
"github.com/pquerna/otp/totp"
|
||||||
|
@ -89,6 +91,35 @@ func loginHash(c *gin.Context, req *LoginReq) {
|
||||||
loginCache.Del(ip)
|
loginCache.Del(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RegisterReq struct {
|
||||||
|
Username string `json:"username" binding:"required"`
|
||||||
|
Password string `json:"password" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register a new user
|
||||||
|
func Register(c *gin.Context) {
|
||||||
|
if !setting.GetBool(conf.AllowRegister) {
|
||||||
|
common.ErrorStrResp(c, "registration is disabled", 403)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var req RegisterReq
|
||||||
|
if err := c.ShouldBind(&req); err != nil {
|
||||||
|
common.ErrorResp(c, err, 400)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
user := &model.User{
|
||||||
|
Username: req.Username,
|
||||||
|
Role: model.Roles{op.GetDefaultRoleID()},
|
||||||
|
Authn: "[]",
|
||||||
|
}
|
||||||
|
user.SetPassword(req.Password)
|
||||||
|
if err := op.CreateUser(user); err != nil {
|
||||||
|
common.ErrorResp(c, err, 500, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
common.SuccessResp(c)
|
||||||
|
}
|
||||||
|
|
||||||
type UserResp struct {
|
type UserResp struct {
|
||||||
model.User
|
model.User
|
||||||
Otp bool `json:"otp"`
|
Otp bool `json:"otp"`
|
||||||
|
|
|
@ -44,7 +44,7 @@ func GetRole(c *gin.Context) {
|
||||||
|
|
||||||
func CreateRole(c *gin.Context) {
|
func CreateRole(c *gin.Context) {
|
||||||
var req model.Role
|
var req model.Role
|
||||||
if err := c.ShouldBind(&req); err != nil {
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,14 @@ func CreateRole(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UpdateRole(c *gin.Context) {
|
func UpdateRole(c *gin.Context) {
|
||||||
var req model.Role
|
var req struct {
|
||||||
if err := c.ShouldBind(&req); err != nil {
|
ID uint `json:"id"`
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
PermissionScopes []model.PermissionEntry `json:"permission_scopes"`
|
||||||
|
Default *bool `json:"default"`
|
||||||
|
}
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -74,7 +80,13 @@ func UpdateRole(c *gin.Context) {
|
||||||
case "guest":
|
case "guest":
|
||||||
req.Name = "guest"
|
req.Name = "guest"
|
||||||
}
|
}
|
||||||
if err := op.UpdateRole(&req); err != nil {
|
role.Name = req.Name
|
||||||
|
role.Description = req.Description
|
||||||
|
role.PermissionScopes = req.PermissionScopes
|
||||||
|
if req.Default != nil {
|
||||||
|
role.Default = *req.Default
|
||||||
|
}
|
||||||
|
if err := op.UpdateRole(role); err != nil {
|
||||||
common.ErrorResp(c, err, 500, true)
|
common.ErrorResp(c, err, 500, true)
|
||||||
} else {
|
} else {
|
||||||
common.SuccessResp(c)
|
common.SuccessResp(c)
|
||||||
|
|
|
@ -14,6 +14,18 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func getRoleOptions() string {
|
||||||
|
roles, _, err := op.GetRoles(1, model.MaxInt)
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
names := make([]string, len(roles))
|
||||||
|
for i, r := range roles {
|
||||||
|
names[i] = r.Name
|
||||||
|
}
|
||||||
|
return strings.Join(names, ",")
|
||||||
|
}
|
||||||
|
|
||||||
func ResetToken(c *gin.Context) {
|
func ResetToken(c *gin.Context) {
|
||||||
token := random.Token()
|
token := random.Token()
|
||||||
item := model.SettingItem{Key: "token", Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE}
|
item := model.SettingItem{Key: "token", Value: token, Type: conf.TypeString, Group: model.SINGLE, Flag: model.PRIVATE}
|
||||||
|
@ -34,6 +46,12 @@ func GetSetting(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if item.Key == conf.DefaultRole {
|
||||||
|
copy := *item
|
||||||
|
copy.Options = getRoleOptions()
|
||||||
|
common.SuccessResp(c, copy)
|
||||||
|
return
|
||||||
|
}
|
||||||
common.SuccessResp(c, item)
|
common.SuccessResp(c, item)
|
||||||
} else {
|
} else {
|
||||||
items, err := op.GetSettingItemInKeys(strings.Split(keys, ","))
|
items, err := op.GetSettingItemInKeys(strings.Split(keys, ","))
|
||||||
|
@ -41,6 +59,12 @@ func GetSetting(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
for i := range items {
|
||||||
|
if items[i].Key == conf.DefaultRole {
|
||||||
|
items[i].Options = getRoleOptions()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
common.SuccessResp(c, items)
|
common.SuccessResp(c, items)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,6 +112,12 @@ func ListSettings(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
for i := range settings {
|
||||||
|
if settings[i].Key == conf.DefaultRole {
|
||||||
|
settings[i].Options = getRoleOptions()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
common.SuccessResp(c, settings)
|
common.SuccessResp(c, settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ func CreateUser(c *gin.Context) {
|
||||||
common.ErrorResp(c, err, 400)
|
common.ErrorResp(c, err, 400)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if len(req.Role) == 0 {
|
||||||
|
req.Role = model.Roles{op.GetDefaultRoleID()}
|
||||||
|
}
|
||||||
if req.IsAdmin() || req.IsGuest() {
|
if req.IsAdmin() || req.IsGuest() {
|
||||||
common.ErrorStrResp(c, "admin or guest user can not be created", 400, true)
|
common.ErrorStrResp(c, "admin or guest user can not be created", 400, true)
|
||||||
return
|
return
|
||||||
|
|
|
@ -61,6 +61,7 @@ func Init(e *gin.Engine) {
|
||||||
api.POST("/auth/login", handles.Login)
|
api.POST("/auth/login", handles.Login)
|
||||||
api.POST("/auth/login/hash", handles.LoginHash)
|
api.POST("/auth/login/hash", handles.LoginHash)
|
||||||
api.POST("/auth/login/ldap", handles.LoginLdap)
|
api.POST("/auth/login/ldap", handles.LoginLdap)
|
||||||
|
api.POST("/auth/register", handles.Register)
|
||||||
auth.GET("/me", handles.CurrentUser)
|
auth.GET("/me", handles.CurrentUser)
|
||||||
auth.POST("/me/update", handles.UpdateCurrent)
|
auth.POST("/me/update", handles.UpdateCurrent)
|
||||||
auth.GET("/me/sshkey/list", handles.ListMyPublicKey)
|
auth.GET("/me/sshkey/list", handles.ListMyPublicKey)
|
||||||
|
|
Loading…
Reference in New Issue