add functionality to assign user to teams through oidc custom claim
This commit is contained in:
parent
d3fa4a04c0
commit
3ef25e7be5
|
@ -150,6 +150,7 @@ func HandleCallback(c echo.Context) error {
|
||||||
|
|
||||||
// Extract custom claims
|
// Extract custom claims
|
||||||
cl := &claims{}
|
cl := &claims{}
|
||||||
|
|
||||||
err = idToken.Claims(cl)
|
err = idToken.Claims(cl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error getting token claims for provider %s: %v", provider.Name, err)
|
log.Errorf("Error getting token claims for provider %s: %v", provider.Name, err)
|
||||||
|
@ -204,57 +205,117 @@ func HandleCallback(c echo.Context) error {
|
||||||
return handler.HandleHTTPError(err, c)
|
return handler.HandleHTTPError(err, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if we have seen these teams before
|
// does the oidc token contain well formed "vikunja_groups" through vikunja_scope
|
||||||
if len(cl.Teams) > 0 {
|
teamData, err := getTeamDataFromToken(cl.VikunjaGroups, provider)
|
||||||
teams, err := GetOrCreateTeamsByNames(s, cl.Teams, u)
|
if err != nil {
|
||||||
|
log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err)
|
||||||
|
return handler.HandleHTTPError(err, c)
|
||||||
|
}
|
||||||
|
// check if we have seen these teams before.
|
||||||
|
// find or create Teams and assign user as teammember.
|
||||||
|
if len(teamData) > 0 {
|
||||||
|
log.Debugf("TeamData is set %v", teamData)
|
||||||
|
teams, err := GetOrCreateTeamsByNames(s, teamData, u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err)
|
log.Errorf("Error verifying team for name %v, got %v", cl.Name, teams, err)
|
||||||
return err
|
return err
|
||||||
} else {
|
}
|
||||||
|
|
||||||
for _, team := range teams {
|
for _, team := range teams {
|
||||||
tm := models.TeamMember{TeamID: team.ID, Username: u.Username}
|
tm := models.TeamMember{TeamID: team.ID, Username: u.Username}
|
||||||
err := tm.CheckMembership(s)
|
exists, err := tm.CheckMembership(s)
|
||||||
if err == nil {
|
if !exists {
|
||||||
tm.Create(s, u)
|
err = tm.Create(s, u)
|
||||||
}
|
if err != nil {
|
||||||
|
log.Debugf("Could not assign %v to %v. %v", u.Username, team.Name, err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("Team exists? %v or error: %v", exists, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Commit()
|
err = s.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
_ = s.Rollback()
|
||||||
|
log.Errorf("Error creating new Team for provider %s: %v", provider.Name, err)
|
||||||
return handler.HandleHTTPError(err, c)
|
return handler.HandleHTTPError(err, c)
|
||||||
}
|
}
|
||||||
// Create token
|
// Create token
|
||||||
return auth.NewUserAuthTokenResponse(u, c, false)
|
return auth.NewUserAuthTokenResponse(u, c, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetOrCreateTeamsByNames(s *xorm.Session, teamNames []string, u *user.User) (te []models.Team, err error) {
|
func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) {
|
||||||
te = []models.Team{}
|
teamData = []TeamData{}
|
||||||
for _, t := range teamNames {
|
if groups != nil {
|
||||||
team, err := models.GetTeamsByName(s, t)
|
el := groups.([]interface{})
|
||||||
|
for _, data := range el {
|
||||||
|
team := data.(map[string]interface{})
|
||||||
|
log.Debugf("%s", team)
|
||||||
|
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 = fmt.Sprintf("%v", team["oidcID"])
|
||||||
|
case string:
|
||||||
|
oidcID = string(team["oidcID"].(string))
|
||||||
|
case float64:
|
||||||
|
fl := float64(team["oidcID"].(float64))
|
||||||
|
oidcID = fmt.Sprintf("%v", fl)
|
||||||
|
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)
|
||||||
|
return teamData, &user.ErrOpenIDCustomScopeMalformed{}
|
||||||
|
}
|
||||||
|
teamData = append(teamData, TeamData{TeamName: name, OidcID: oidcID, Description: description})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return teamData, nil
|
||||||
|
}
|
||||||
|
|
||||||
// if team does not exists, create it
|
func CreateTeamWithData(s *xorm.Session, teamData TeamData, u *user.User) (team *models.Team, err error) {
|
||||||
if models.IsErrTeamsDoNotExist(err) {
|
|
||||||
log.Debugf("No such Team: %v, create %v ..", t, team)
|
|
||||||
tea := &models.Team{
|
tea := &models.Team{
|
||||||
Name: t,
|
Name: teamData.TeamName,
|
||||||
|
Description: teamData.Description,
|
||||||
|
OidcID: teamData.OidcID,
|
||||||
}
|
}
|
||||||
err := tea.Create(s, u)
|
log.Debugf("Teams: %v", tea.OidcID)
|
||||||
|
|
||||||
|
err = tea.Create(s, u)
|
||||||
|
return tea, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// this functions creates an array of existing teams that was generated from the oidc data.
|
||||||
|
func GetOrCreateTeamsByNames(s *xorm.Session, teamData []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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Teams: %v, err: %v", tea, err)
|
log.Debugf("Team with oidc_id %v and name %v does not exist. Create Team.. ", oidcTeam.OidcID, oidcTeam.TeamName)
|
||||||
|
newTeam, err := CreateTeamWithData(s, oidcTeam, u)
|
||||||
|
if err != nil {
|
||||||
|
return te, err
|
||||||
|
}
|
||||||
|
te = append(te, *newTeam)
|
||||||
} else {
|
} else {
|
||||||
te = append(te, *tea)
|
log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name)
|
||||||
}
|
te = append(te, team)
|
||||||
} else {
|
|
||||||
// if multiple teams with same name are found,
|
|
||||||
if len(team) == 1 {
|
|
||||||
// append team to return value
|
|
||||||
te = append(te, *team[len(team)-1])
|
|
||||||
} else {
|
|
||||||
log.Debugf("Multiple Teams have the same name: %v, ignore assignment of %v", team[len(team)-1].Name, u.Name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
log.Debugf("Array: %v", te)
|
||||||
return te, err
|
return te, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user