Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 33 additions & 5 deletions internal/controller/oauth_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,14 +224,15 @@ func (controller *OAuthController) oauthCallbackHandler(c *gin.Context) {
Username: user.PreferredUsername,
Email: user.Email,
Name: user.Name,
Groups: utils.CoalesceToString(user.Groups),
})

sessionCookie := repository.Session{
Username: oauthUserInfo.Username,
Name: oauthUserInfo.Name,
Email: oauthUserInfo.Email,
Provider: svc.ID(),
OAuthGroups: utils.CoalesceToString(user.Groups),
OAuthGroups: oauthUserInfo.Groups,
OAuthName: svc.Name(),
OAuthSub: user.Sub,
}
Expand Down Expand Up @@ -341,15 +342,20 @@ type oauthUserInfo struct {
Email string
Username string
Name string
Groups string
}

func (controller *OAuthController) createOAuthUserInfo(input oauthUserInfo) oauthUserInfo {
info := oauthUserInfo{
Email: input.Email,
}

userAttribs := controller.getUserAttributes(input.Email)

if controller.config.Experimental.OAuthBridgeEnabled {
if input.Username != "" {
if userAttribs.PreferredUsername != "" {
info.Username = userAttribs.PreferredUsername
} else if input.Username != "" {
info.Username = input.Username
} else {
parts := strings.SplitN(input.Email, "@", 2)
Expand All @@ -360,7 +366,9 @@ func (controller *OAuthController) createOAuthUserInfo(input oauthUserInfo) oaut
}
}

if input.Name != "" {
if userAttribs.Name != "" {
info.Name = userAttribs.Name
} else if input.Name != "" {
info.Name = input.Name
} else {
info.Name = utils.Capitalize(info.Username)
Expand All @@ -369,7 +377,9 @@ func (controller *OAuthController) createOAuthUserInfo(input oauthUserInfo) oaut
return info
}

if input.Name != "" {
if userAttribs.Name != "" {
info.Name = userAttribs.Name
} else if input.Name != "" {
controller.log.App.Debug().Msg("Using name from OAuth provider")
info.Name = input.Name
} else {
Expand All @@ -382,13 +392,31 @@ func (controller *OAuthController) createOAuthUserInfo(input oauthUserInfo) oaut
}
}

if input.Username != "" {
if userAttribs.PreferredUsername != "" {
controller.log.App.Debug().Msg("Using preferred username from Auth user attributes")
info.Username = userAttribs.PreferredUsername
} else if input.Username != "" {
controller.log.App.Debug().Msg("Using preferred username from OAuth provider")
info.Username = input.Username
} else {
controller.log.App.Debug().Msg("No preferred username from OAuth provider, generating from email")
info.Username = strings.Replace(info.Email, "@", "_", 1)
}

if userAttribs.Groups != nil {
info.Groups = strings.Join(userAttribs.Groups, ",")
controller.log.App.Debug().Msgf("Using groups from Auth user attributes: %s", userAttribs.Groups)
} else if input.Groups != "" {
controller.log.App.Debug().Msg("Using groups from OAuth provider")
info.Groups = input.Groups
}

return info
}

func (controller *OAuthController) getUserAttributes(email string) model.UserAttributes {
email = strings.ReplaceAll(email, "@", "-")
email = strings.ReplaceAll(email, ".", "-")
attribs := controller.config.Auth.UserAttributes[email]
return attribs
}
32 changes: 17 additions & 15 deletions internal/model/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,21 +156,23 @@ type AuthConfig struct {
}

type UserAttributes struct {
Name string `description:"Full name of the user." yaml:"name,omitempty"`
GivenName string `description:"Given (first) name of the user." yaml:"givenName,omitempty"`
FamilyName string `description:"Family (last) name of the user." yaml:"familyName,omitempty"`
MiddleName string `description:"Middle name of the user." yaml:"middleName,omitempty"`
Nickname string `description:"Nickname of the user." yaml:"nickname,omitempty"`
Profile string `description:"URL of the user's profile page." yaml:"profile,omitempty"`
Picture string `description:"URL of the user's profile picture." yaml:"picture,omitempty"`
Website string `description:"URL of the user's website." yaml:"website,omitempty"`
Email string `description:"Email address of the user." yaml:"email,omitempty"`
Gender string `description:"Gender of the user." yaml:"gender,omitempty"`
Birthdate string `description:"Birthdate of the user (YYYY-MM-DD)." yaml:"birthdate,omitempty"`
Zoneinfo string `description:"Time zone of the user (e.g. Europe/Athens)." yaml:"zoneinfo,omitempty"`
Locale string `description:"Locale of the user (e.g. en-US)." yaml:"locale,omitempty"`
PhoneNumber string `description:"Phone number of the user." yaml:"phoneNumber,omitempty"`
Address AddressClaim `description:"Address of the user." yaml:"address,omitempty"`
Name string `description:"Full name of the user." yaml:"name,omitempty"`
GivenName string `description:"Given (first) name of the user." yaml:"givenName,omitempty"`
FamilyName string `description:"Family (last) name of the user." yaml:"familyName,omitempty"`
MiddleName string `description:"Middle name of the user." yaml:"middleName,omitempty"`
Nickname string `description:"Nickname of the user." yaml:"nickname,omitempty"`
PreferredUsername string `description:"Preferred username of the user." yaml:"preferredUsername,omitempty"`
Groups []string `description:"List of groups the user belongs to." yaml:"groups,omitempty"`
Profile string `description:"URL of the user's profile page." yaml:"profile,omitempty"`
Picture string `description:"URL of the user's profile picture." yaml:"picture,omitempty"`
Website string `description:"URL of the user's website." yaml:"website,omitempty"`
Email string `description:"Email address of the user." yaml:"email,omitempty"`
Gender string `description:"Gender of the user." yaml:"gender,omitempty"`
Birthdate string `description:"Birthdate of the user (YYYY-MM-DD)." yaml:"birthdate,omitempty"`
Zoneinfo string `description:"Time zone of the user (e.g. Europe/Athens)." yaml:"zoneinfo,omitempty"`
Locale string `description:"Locale of the user (e.g. en-US)." yaml:"locale,omitempty"`
PhoneNumber string `description:"Phone number of the user." yaml:"phoneNumber,omitempty"`
Address AddressClaim `description:"Address of the user." yaml:"address,omitempty"`
}

type AddressClaim struct {
Expand Down
8 changes: 6 additions & 2 deletions internal/service/access_controls_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,12 @@ func (rule *OAuthGroupRule) Evaluate(ctx *ACLContext) Effect {
}

if _, ok := model.OverrideProviders[ctx.UserContext.OAuth.ID]; ok {
rule.Log.App.Debug().Str("provider", ctx.UserContext.OAuth.ID).Msg("Provider override detected, skipping group check")
return EffectAllow
if len(ctx.UserContext.OAuth.Groups) == 0 {
rule.Log.App.Debug().Str("provider", ctx.UserContext.OAuth.ID).Msg("Provider override detected, skipping group check")
return EffectAllow
}

rule.Log.App.Debug().Str("provider", ctx.UserContext.OAuth.ID).Msg("Provider override detected but user has groups, doing group check")
}

for _, group := range ctx.UserContext.OAuth.Groups {
Expand Down