add functionality for deleting user only from oidc teams which are not present in the current token
This commit is contained in:
parent
4dc2547e09
commit
625d847e9f
|
@ -1099,7 +1099,6 @@ func (err ErrTeamNameCannotBeEmpty) HTTPError() web.HTTPError {
|
||||||
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTeamNameCannotBeEmpty, Message: "The team name cannot be empty"}
|
return web.HTTPError{HTTPCode: http.StatusBadRequest, Code: ErrCodeTeamNameCannotBeEmpty, Message: "The team name cannot be empty"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrTeamDoesNotExist represents an error where a team does not exist
|
|
||||||
type ErrTeamDoesNotExist struct {
|
type ErrTeamDoesNotExist struct {
|
||||||
TeamID int64
|
TeamID int64
|
||||||
}
|
}
|
||||||
|
@ -1218,6 +1217,51 @@ func (err ErrTeamDoesNotHaveAccessToProject) HTTPError() web.HTTPError {
|
||||||
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."}
|
return web.HTTPError{HTTPCode: http.StatusForbidden, Code: ErrCodeTeamDoesNotHaveAccessToProject, Message: "This team does not have access to the project."}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ErrTeamsDoNotExist struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrTeamDoNotExist checks if an error is ErrTeamDoesNotExist.
|
||||||
|
func IsErrTeamsDoNotExist(err error) bool {
|
||||||
|
_, ok := err.(ErrTeamsDoNotExist)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrTeamsDoNotExist) Error() string {
|
||||||
|
return fmt.Sprintf("Team does not exist [Team Name: %v]", err.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCodeTeamDoesNotExist holds the unique world-error code of this error
|
||||||
|
const ErrCodeTeamsDoNotExist = 6008
|
||||||
|
|
||||||
|
// HTTPError holds the http error description
|
||||||
|
func (err ErrTeamsDoNotExist) HTTPError() web.HTTPError {
|
||||||
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "No team with given name exists."}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrOIDCTeamsDoNotExistForUser represents an error where an oidcTeam does not exist for the user
|
||||||
|
type ErrOIDCTeamsDoNotExistForUser struct {
|
||||||
|
UserID int64
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErrOIDCTeamsDoNotExistForUser checks if an error is ErrOIDCTeamsDoNotExistForUser.
|
||||||
|
func IsErrOIDCTeamsDoNotExistForUser(err error) bool {
|
||||||
|
_, ok := err.(ErrTeamDoesNotExist)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrOIDCTeamsDoNotExistForUser) Error() string {
|
||||||
|
return fmt.Sprintf("No Oidc exists for User [User ID: %d]", err.UserID)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrCodeTeamDoesNotExist holds the unique world-error code of this error
|
||||||
|
const ErrCodeOIDCTeamsDoNotExistForUser = 6009
|
||||||
|
|
||||||
|
// HTTPError holds the http error description
|
||||||
|
func (err ErrOIDCTeamsDoNotExistForUser) HTTPError() web.HTTPError {
|
||||||
|
return web.HTTPError{HTTPCode: http.StatusNotFound, Code: ErrCodeTeamDoesNotExist, Message: "This team does not exist."}
|
||||||
|
}
|
||||||
|
|
||||||
// ====================
|
// ====================
|
||||||
// User <-> Project errors
|
// User <-> Project errors
|
||||||
// ====================
|
// ====================
|
||||||
|
|
|
@ -94,6 +94,12 @@ type TeamUser struct {
|
||||||
TeamID int64 `json:"-"`
|
TeamID int64 `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TeamData struct {
|
||||||
|
TeamName string
|
||||||
|
OidcID string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
// GetTeamByID gets a team by its ID
|
// GetTeamByID gets a team by its ID
|
||||||
func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) {
|
func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) {
|
||||||
if id < 1 {
|
if id < 1 {
|
||||||
|
@ -143,16 +149,30 @@ func GetTeamsByName(s *xorm.Session, name string) (teams []*Team, err error) {
|
||||||
|
|
||||||
// GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters
|
// GetTeamByOidcIDAndName gets teams where oidc_id and name match parameters
|
||||||
// For oidc team creation oidcID and Name need to be set
|
// For oidc team creation oidcID and Name need to be set
|
||||||
func GetTeamByOidcIDAndName(s *xorm.Session, id string, name string) (team Team, err error) {
|
func GetTeamByOidcIDAndName(s *xorm.Session, oidcID string, teamName string) (team Team, err error) {
|
||||||
exists, err := s.
|
exists, err := s.
|
||||||
Table("teams").
|
Table("teams").
|
||||||
Where("oidc_id = ? AND name = ?", id, name).
|
Where("oidc_id = ? AND name = ?", oidcID, teamName).
|
||||||
Get(&team)
|
Get(&team)
|
||||||
log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists)
|
log.Debugf("GetTeamByOidcIDAndName: %v, exists: %v", team.Name, exists)
|
||||||
if exists && err == nil {
|
if exists && err == nil {
|
||||||
return team, nil
|
return team, nil
|
||||||
}
|
}
|
||||||
return team, ErrTeamsDoNotExist{id}
|
return team, ErrTeamsDoNotExist{oidcID}
|
||||||
|
}
|
||||||
|
|
||||||
|
func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err error) {
|
||||||
|
err = s.
|
||||||
|
Table("team_members").
|
||||||
|
Where("user_id = ? ", userID).
|
||||||
|
Join("RIGHT", "teams", "teams.id = team_members.team_id").
|
||||||
|
Where("teams.oidc_id != ?", "").
|
||||||
|
Cols("teams.id").
|
||||||
|
Find(&ts)
|
||||||
|
if ts == nil || err != nil {
|
||||||
|
return ts, ErrOIDCTeamsDoNotExistForUser{userID}
|
||||||
|
}
|
||||||
|
return ts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) {
|
func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) {
|
||||||
|
|
|
@ -209,16 +209,22 @@ func HandleCallback(c echo.Context) error {
|
||||||
log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err)
|
log.Errorf("Error creating teams for user and vikunja groups %s: %v", cl.VikunjaGroups, err)
|
||||||
return handler.HandleHTTPError(err, c)
|
return handler.HandleHTTPError(err, c)
|
||||||
}
|
}
|
||||||
// check if we have seen these teams before.
|
|
||||||
// find or create Teams and assign user as teammember.
|
//TODO: fix this error check
|
||||||
|
// nil is no problem
|
||||||
|
|
||||||
if len(teamData) > 0 {
|
if len(teamData) > 0 {
|
||||||
|
//find old teams for user through oidc
|
||||||
|
oldOidcTeams, _ := models.FindAllOidcTeamIDsForUser(s, u.ID)
|
||||||
|
// check if we have seen these teams before.
|
||||||
|
// find or create Teams and assign user as teammember.
|
||||||
|
var oidcTeams []int64
|
||||||
log.Debugf("TeamData is set %v", teamData)
|
log.Debugf("TeamData is set %v", teamData)
|
||||||
teams, err := GetOrCreateTeamsByOIDCAndNames(s, teamData, u)
|
teams, err := GetOrCreateTeamsByOIDCAndNames(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
|
||||||
}
|
}
|
||||||
|
|
||||||
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}
|
||||||
exists, err := tm.CheckMembership(s)
|
exists, err := tm.CheckMembership(s)
|
||||||
|
@ -230,9 +236,10 @@ func HandleCallback(c echo.Context) error {
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Team exists? %v or error: %v", exists, err)
|
log.Debugf("Team exists? %v or error: %v", exists, err)
|
||||||
}
|
}
|
||||||
|
oidcTeams = append(oidcTeams, team.ID)
|
||||||
}
|
}
|
||||||
|
SignOutFromOrDeleteTeamsByID(s, u, notIn(oldOidcTeams, oidcTeams))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.Commit()
|
err = s.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = s.Rollback()
|
_ = s.Rollback()
|
||||||
|
@ -243,13 +250,30 @@ func HandleCallback(c echo.Context) error {
|
||||||
return auth.NewUserAuthTokenResponse(u, c, false)
|
return auth.NewUserAuthTokenResponse(u, c, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SignOutFromOrDeleteTeamsByID(s *xorm.Session, u *user.User, teamIDs []int64) {
|
||||||
|
for _, teamID := range teamIDs {
|
||||||
|
tm := models.TeamMember{TeamID: teamID, Username: u.Username}
|
||||||
|
err := tm.Delete(s, u)
|
||||||
|
if err != nil {
|
||||||
|
team, err := models.GetTeamByID(s, teamID)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Cannot find team with id: %v, err: %v", teamID, err)
|
||||||
|
} else {
|
||||||
|
err = team.Delete(s, u)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Cannot delete team %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) {
|
func getTeamDataFromToken(groups interface{}, provider *Provider) (teamData []TeamData, err error) {
|
||||||
teamData = []TeamData{}
|
teamData = []TeamData{}
|
||||||
if groups != nil {
|
if groups != nil {
|
||||||
el := groups.([]interface{})
|
el := groups.([]interface{})
|
||||||
for _, data := range el {
|
for _, data := range el {
|
||||||
team := data.(map[string]interface{})
|
team := data.(map[string]interface{})
|
||||||
log.Debugf("%s", team)
|
|
||||||
var name string
|
var name string
|
||||||
var description string
|
var description string
|
||||||
var oidcID string
|
var oidcID string
|
||||||
|
@ -395,3 +419,23 @@ func getOrCreateUser(s *xorm.Session, cl *claims, issuer, subject string) (u *us
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find the elements which appear in slice1,but not in slice2
|
||||||
|
func notIn(slice1 []int64, slice2 []int64) []int64 {
|
||||||
|
var diff []int64
|
||||||
|
|
||||||
|
for _, s1 := range slice1 {
|
||||||
|
found := false
|
||||||
|
for _, s2 := range slice2 {
|
||||||
|
if s1 == s2 {
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// String not found. We add it to return slice
|
||||||
|
if !found {
|
||||||
|
diff = append(diff, s1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return diff
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user