fix: idp config definition (#1115)

fix: idp definition
This commit is contained in:
boojack 2023-02-18 18:31:03 +08:00 committed by GitHub
parent 19efacef9c
commit 852903bdbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 31 deletions

View file

@ -6,7 +6,9 @@ const (
IdentityProviderOAuth2 IdentityProviderType = "OAUTH2"
)
type IdentityProviderConfig interface{}
type IdentityProviderConfig struct {
OAuth2Config *IdentityProviderOAuth2Config `json:"oauth2Config"`
}
type IdentityProviderOAuth2Config struct {
ClientID string `json:"clientId"`

View file

@ -35,16 +35,16 @@ func (s *Server) registerIdentityProviderRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted post identity provider request").SetInternal(err)
}
identityProvider, err := s.Store.CreateIdentityProvider(ctx, &store.IdentityProviderMessage{
identityProviderMessage, err := s.Store.CreateIdentityProvider(ctx, &store.IdentityProviderMessage{
Name: identityProviderCreate.Name,
Type: store.IdentityProviderType(identityProviderCreate.Type),
IdentifierFilter: identityProviderCreate.IdentifierFilter,
Config: (*store.IdentityProviderConfig)(identityProviderCreate.Config),
Config: convertIdentityProviderConfigToStore(identityProviderCreate.Config),
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to create identity provider").SetInternal(err)
}
return c.JSON(http.StatusOK, composeResponse(identityProvider))
return c.JSON(http.StatusOK, composeResponse(convertIdentityProviderFromStore(identityProviderMessage)))
})
g.PATCH("/idp/:idpId", func(c echo.Context) error {
@ -76,17 +76,17 @@ func (s *Server) registerIdentityProviderRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusBadRequest, "Malformatted patch identity provider request").SetInternal(err)
}
identityProvider, err := s.Store.UpdateIdentityProvider(ctx, &store.UpdateIdentityProviderMessage{
identityProviderMessage, err := s.Store.UpdateIdentityProvider(ctx, &store.UpdateIdentityProviderMessage{
ID: identityProviderPatch.ID,
Type: store.IdentityProviderType(identityProviderPatch.Type),
Name: identityProviderPatch.Name,
IdentifierFilter: identityProviderPatch.IdentifierFilter,
Config: (*store.IdentityProviderConfig)(identityProviderPatch.Config),
Config: convertIdentityProviderConfigToStore(identityProviderPatch.Config),
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to patch identity provider").SetInternal(err)
}
return c.JSON(http.StatusOK, identityProvider)
return c.JSON(http.StatusOK, composeResponse(convertIdentityProviderFromStore(identityProviderMessage)))
})
g.GET("/idp", func(c echo.Context) error {
@ -112,13 +112,44 @@ func (s *Server) registerIdentityProviderRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find identity provider list").SetInternal(err)
}
var identityProviderList []*api.IdentityProvider
identityProviderList := []*api.IdentityProvider{}
for _, identityProviderMessage := range identityProviderMessageList {
identityProviderList = append(identityProviderList, convertIdentityProviderFromStore(identityProviderMessage))
}
return c.JSON(http.StatusOK, composeResponse(identityProviderList))
})
g.GET("/idp/:idpId", func(c echo.Context) error {
ctx := c.Request().Context()
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
}
user, err := s.Store.FindUser(ctx, &api.UserFind{
ID: &userID,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find user").SetInternal(err)
}
// We should only show identity provider list to host user.
if user == nil || user.Role != api.Host {
return echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized")
}
identityProviderID, err := strconv.Atoi(c.Param("idpId"))
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("ID is not a number: %s", c.Param("idpId"))).SetInternal(err)
}
identityProviderMessage, err := s.Store.GetIdentityProvider(ctx, &store.FindIdentityProviderMessage{
ID: &identityProviderID,
})
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to get identity provider").SetInternal(err)
}
return c.JSON(http.StatusOK, composeResponse(convertIdentityProviderFromStore(identityProviderMessage)))
})
g.DELETE("/idp/:idpId", func(c echo.Context) error {
ctx := c.Request().Context()
userID, ok := c.Get(getUserIDContextKey()).(int)
@ -152,27 +183,47 @@ func (s *Server) registerIdentityProviderRoutes(g *echo.Group) {
}
func convertIdentityProviderFromStore(identityProviderMessage *store.IdentityProviderMessage) *api.IdentityProvider {
identityProvider := &api.IdentityProvider{
return &api.IdentityProvider{
ID: identityProviderMessage.ID,
Name: identityProviderMessage.Name,
Type: api.IdentityProviderType(identityProviderMessage.Type),
IdentifierFilter: identityProviderMessage.IdentifierFilter,
Config: convertIdentityProviderConfigFromStore(identityProviderMessage.Config),
}
}
func convertIdentityProviderConfigFromStore(config *store.IdentityProviderConfig) *api.IdentityProviderConfig {
return &api.IdentityProviderConfig{
OAuth2Config: &api.IdentityProviderOAuth2Config{
ClientID: config.OAuth2Config.ClientID,
ClientSecret: config.OAuth2Config.ClientSecret,
AuthURL: config.OAuth2Config.AuthURL,
TokenURL: config.OAuth2Config.TokenURL,
UserInfoURL: config.OAuth2Config.UserInfoURL,
Scopes: config.OAuth2Config.Scopes,
FieldMapping: &api.FieldMapping{
Identifier: config.OAuth2Config.FieldMapping.Identifier,
DisplayName: config.OAuth2Config.FieldMapping.DisplayName,
Email: config.OAuth2Config.FieldMapping.Email,
},
},
}
}
func convertIdentityProviderConfigToStore(config *api.IdentityProviderConfig) *store.IdentityProviderConfig {
return &store.IdentityProviderConfig{
OAuth2Config: &store.IdentityProviderOAuth2Config{
ClientID: config.OAuth2Config.ClientID,
ClientSecret: config.OAuth2Config.ClientSecret,
AuthURL: config.OAuth2Config.AuthURL,
TokenURL: config.OAuth2Config.TokenURL,
UserInfoURL: config.OAuth2Config.UserInfoURL,
Scopes: config.OAuth2Config.Scopes,
FieldMapping: &store.FieldMapping{
Identifier: config.OAuth2Config.FieldMapping.Identifier,
DisplayName: config.OAuth2Config.FieldMapping.DisplayName,
Email: config.OAuth2Config.FieldMapping.Email,
},
},
}
if identityProvider.Type == api.IdentityProviderOAuth2 {
configMessage := any(identityProviderMessage.Config).(*store.IdentityProviderOAuth2Config)
identityProvider.Config = any(&api.IdentityProviderOAuth2Config{
ClientID: configMessage.ClientID,
ClientSecret: configMessage.ClientSecret,
AuthURL: configMessage.AuthURL,
TokenURL: configMessage.TokenURL,
UserInfoURL: configMessage.UserInfoURL,
Scopes: configMessage.Scopes,
FieldMapping: &api.FieldMapping{
Identifier: configMessage.FieldMapping.Identifier,
DisplayName: configMessage.FieldMapping.DisplayName,
Email: configMessage.FieldMapping.Email,
},
}).(*api.IdentityProviderConfig)
}
return identityProvider
}

View file

@ -16,7 +16,9 @@ const (
IdentityProviderOAuth2 IdentityProviderType = "OAUTH2"
)
type IdentityProviderConfig interface{}
type IdentityProviderConfig struct {
OAuth2Config *IdentityProviderOAuth2Config
}
type IdentityProviderOAuth2Config struct {
ClientID string `json:"clientId"`
@ -67,7 +69,7 @@ func (s *Store) CreateIdentityProvider(ctx context.Context, create *IdentityProv
var configBytes []byte
if create.Type == IdentityProviderOAuth2 {
configBytes, err = json.Marshal(any(create.Config).(*IdentityProviderOAuth2Config))
configBytes, err = json.Marshal(create.Config.OAuth2Config)
if err != nil {
return nil, err
}
@ -153,7 +155,7 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti
if v := update.Config; v != nil {
var configBytes []byte
if update.Type == IdentityProviderOAuth2 {
configBytes, err = json.Marshal(any(update.Config).(*IdentityProviderOAuth2Config))
configBytes, err = json.Marshal(update.Config.OAuth2Config)
if err != nil {
return nil, err
}
@ -182,9 +184,13 @@ func (s *Store) UpdateIdentityProvider(ctx context.Context, update *UpdateIdenti
return nil, FormatError(err)
}
if identityProviderMessage.Type == IdentityProviderOAuth2 {
if err := json.Unmarshal([]byte(identityProviderConfig), any(identityProviderMessage.Config).(*IdentityProviderOAuth2Config)); err != nil {
oauth2Config := &IdentityProviderOAuth2Config{}
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
return nil, err
}
identityProviderMessage.Config = &IdentityProviderConfig{
OAuth2Config: oauth2Config,
}
} else {
return nil, fmt.Errorf("unsupported idp type %s", string(identityProviderMessage.Type))
}
@ -252,9 +258,13 @@ func listIdentityProviders(ctx context.Context, tx *sql.Tx, find *FindIdentityPr
return nil, FormatError(err)
}
if identityProviderMessage.Type == IdentityProviderOAuth2 {
if err := json.Unmarshal([]byte(identityProviderConfig), any(identityProviderMessage.Config).(*IdentityProviderOAuth2Config)); err != nil {
oauth2Config := &IdentityProviderOAuth2Config{}
if err := json.Unmarshal([]byte(identityProviderConfig), oauth2Config); err != nil {
return nil, err
}
identityProviderMessage.Config = &IdentityProviderConfig{
OAuth2Config: oauth2Config,
}
} else {
return nil, fmt.Errorf("unsupported idp type %s", string(identityProviderMessage.Type))
}