mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-27 16:17:34 +00:00
[Backport release-1.5] Fix: support to test authentication with dex (#4440)
* Fix: support to test login with dex Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit8d0d20fd60) * Fix: support to update the user when the login mode is dex Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit442d4601e9) * Fix: systemInfoService is nil Signed-off-by: barnettZQG <barnett.zqg@gmail.com> (cherry picked from commit392637e69d) Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
This commit is contained in:
co-authored by
barnettZQG
parent
ca2a90a097
commit
853f44cf61
@@ -57,6 +57,8 @@ type DexConfig struct {
|
||||
Issuer string `json:"issuer"`
|
||||
Web DexWeb `json:"web"`
|
||||
Storage DexStorage `json:"storage"`
|
||||
Telemetry Telemetry `json:"telemetry"`
|
||||
Frontend WebConfig `json:"frontend"`
|
||||
StaticClients []DexStaticClient `json:"staticClients"`
|
||||
Connectors []map[string]interface{} `json:"connectors,omitempty"`
|
||||
EnablePasswordDB bool `json:"enablePasswordDB"`
|
||||
@@ -95,6 +97,26 @@ type DexStorageConfig struct {
|
||||
|
||||
// DexWeb dex web
|
||||
type DexWeb struct {
|
||||
HTTP string `json:"http"`
|
||||
HTTPS string `json:"https"`
|
||||
TLSCert string `json:"tlsCert"`
|
||||
TLSKey string `json:"tlsKey"`
|
||||
AllowedOrigins []string `json:"allowedOrigins"`
|
||||
}
|
||||
|
||||
// WebConfig holds the server's frontend templates and asset configuration.
|
||||
type WebConfig struct {
|
||||
LogoURL string
|
||||
|
||||
// Defaults to "dex"
|
||||
Issuer string
|
||||
|
||||
// Defaults to "light"
|
||||
Theme string
|
||||
}
|
||||
|
||||
// Telemetry is the config format for telemetry including the HTTP server config.
|
||||
type Telemetry struct {
|
||||
HTTP string `json:"http"`
|
||||
}
|
||||
|
||||
|
||||
@@ -129,9 +129,10 @@ func (a *authenticationServiceImpl) newDexHandler(ctx context.Context, req apisv
|
||||
return nil, err
|
||||
}
|
||||
return &dexHandlerImpl{
|
||||
idToken: idToken,
|
||||
Store: a.Store,
|
||||
projectService: a.ProjectService,
|
||||
idToken: idToken,
|
||||
Store: a.Store,
|
||||
projectService: a.ProjectService,
|
||||
systemInfoService: a.SystemInfoService,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -156,13 +157,13 @@ func (a *authenticationServiceImpl) Login(ctx context.Context, loginReq apisv1.L
|
||||
}
|
||||
loginType := sysInfo.LoginType
|
||||
|
||||
switch loginType {
|
||||
case model.LoginTypeDex:
|
||||
switch {
|
||||
case loginType == model.LoginTypeDex || (loginReq.Code != "" && loginReq.Username == ""):
|
||||
handler, err = a.newDexHandler(ctx, loginReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case model.LoginTypeLocal:
|
||||
case loginType == model.LoginTypeLocal:
|
||||
handler, err = a.newLocalHandler(loginReq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -288,6 +289,11 @@ func generateDexConfig(ctx context.Context, kubeClient client.Client, update *mo
|
||||
if len(update.StaticPasswords) > 0 {
|
||||
dexConfig.StaticPasswords = update.StaticPasswords
|
||||
}
|
||||
// This is the title that the dex login page.
|
||||
// It will be: Log in to KubeVela
|
||||
if dexConfig.Frontend.Issuer == "" {
|
||||
dexConfig.Frontend.Issuer = "KubeVela"
|
||||
}
|
||||
config, err := model.NewJSONStructByStruct(dexConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -323,7 +329,7 @@ func initDexConfig(ctx context.Context, kubeClient client.Client, velaAddress st
|
||||
StaticClients: []model.DexStaticClient{
|
||||
{
|
||||
ID: "velaux",
|
||||
Name: "Vela UX",
|
||||
Name: "VelaUX",
|
||||
Secret: "velaux-secret",
|
||||
RedirectURIs: []string{fmt.Sprintf("%s/callback", velaAddress)},
|
||||
},
|
||||
@@ -403,9 +409,13 @@ func getDexConfig(ctx context.Context, kubeClient client.Client) (*model.DexConf
|
||||
Namespace: velatypes.DefaultKubeVelaNS,
|
||||
}, dexConfigSecret); err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
return nil, bcode.ErrDexConfigNotFound
|
||||
dexConfigSecret, err = initDexConfig(ctx, kubeClient, "http://velaux.com")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
return nil, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if dexConfigSecret.Data == nil {
|
||||
return nil, bcode.ErrInvalidDexConfig
|
||||
@@ -468,6 +478,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
|
||||
if len(users) > 0 {
|
||||
u := users[0].(*model.User)
|
||||
u.LastLoginTime = time.Now()
|
||||
u.DexSub = claims.Sub
|
||||
if err := d.Store.Put(ctx, u); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -481,6 +492,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
|
||||
LastLoginTime: time.Now(),
|
||||
}
|
||||
if err := d.Store.Add(ctx, user); err != nil {
|
||||
log.Logger.Errorf("failed to save the user from the dex: %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
systemInfo, err := d.systemInfoService.GetSystemInfo(ctx)
|
||||
|
||||
@@ -19,6 +19,7 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strconv"
|
||||
@@ -64,8 +65,9 @@ var _ = Describe("Test authentication service functions", func() {
|
||||
})
|
||||
It("Test Dex login", func() {
|
||||
testIDToken := &oidc.IDToken{}
|
||||
sub := "248289761001"
|
||||
patch := ApplyMethod(reflect.TypeOf(testIDToken), "Claims", func(_ *oidc.IDToken, v interface{}) error {
|
||||
return json.Unmarshal([]byte(`{"email":"test@test.com", "name":"show name", "sub": "testuser"}`), v)
|
||||
return json.Unmarshal([]byte(fmt.Sprintf(`{"email":"test@test.com", "name":"show name", "sub": "%s"}`, sub)), v)
|
||||
})
|
||||
defer patch.Reset()
|
||||
|
||||
@@ -94,22 +96,22 @@ var _ = Describe("Test authentication service functions", func() {
|
||||
resp, err := dexHandler.login(context.Background())
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(resp.Email).Should(Equal("test@test.com"))
|
||||
Expect(resp.Name).Should(Equal("testuser"))
|
||||
Expect(resp.Name).Should(Equal(sub))
|
||||
Expect(resp.Alias).Should(Equal("show name"))
|
||||
|
||||
projects, err := projectService.ListUserProjects(context.TODO(), "testuser")
|
||||
projects, err := projectService.ListUserProjects(context.TODO(), sub)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(projects)).Should(Equal(1))
|
||||
|
||||
user := &model.User{
|
||||
Name: "testuser",
|
||||
Name: sub,
|
||||
}
|
||||
err = ds.Get(context.Background(), user)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(user.Email).Should(Equal("test@test.com"))
|
||||
|
||||
existUser := &model.User{
|
||||
Name: "testuser",
|
||||
Name: sub,
|
||||
}
|
||||
err = ds.Delete(context.Background(), existUser)
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -131,7 +133,7 @@ var _ = Describe("Test authentication service functions", func() {
|
||||
existUser = &model.User{
|
||||
Name: "zhangsan",
|
||||
Email: "test2@test.com",
|
||||
DexSub: "testuser",
|
||||
DexSub: sub,
|
||||
}
|
||||
err = ds.Add(context.Background(), existUser)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -192,18 +192,17 @@ func (u *userServiceImpl) UpdateUser(ctx context.Context, user *model.User, req
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if sysInfo.LoginType == model.LoginTypeDex {
|
||||
return nil, bcode.ErrUserCannotModified
|
||||
}
|
||||
if req.Alias != "" {
|
||||
user.Alias = req.Alias
|
||||
}
|
||||
if req.Password != "" {
|
||||
hash, err := GeneratePasswordHash(req.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if sysInfo.LoginType != model.LoginTypeDex {
|
||||
if req.Password != "" {
|
||||
hash, err := GeneratePasswordHash(req.Password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
user.Password = hash
|
||||
}
|
||||
user.Password = hash
|
||||
}
|
||||
if req.Email != "" {
|
||||
if user.Email != "" {
|
||||
@@ -211,6 +210,7 @@ func (u *userServiceImpl) UpdateUser(ctx context.Context, user *model.User, req
|
||||
}
|
||||
user.Email = req.Email
|
||||
}
|
||||
|
||||
// TODO: validate the roles, they must be platform roles
|
||||
if req.Roles != nil {
|
||||
user.UserRoles = *req.Roles
|
||||
|
||||
@@ -82,8 +82,13 @@ func (v *velaQLServiceImpl) QueryView(ctx context.Context, velaQL string) (*apis
|
||||
return nil, bcode.ErrParseQuery2Json
|
||||
}
|
||||
if strings.Contains(velaQL, "collect-logs") {
|
||||
enc, _ := base64.StdEncoding.DecodeString(resp["logs"].(string))
|
||||
resp["logs"] = string(enc)
|
||||
logs, ok := resp["logs"].(string)
|
||||
if ok {
|
||||
enc, _ := base64.StdEncoding.DecodeString(logs)
|
||||
resp["logs"] = string(enc)
|
||||
} else {
|
||||
resp["logs"] = ""
|
||||
}
|
||||
}
|
||||
return &resp, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user