feat: assign users to teams via OIDC claims #1393
|
@ -203,23 +203,24 @@ func HandleCallback(c echo.Context) error {
|
|||
|
||||
viehlieb marked this conversation as resolved
Outdated
|
||||
// does the oidc token contain well formed "vikunja_groups" through vikunja_scope
|
||||
teamData, errs := getTeamDataFromToken(cl.VikunjaGroups, provider)
|
||||
for _, err := range errs {
|
||||
log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err)
|
||||
}
|
||||
if teamData != nil {
|
||||
for _, err := range errs {
|
||||
log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err)
|
||||
}
|
||||
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Typo: Please check the other log messages as well for typos, I've seen a few more like this. Typo: `team` and `oidc` should be lowercase.
Please check the other log messages as well for typos, I've seen a few more like this.
|
||||
//find old teams for user through oidc
|
||||
oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID)
|
||||
if err != nil {
|
||||
log.Errorf("No Oidc Teams found for user %v", err)
|
||||
}
|
||||
oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData)
|
||||
if err != nil {
|
||||
log.Errorf("Could not proceed with group routine %v", err)
|
||||
}
|
||||
errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams))
|
||||
log.Errorf("%v", errs)
|
||||
for _, err := range errs {
|
||||
log.Errorf("Found Error while signing out from teams %v", err)
|
||||
//find old teams for user through oidc
|
||||
oldOidcTeams, err := models.FindAllOidcTeamIDsForUser(s, u.ID)
|
||||
if err != nil {
|
||||
log.Errorf("No Oidc Teams found for user %v", err)
|
||||
}
|
||||
oidcTeams, err := AssignOrCreateUserToTeams(s, u, teamData)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please don't ignore the error. Please don't ignore the error.
|
||||
if err != nil {
|
||||
log.Errorf("Could not proceed with group routine %v", err)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please don't call this "Sign out". That's a different thing. Please don't call this "Sign out". That's a different thing.
|
||||
}
|
||||
errs = RemoveUserFromTeamsByIds(s, u, utils.NotIn(oldOidcTeams, oidcTeams))
|
||||
for _, err := range errs {
|
||||
log.Errorf("Found Error while signing out from teams %v", err)
|
||||
}
|
||||
}
|
||||
konrad marked this conversation as resolved
Outdated
konrad
commented
Doing this every time a user logs in probably has performance implications but that's a problem to care about when we'll hit it in the wild. Doing this every time a user logs in probably has performance implications but that's a problem to care about when we'll hit it in the wild.
viehlieb
commented
only if it has teamIDsToLeave, but yeah I agree. The problem is more the oidc structure itself, that you "have" to check for changes "everytime" you sign in.. only if it has teamIDsToLeave, but yeah I agree.
The problem is more the oidc structure itself, that you "have" to check for changes "everytime" you sign in..
|
||||
err = s.Commit()
|
||||
if err != nil {
|
||||
|
@ -254,8 +255,10 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.
|
|||
for _, err := range errs {
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please call this something like Please call this something like `RemoveUserFromTeamsByID` so that it is clear how destructive this is.
|
||||
log.Errorf("Found Error while signing out from teams %v", err)
|
||||
}
|
||||
oidcTeams = append(oidcTeams, team.ID)
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
why not do this in one sql query? why not do this in one sql query?
viehlieb
commented
You mean something like:
You mean something like:
```
func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (err error) {
if len(teamIDs) < 1 {
return nil
}
strSlice := make([]string, len(teamIDs))
for i, num := range teamIDs {
strSlice[i] = strconv.FormatInt(num, 10)
}
sql := fmt.Sprintf(`DELETE FROM team_members WHERE user_id = %d AND team_id IN (%v)`, u.ID, strings.Join(strSlice, ","))
_, err = s.Exec(sql)
return err
```
konrad
commented
Yes, but with xorm:
Yes, but with xorm:
```
_, err = s.Where(builder.And(builder.Where("user_id = ?", u.ID), builder.In("team_id", teamIDs)).Delete(&TeamMember{})
return err
```
viehlieb
commented
went for:
went for:
`_, err = s.Where("team_id IN (?) AND user_id = ?", strings.Join(strSlice, ","), u.ID).Delete(&models.TeamMember{})`
konrad
commented
That's still working agains the orm - makes things more complicated in the end. Please use xorm's Something like this might work as well:
That's still working agains the orm - makes things more complicated in the end.
Please use xorm's `In` function instead.
Something like this might work as well:
```go
_, err = s.And("user_id = ?", u.ID).In("team_id", teamIDs).Delete(&TeamMember{})
return err
```
|
||||
}
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please return the error instead of logging only. Please return the error instead of logging only.
konrad
commented
Please don't ignore the errors. Please don't ignore the errors.
viehlieb
commented
not ignored now not ignored now
|
||||
return oidcTeams, err
|
||||
<<<<<<< HEAD
|
||||
|
||||
func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.OIDCTeamData) (oidcTeams []int64, err error) {
|
||||
if len(teamData) == 0 {
|
||||
|
@ -285,6 +288,10 @@ func AssignOrCreateUserToTeams(s *xorm.Session, u *user.User, teamData []models.
|
|||
|
||||
viehlieb marked this conversation as resolved
Outdated
konrad
commented
Please use `strconv.FormatInt Please use `strconv.FormatInt
viehlieb
commented
done done
|
||||
=======
|
||||
>>>>>>> 169b668c... remove left over function GetMemberCount, rename function SignOut to RemoveFrom
|
||||
=======
|
||||
}
|
||||
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.
|
||||
|
||||
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)
|
||||
>>>>>>> 3fdbd53b... work on openid to just start group workflow when teamData is available
|
||||
func RemoveUserFromTeamsByIds(s *xorm.Session, u *user.User, teamIDs []int64) (errs []error) {
|
||||
errs = []error{}
|
||||
for _, teamID := range teamIDs {
|
||||
|
|
I feel like the next 20 lines need better error handling - is it intended to not return when an error happens?
The rationale was to ensure users can still log in, even though the scope is malformed.
Therefore the Errors are logged instead of returning.
Also: It might be some groups with valid token details get through, some not.
We can also go for not signing in altogether.
If this works and won't create duplicate teams when users log in again in the future, I think it's fine to leave it like this.