feat: assign users to teams via OIDC claims #1393
|
@ -60,11 +60,11 @@ type Provider struct {
|
|||
Oauth2Config *oauth2.Config `json:"-"`
|
||||
}
|
||||
type claims struct {
|
||||
viehlieb marked this conversation as resolved
Outdated
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferred_username"`
|
||||
Nickname string `json:"nickname"`
|
||||
VikunjaGroups interface{} `json:"vikunja_groups"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
PreferredUsername string `json:"preferred_username"`
|
||||
Nickname string `json:"nickname"`
|
||||
VikunjaGroups []map[string]interface{} `json:"vikunja_groups"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -277,41 +277,37 @@ func SignOutFromTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) (errs
|
|||
return errs
|
||||
}
|
||||
|
||||
func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []models.TeamData, errs []error) {
|
||||
func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []models.TeamData, errs []error) {
|
||||
teamData = []models.TeamData{}
|
||||
errs = []error{}
|
||||
if groups != nil {
|
||||
el := groups.([]interface{})
|
||||
for _, data := range el {
|
||||
team := data.(map[string]interface{})
|
||||
var name string
|
||||
var description string
|
||||
var oidcID string
|
||||
if team["name"] != nil {
|
||||
name = team["name"].(string)
|
||||
}
|
||||
if team["description"] != nil {
|
||||
description = team["description"].(string)
|
||||
}
|
||||
if team["oidcID"] != nil {
|
||||
switch t := team["oidcID"].(type) {
|
||||
case int64:
|
||||
oidcID = strconv.FormatInt(team["oidcID"].(int64), 10)
|
||||
case string:
|
||||
oidcID = string(team["oidcID"].(string))
|
||||
case float64:
|
||||
oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64)
|
||||
default:
|
||||
log.Errorf("No oidcID assigned for %v or type %v not supported", team, t)
|
||||
}
|
||||
}
|
||||
if name == "" || oidcID == "" {
|
||||
log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name)
|
||||
errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{})
|
||||
continue
|
||||
}
|
||||
teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description})
|
||||
for _, team := range groups {
|
||||
var name string
|
||||
var description string
|
||||
var oidcID string
|
||||
if team["name"] != nil {
|
||||
name = team["name"].(string)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please use `strconv.FormatInt Please use `strconv.FormatInt
viehlieb
commented
done done
|
||||
}
|
||||
if team["description"] != nil {
|
||||
description = team["description"].(string)
|
||||
}
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please use xorm's Please use xorm's `In` function because that allows you to pass an int slice directly and avoids the need for the conversion you're doing.
|
||||
if team["oidcID"] != nil {
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please use Please use `strconv.FormatFloat` (not 100% sure if the function is really called that)
|
||||
switch t := team["oidcID"].(type) {
|
||||
case int64:
|
||||
oidcID = strconv.FormatInt(team["oidcID"].(int64), 10)
|
||||
case string:
|
||||
oidcID = string(team["oidcID"].(string))
|
||||
case float64:
|
||||
oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
The return here will mean if one team claim is invalid, it will not try to validate any others. Is that what you intended? The return here will mean if one team claim is invalid, it will not try to validate any others. Is that what you intended?
viehlieb
commented
changed behaviour to skipping the invalid team changed behaviour to skipping the invalid team
|
||||
default:
|
||||
log.Errorf("No oidcID assigned for %v or type %v not supported", team, t)
|
||||
}
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please use Please use `_, exists := team["name"]` to check if the field exists (`exists` is a boolean indicating whether the field exists). Same for the other fields.
|
||||
}
|
||||
if name == "" || oidcID == "" {
|
||||
log.Errorf("Claim of your custom scope does not hold name or oidcID for automatic group assignment through oidc provider. Please check %s", provider.Name)
|
||||
errs = append(errs, &user.ErrOpenIDCustomScopeMalformed{})
|
||||
continue
|
||||
}
|
||||
teamData = append(teamData, models.TeamData{TeamName: name, OidcID: oidcID, Description: description})
|
||||
}
|
||||
return teamData, errs
|
||||
}
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please rename this to Please rename this to `team`.
konrad
commented
What's the advantage of this method over What's the advantage of this method over `team.Create`?
viehlieb
commented
i think it was cyclomatic complexity. i think it was cyclomatic complexity.
|
||||
|
@ -327,8 +323,8 @@ func CreateTeamWithData(s *xorm.Session, teamData models.TeamData, u *user.User)
|
|||
}
|
||||
|
||||
// this functions creates an array of existing teams that was generated from the oidc data.
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Which oidcID? In the Which oidcID? In the `teamData`? Isn't that always a string, due to the type system? Then the comment is redundant, please remove or clarify further.
|
||||
func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []models.Team, err error) {
|
||||
te = []models.Team{}
|
||||
func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData, u *user.User) (te []*models.Team, err error) {
|
||||
te = []*models.Team{}
|
||||
// Procedure can only be successful if oidcID is set and converted to string
|
||||
for _, oidcTeam := range teamData {
|
||||
team, err := models.GetTeamByOidcIDAndName(s, oidcTeam.OidcID, oidcTeam.TeamName)
|
||||
|
@ -338,12 +334,11 @@ func GetOrCreateTeamsByOIDCAndNames(s *xorm.Session, teamData []models.TeamData,
|
|||
if err != nil {
|
||||
return te, err
|
||||
}
|
||||
te = append(te, *newTeam)
|
||||
te = append(te, newTeam)
|
||||
} else {
|
||||
log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please make this debug message more descriptive or remove it alltogether. Please make this debug message more descriptive or remove it alltogether.
|
||||
te = append(te, team)
|
||||
te = append(te, &team)
|
||||
}
|
||||
|
||||
}
|
||||
return te, err
|
||||
}
|
||||
|
|
Didn't you declare this already somewhere else?