diff --git a/.vscode/launch.json b/.vscode/launch.json index 58bbe14..fcd9618 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "go", "debugAdapter": "dlv-dap", "request": "launch", - "port": 39337, + "port": 36633, "host": "127.0.0.1", "mode": "exec", "program": "${workspaceFolder}/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service" diff --git a/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service b/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service index a760959..cf5ab2e 100755 Binary files a/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service and b/dist/casaos-user-service-amd64_linux_amd64_v1/build/sysroot/usr/bin/casaos-user-service differ diff --git a/dist/metadata.json b/dist/metadata.json index ddea182..4c6e510 100644 --- a/dist/metadata.json +++ b/dist/metadata.json @@ -1 +1 @@ -{"project_name":"casaos-user-service","tag":"v1.0.0","previous_tag":"","version":"1.0.1","commit":"e360248157caa396765f4c7db5e5e5c65240059a","date":"2024-09-25T10:52:32.08272657+07:00","runtime":{"goos":"linux","goarch":"amd64"}} \ No newline at end of file +{"project_name":"casaos-user-service","tag":"v1.0.0","previous_tag":"","version":"1.0.1","commit":"7c56d5865c9829a6af7fbd6c16a87b3266e9098a","date":"2024-09-30T12:02:33.51552871+07:00","runtime":{"goos":"linux","goarch":"amd64"}} \ No newline at end of file diff --git a/route/v1.go b/route/v1.go index 3fea428..61dd606 100644 --- a/route/v1.go +++ b/route/v1.go @@ -41,6 +41,8 @@ func InitRouter() *gin.Engine { r.POST("/v1/users/oidc/validateToken", v1.OIDCValidateToken) r.POST("/v1/users/oidc/logout", v1.OIDCLogout) r.GET("/v1/users/oidc/health", v1.OIDCHealthCheck) + r.GET("/v1/users/oidc/settings", v1.GetOIDCSettings) + r.POST("/v1/users/oidc/saveSettings", v1.SaveOIDCSettings) v1Group := r.Group("/v1") v1Group.Use(jwt.JWT( diff --git a/route/v1/user.go b/route/v1/user.go index 8f605f2..63f01c4 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -51,10 +51,20 @@ var ( clientSecret = "PE05fcDP4qESUmyZ1TNYpZNBxRPq70VpFI81vehsoJ6WhGz5yPXMljrFrOdMRdRhrYmF03fHWTZHgO9ZdNENrLN13BzL8CAgtEkTsyjXfgx9GvISheIjYfpSfvo219fL" authURL = "http://accessmanager.local/application/o/nextzenos-oidc/" //authURL = "http://10.0.0.26:9000/application/o/nextzenos-oidc/" - //callbackURL = "http://nextzenos.local/v1/users/oidc/callback" - callbackURL = "http://172.20.60.244:8080/v1/users/oidc/callback" + callbackURL = "http://nextzenos.local/v1/users/oidc/callback" + //callbackURL = "http://172.20.60.244:8080/v1/users/oidc/callback" ) +type OIDCSetting struct { + Settings struct { + ClientID string `json:"clientId"` + ClientSecret string `json:"clientSecret"` + Issuer string `json:"issuer"` + AuthURL string `json:"authUrl"` + CallbackURL string `json:"callbackUrl"` + } `json:"settings"` +} + // @Summary register user // @Router /user/register/ [post] func PostUserRegister(c *gin.Context) { @@ -246,7 +256,7 @@ func CheckOIDCInit() gin.HandlerFunc { return func(c *gin.Context) { if !oidcInit { log.Println("Provider is Offline") - c.JSON(http.StatusServiceUnavailable, model.Result{Success: http.StatusProxyAuthRequired, Message: "Authentik Server is Offline"}) + c.JSON(http.StatusServiceUnavailable, model.Result{Success: common_err.OIDC_OFFLINE, Message: "Authentik Server is Offline"}) return } c.Next() @@ -255,6 +265,14 @@ func CheckOIDCInit() gin.HandlerFunc { // Use an init function to initialize the oauth2Config variable. func OIDC() error { + authentik, err := service.MyService.Authentik().GetSettings() + if (authentik != model2.AuthentikCredentialsDBModel{} && err == nil) { + clientID = authentik.ClientID + clientSecret = authentik.ClientSecret + authServer = authentik.Issuer + authURL = authentik.AuthUrl + callbackURL = authentik.CallbackUrl + } ctx := context.Background() provider, err := oidc.NewProvider(ctx, authURL) if err != nil { @@ -270,6 +288,24 @@ func OIDC() error { } return nil } +func GetOIDCSettings(c *gin.Context) { + authentik, err := service.MyService.Authentik().GetSettings() + if err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{ + Success: common_err.SERVICE_ERROR, + Message: common_err.GetMsg(common_err.SERVICE_ERROR), + }) + return + } + c.JSON(common_err.SUCCESS, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: authentik, + }) + return +} func OIDCLogin(c *gin.Context) { json := make(map[string]string) c.ShouldBind(&json) @@ -285,6 +321,30 @@ func OIDCLogin(c *gin.Context) { Data: oauth2Config.AuthCodeURL(state), }) } +func SaveOIDCSettings(c *gin.Context) { + var oidcSetting OIDCSetting + var authentik model2.AuthentikCredentialsDBModel + c.ShouldBind(&oidcSetting) + authentik.ClientID = oidcSetting.Settings.ClientID + authentik.ClientSecret = oidcSetting.Settings.ClientSecret + authentik.Issuer = oidcSetting.Settings.Issuer + authentik.AuthUrl = oidcSetting.Settings.AuthURL + authentik.CallbackUrl = oidcSetting.Settings.CallbackURL + var result, err = service.MyService.Authentik().UpdateSettings(authentik) + if err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{ + Success: common_err.SERVICE_ERROR, + Message: common_err.GetMsg(common_err.SERVICE_ERROR), + }) + } + c.JSON(common_err.SUCCESS, + model.Result{ + Success: common_err.SUCCESS, + Message: common_err.GetMsg(common_err.SUCCESS), + Data: result, + }) +} func OIDCCallback(c *gin.Context) { w := c.Writer r := c.Request diff --git a/service/authentik.go b/service/authentik.go index d338f77..8912b45 100644 --- a/service/authentik.go +++ b/service/authentik.go @@ -16,9 +16,9 @@ import ( type AuthentikService interface { GetUserInfo(accessToken string, baseURL string) (model2.AuthentikUser, error) GetUserApp(accessToken string, baseURL string) (model2.AuthentikApplication, error) - CreateCredential(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel - UpdateCredential(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel - GetCredential(id int) model2.AuthentikCredentialsDBModel + CreateSettings(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel + UpdateSettings(m model2.AuthentikCredentialsDBModel) (model2.AuthentikCredentialsDBModel, error) + GetSettings() (model2.AuthentikCredentialsDBModel, error) ValidateToken(clientId string, clientSecret string, accessToken string, baseURL string) (model2.AuthentikToken, error) HealthCheck(baseURL string) (string, error) } @@ -31,18 +31,40 @@ var ( APICorePrefix = "/api/v3/core" ) -func (a *authentikService) CreateCredential(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel { +func (a *authentikService) CreateSettings(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel { a.db.Create(&m) return m } -func (a *authentikService) UpdateCredential(m model2.AuthentikCredentialsDBModel) model2.AuthentikCredentialsDBModel { - a.db.Model(&m).Where("id = ?", m.Id).Updates(m) - return m +func (a *authentikService) UpdateSettings(m model2.AuthentikCredentialsDBModel) (model2.AuthentikCredentialsDBModel, error) { + // Find the first matching record + var existing model2.AuthentikCredentialsDBModel + result := a.db.First(&existing) + if result.Error != nil { + return existing, result.Error + } + + // Update the existing record + existing.ClientID = m.ClientID + existing.ClientSecret = m.ClientSecret + existing.Issuer = m.Issuer + existing.AuthUrl = m.AuthUrl + existing.CallbackUrl = m.CallbackUrl + + // Save the updated record + result = a.db.Save(&existing) + if result.Error != nil { + return existing, result.Error + } + + return existing, nil } -func (a *authentikService) GetCredential(id int) model2.AuthentikCredentialsDBModel { +func (a *authentikService) GetSettings() (model2.AuthentikCredentialsDBModel, error) { var m model2.AuthentikCredentialsDBModel - a.db.Limit(1).Where("id = ?", id).First(&m) - return m + result := a.db.First(&m) + if result.Error != nil { + return model2.AuthentikCredentialsDBModel{}, result.Error + } + return m, nil } func (a *authentikService) HealthCheck(baseURL string) (string, error) { // Check health/live first diff --git a/service/model/o_authentik_credetials.go b/service/model/o_authentik_credetials.go index 4f6416f..247ca50 100644 --- a/service/model/o_authentik_credetials.go +++ b/service/model/o_authentik_credetials.go @@ -7,7 +7,9 @@ type AuthentikCredentialsDBModel struct { Id int `gorm:"column:id;primary_key" json:"id"` ClientID string `json:"clientId"` ClientSecret string `json:"clientSecret"` - Server string `json:"server"` + Issuer string `json:"issuer"` + AuthUrl string `json:"authUrl"` + CallbackUrl string `json:"callbackUrl"` CreatedAt time.Time `gorm:"<-:create;autoCreateTime" json:"created_at,omitempty"` UpdatedAt time.Time `gorm:"<-:create;<-:update;autoUpdateTime" json:"updated_at,omitempty"` }