feat(auth): rename oidc_id to external_id

This commit is contained in:
kolaente 2025-03-17 17:54:26 +01:00 committed by konrad
parent 55a078b171
commit 62beb3db2d
5 changed files with 103 additions and 36 deletions

View File

@ -33,12 +33,12 @@
- id: 14
name: testteam14
created_by_id: 7
oidc_id: 14
external_id: 14
issuer: "https://some.issuer"
- id: 15
name: testteam15
created_by_id: 7
oidc_id: 15
external_id: 15
issuer: "https://some.issuer"
is_public: true
description: "This is a public team"

View File

@ -0,0 +1,78 @@
// Vikunja is a to-do list application to facilitate your life.
// Copyright 2018-present Vikunja and contributors. All rights reserved.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public Licensee as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public Licensee for more details.
//
// You should have received a copy of the GNU Affero General Public Licensee
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package migration
import (
"src.techknowlogick.com/xormigrate"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
func init() {
migrations = append(migrations, &xormigrate.Migration{
ID: "20250317174522",
Description: "",
Migrate: func(tx *xorm.Engine) (err error) {
if tx.Dialect().URI().DBType == schemas.SQLITE {
_, err = tx.Exec(`create table teams_dg_tmp
(
id INTEGER not null
primary key autoincrement,
name TEXT not null,
description TEXT,
created_by_id INTEGER not null,
external_id TEXT,
issuer TEXT,
created DATETIME,
updated DATETIME,
is_public INTEGER default 0 not null
);
insert into teams_dg_tmp(id, name, description, created_by_id, external_id, issuer, created, updated, is_public)
select id,
name,
description,
created_by_id,
oidc_id,
issuer,
created,
updated,
is_public
from teams;
drop table teams;
alter table teams_dg_tmp
rename to teams;
create index IDX_teams_created_by_id
on teams (created_by_id);
create unique index UQE_teams_id
on teams (id);
`)
return
}
_, err = tx.Exec("ALTER TABLE `teams` RENAME COLUMN `oidc_id` TO `external_id`")
return
},
Rollback: func(tx *xorm.Engine) error {
return nil
},
})
}

View File

@ -39,8 +39,8 @@ type Team struct {
// The team's description.
Description string `xorm:"longtext null" json:"description"`
CreatedByID int64 `xorm:"bigint not null INDEX" json:"-"`
// The team's oidc id delivered by the oidc provider
OidcID string `xorm:"varchar(250) null" maxLength:"250" json:"oidc_id"`
// The team's external id provided by the openid or ldap provider
ExternalID string `xorm:"varchar(250) null" maxLength:"250" json:"external_id"`
// Contains the issuer extracted from the vikunja_groups claim if this team was created through oidc
Issuer string `xorm:"text null" json:"-"`
@ -102,14 +102,6 @@ type TeamUser struct {
TeamID int64 `json:"-"`
}
// OIDCTeam is the relevant data for a team and is delivered by oidc token
type OIDCTeam struct {
Name string
OidcID string
Description string
IsPublic bool
}
// GetTeamByID gets a team by its ID
func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) {
if id < 1 {
@ -139,13 +131,13 @@ func GetTeamByID(s *xorm.Session, id int64) (team *Team, err error) {
return
}
// GetTeamByOidcID returns a team matching the given oidc_id
// GetTeamByOidcID returns a team matching the given external_id
// For oidc team creation oidcID and Name need to be set
func GetTeamByOidcIDAndIssuer(s *xorm.Session, oidcID string, issuer string) (*Team, error) {
team := &Team{}
has, err := s.
Table("teams").
Where("oidc_id = ? AND issuer = ?", oidcID, issuer).
Where("external_id = ? AND issuer = ?", oidcID, issuer).
Get(team)
if !has || err != nil {
return nil, ErrOIDCTeamDoesNotExist{issuer, oidcID}
@ -158,13 +150,10 @@ func FindAllOidcTeamIDsForUser(s *xorm.Session, userID int64) (ts []int64, err e
Table("team_members").
Where("user_id = ? ", userID).
Join("RIGHT", "teams", "teams.id = team_members.team_id").
Where("teams.oidc_id != ? AND teams.oidc_id IS NOT NULL", "").
Where("teams.external_id != ? AND teams.external_id IS NOT NULL", "").
Cols("teams.id").
Find(&ts)
if ts == nil || err != nil {
return ts, err
}
return ts, nil
return
}
func addMoreInfoToTeams(s *xorm.Session, teams []*Team) (err error) {

View File

@ -31,7 +31,7 @@ func RemoveEmptySSOTeams(s *xorm.Session) (err error) {
err = s.
Where(
builder.NotIn("id", builder.Expr("select team_members.team_id from team_members")),
builder.Or(builder.Neq{"oidc_id": ""}, builder.NotNull{"oidc_id"}),
builder.Or(builder.Neq{"external_id": ""}, builder.NotNull{"external_id"}),
).
Find(&teams)
if err != nil {

View File

@ -221,42 +221,42 @@ func RemoveUserFromTeamsByIDs(s *xorm.Session, u *user.User, teamIDs []int64) (e
func getTeamDataFromToken(groups []map[string]interface{}, provider *Provider) (teamData []*team, errs []error) {
teamData = []*team{}
errs = []error{}
for _, team := range groups {
for _, t := range groups {
var name string
var description string
var oidcID string
var IsPublic bool
// Read name
_, exists := team["name"]
_, exists := t["name"]
if exists {
name = team["name"].(string)
name = t["name"].(string)
}
// Read description
_, exists = team["description"]
_, exists = t["description"]
if exists {
description = team["description"].(string)
description = t["description"].(string)
}
// Read isPublic flag
_, exists = team["isPublic"]
_, exists = t["isPublic"]
if exists {
IsPublic = team["isPublic"].(bool)
IsPublic = t["isPublic"].(bool)
}
// Read oidcID
_, exists = team["oidcID"]
_, exists = t["oidcID"]
if exists {
switch t := team["oidcID"].(type) {
switch id := t["oidcID"].(type) {
case string:
oidcID = team["oidcID"].(string)
oidcID = id
case int64:
oidcID = strconv.FormatInt(team["oidcID"].(int64), 10)
oidcID = strconv.FormatInt(id, 10)
case float64:
oidcID = strconv.FormatFloat(team["oidcID"].(float64), 'f', -1, 64)
oidcID = strconv.FormatFloat(id, 'f', -1, 64)
default:
log.Errorf("No oidcID assigned for %v or type %v not supported", team, t)
log.Errorf("No oidcID assigned for %v or type %v not supported", t, t)
}
}
if name == "" || oidcID == "" {
@ -277,7 +277,7 @@ func CreateOIDCTeam(s *xorm.Session, teamData *team, u *user.User, issuer string
team = &models.Team{
Name: getOIDCTeamName(teamData.Name),
Description: teamData.Description,
OidcID: teamData.OidcID,
ExternalID: teamData.OidcID,
Issuer: issuer,
IsPublic: teamData.IsPublic,
}
@ -295,7 +295,7 @@ func GetOrCreateTeamsByOIDC(s *xorm.Session, teamData []*team, u *user.User, iss
return nil, err
}
if err != nil && models.IsErrOIDCTeamDoesNotExist(err) {
log.Debugf("Team with oidc_id %v and name %v does not exist. Creating team… ", oidcTeam.OidcID, oidcTeam.Name)
log.Debugf("Team with external_id %v and name %v does not exist. Creating team… ", oidcTeam.OidcID, oidcTeam.Name)
newTeam, err := CreateOIDCTeam(s, oidcTeam, u, issuer)
if err != nil {
return te, err
@ -324,7 +324,7 @@ func GetOrCreateTeamsByOIDC(s *xorm.Session, teamData []*team, u *user.User, iss
return nil, err
}
log.Debugf("Team with oidc_id %v and name %v already exists.", team.OidcID, team.Name)
log.Debugf("Team with external_id %v and name %v already exists.", team.ExternalID, team.Name)
te = append(te, team)
}
return te, err