mirror of
https://github.com/paralus/paralus.git
synced 2026-08-24 15:47:19 +00:00
Add option to filter by user auth mode
Pass in type=password or type=oidc to pick the mode
This commit is contained in:
@@ -97,8 +97,16 @@ func GetQueryFilteredUsers(ctx context.Context, db bun.IDB, partner, org, group,
|
||||
}
|
||||
|
||||
// ListFilteredUsers will return the list of users fileterd by query
|
||||
func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) {
|
||||
func ListFilteredUsers(ctx context.Context, db bun.IDB, users *[]models.KratosIdentities, fusers []uuid.UUID, query string, utype string, orderBy string, order string, limit int, offset int) (*[]models.KratosIdentities, error) {
|
||||
q := db.NewSelect().Model(users)
|
||||
|
||||
if utype != "" {
|
||||
q.Relation("IdentityCredential").
|
||||
Relation("IdentityCredential.IdentityCredentialType", func(q *bun.SelectQuery) *bun.SelectQuery {
|
||||
return q.Where("name = ?", utype)
|
||||
})
|
||||
}
|
||||
|
||||
if len(fusers) > 0 {
|
||||
// filter with precomputed users if we have any
|
||||
q.Where("id IN (?)", bun.In(fusers))
|
||||
|
||||
@@ -7,15 +7,32 @@ import (
|
||||
"github.com/uptrace/bun"
|
||||
)
|
||||
|
||||
type KratosIdentityCredentialTypes struct {
|
||||
bun.BaseModel `bun:"table:identity_credential_types,alias:ict"`
|
||||
|
||||
ID uuid.UUID `bun:"id,type:uuid,pk"`
|
||||
Name string `bun:"name,type:string"`
|
||||
}
|
||||
|
||||
type KratosIdentityCredentials struct {
|
||||
bun.BaseModel `bun:"table:identity_credentials,alias:ic"`
|
||||
|
||||
ID uuid.UUID `bun:"id,type:uuid,pk"`
|
||||
IdentityID uuid.UUID `bun:"identity_id,type:uuid"`
|
||||
IdentityCredentialTypeID uuid.UUID `bun:"identity_credential_type_id,type:uuid"`
|
||||
IdentityCredentialType KratosIdentityCredentialTypes `bun:"rel:has-one,join:identity_credential_type_id=id"`
|
||||
}
|
||||
|
||||
type KratosIdentities struct {
|
||||
bun.BaseModel `bun:"table:identities,alias:identities"`
|
||||
|
||||
ID uuid.UUID `bun:"id,type:uuid,pk"`
|
||||
SchemaId string `bun:"schema_id,notnull"`
|
||||
Traits map[string]interface{} `bun:"traits,type:jsonb"`
|
||||
CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"`
|
||||
UpdatedAt time.Time `bun:"updated_at,notnull,default:current_timestamp"`
|
||||
State string `bun:"state,notnull"`
|
||||
StateChangedAt time.Time `bun:"state_changed_at,notnull,default:current_timestamp"`
|
||||
NId uuid.UUID `bun:"nid,type:uuid,pk"`
|
||||
ID uuid.UUID `bun:"id,type:uuid,pk"`
|
||||
SchemaId string `bun:"schema_id,notnull"`
|
||||
Traits map[string]interface{} `bun:"traits,type:jsonb"`
|
||||
CreatedAt time.Time `bun:"created_at,notnull,default:current_timestamp"`
|
||||
UpdatedAt time.Time `bun:"updated_at,notnull,default:current_timestamp"`
|
||||
State string `bun:"state,notnull"`
|
||||
StateChangedAt time.Time `bun:"state_changed_at,notnull,default:current_timestamp"`
|
||||
NId uuid.UUID `bun:"nid,type:uuid,pk"`
|
||||
IdentityCredential KratosIdentityCredentials `bun:"rel:has-one,join:id=identity_id"`
|
||||
}
|
||||
|
||||
+1
-1
@@ -276,7 +276,7 @@ spec:
|
||||
project: :project
|
||||
|
||||
# Get all users
|
||||
GET :host/auth/v3/users
|
||||
GET :host/auth/v3/users?partner=:partner&organization=:org&type=password
|
||||
Content-Type: application/yaml
|
||||
X-Session-Token: :token
|
||||
|
||||
|
||||
+2
-2
@@ -718,7 +718,7 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U
|
||||
if len(uids) != 0 {
|
||||
// TODO: maybe merge this with the previous one into single sql
|
||||
usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs,
|
||||
uids, queryOptions.Q,
|
||||
uids, queryOptions.Q, queryOptions.Type,
|
||||
queryOptions.OrderBy, queryOptions.Order,
|
||||
int(queryOptions.Limit), int(queryOptions.Offset))
|
||||
if err != nil {
|
||||
@@ -728,7 +728,7 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U
|
||||
} else {
|
||||
// If no filters are available we have to list just using identities table
|
||||
usrs, err = dao.ListFilteredUsers(ctx, s.db, &accs,
|
||||
[]uuid.UUID{}, queryOptions.Q,
|
||||
[]uuid.UUID{}, queryOptions.Q, queryOptions.Type,
|
||||
queryOptions.OrderBy, queryOptions.Order,
|
||||
int(queryOptions.Limit), int(queryOptions.Offset))
|
||||
if err != nil {
|
||||
|
||||
@@ -490,6 +490,90 @@ func TestUserList(t *testing.T) {
|
||||
|
||||
performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
func TestUserListWithType(t *testing.T) {
|
||||
// TODO: merge these tests
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
ap := &mockAuthProvider{}
|
||||
mazc := mockAuthzClient{}
|
||||
us := NewUserService(ap, db, &mazc, nil, common.CliConfigDownloadData{})
|
||||
|
||||
uuuid1 := uuid.New().String()
|
||||
uuuid2 := uuid.New().String()
|
||||
puuid := uuid.New().String()
|
||||
ouuid := uuid.New().String()
|
||||
guuid := uuid.New().String()
|
||||
ruuid := uuid.New().String()
|
||||
pruuid := uuid.New().String()
|
||||
|
||||
mock.ExpectQuery(`SELECT "partner"."id" FROM "authsrv_partner" AS "partner"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(puuid))
|
||||
mock.ExpectQuery(`SELECT "organization"."id" FROM "authsrv_organization" AS "organization"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow(ouuid))
|
||||
mock.ExpectQuery(`SELECT "identities"."id", "identities"."schema_id", "identities"."traits", "identities"."created_at", "identities"."updated_at", "identities"."state", "identities"."state_changed_at", "identities"."nid", "identity_credential"."id" AS "identity_credential__id", "identity_credential"."identity_id" AS "identity_credential__identity_id", "identity_credential"."identity_credential_type_id" AS "identity_credential__identity_credential_type_id", "identity_credential__identity_credential_type"."id" AS "identity_credential__identity_credential_type__id", "identity_credential__identity_credential_type"."name" AS "identity_credential__identity_credential_type__name" FROM "identities" LEFT JOIN "identity_credentials" AS "identity_credential" ON ."identity_credential"."identity_id" = "identities"."id". LEFT JOIN "identity_credential_types" AS "identity_credential__identity_credential_type" ON ."identity_credential__identity_credential_type"."id" = "identity_credential"."identity_credential_type_id". WHERE .name = 'password'. LIMIT 10`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"id", "traits"}).
|
||||
AddRow(uuuid1, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)).
|
||||
AddRow(uuuid2, []byte(`{"email":"johndoe@provider.com", "first_name": "John", "last_name": "Doe", "organization_id": "`+ouuid+`", "partner_id": "`+puuid+`", "description": "My awesome user"}`)))
|
||||
|
||||
mock.ExpectQuery(`SELECT "group"."id".* FROM "authsrv_group" AS "group" JOIN authsrv_groupaccount ON authsrv_groupaccount.group_id="group".id WHERE .authsrv_groupaccount.account_id = '` + uuuid1 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"name"}).
|
||||
AddRow("group-" + guuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_group.name as group FROM "authsrv_grouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_grouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_grouprole.group_id WHERE`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "group"}).AddRow("role-"+ruuid, "group-"+guuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id WHERE`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace, authsrv_group.name as group FROM "authsrv_projectgroupnamespacerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role FROM "authsrv_accountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_accountresourcerole.role_id WHERE .authsrv_accountresourcerole.account_id = '` + uuuid1 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("role-" + ruuid))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountresourcerole.project_id WHERE .authsrv_projectaccountresourcerole.account_id = '` + uuuid1 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+pruuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid1 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9))
|
||||
|
||||
mock.ExpectQuery(`SELECT "group"."id".* FROM "authsrv_group" AS "group" JOIN authsrv_groupaccount ON authsrv_groupaccount.group_id="group".id WHERE .authsrv_groupaccount.account_id = '` + uuuid2 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"name"}).
|
||||
AddRow("group-" + guuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_group.name as group FROM "authsrv_grouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_grouprole.role_id JOIN authsrv_group ON authsrv_group.id=authsrv_grouprole.group_id WHERE`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "group"}).AddRow("role-"+ruuid, "group-"+guuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, authsrv_group.name as group FROM "authsrv_projectgrouprole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectgrouprole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectgrouprole.project_id JOIN authsrv_group ON authsrv_group.id=authsrv_projectgrouprole.group_id WHERE`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace, authsrv_group.name as group FROM "authsrv_projectgroupnamespacerole"`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+puuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role FROM "authsrv_accountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_accountresourcerole.role_id WHERE .authsrv_accountresourcerole.account_id = '` + uuuid2 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role"}).AddRow("role-" + ruuid))
|
||||
mock.ExpectQuery(`SELECT distinct authsrv_resourcerole.name as role, authsrv_project.name as project FROM "authsrv_projectaccountresourcerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountresourcerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountresourcerole.project_id WHERE .authsrv_projectaccountresourcerole.account_id = '` + uuuid2 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project"}).AddRow("role-"+ruuid, "project-"+pruuid))
|
||||
mock.ExpectQuery(`SELECT authsrv_resourcerole.name as role, authsrv_project.name as project, namespace_id as namespace FROM "authsrv_projectaccountnamespacerole" JOIN authsrv_resourcerole ON authsrv_resourcerole.id=authsrv_projectaccountnamespacerole.role_id JOIN authsrv_project ON authsrv_project.id=authsrv_projectaccountnamespacerole.project_id WHERE .authsrv_projectaccountnamespacerole.account_id = '` + uuuid2 + `'`).
|
||||
WithArgs().WillReturnRows(sqlmock.NewRows([]string{"role", "project", "namespace"}).AddRow("role-"+ruuid, "project-"+pruuid, 9))
|
||||
|
||||
qo := &commonv3.QueryOptions{Organization: ouuid, Partner: puuid, Type: "password"}
|
||||
userlist, err := us.List(context.Background(), query.WithOptions(qo))
|
||||
if err != nil {
|
||||
t.Fatal("could not list users:", err)
|
||||
}
|
||||
if userlist.Metadata.Count != 2 {
|
||||
t.Fatalf("incorrect number of users returned, expected 2; got %v", userlist.Metadata.Count)
|
||||
}
|
||||
if userlist.Items[0].Metadata.Name != "johndoe@provider.com" || userlist.Items[1].Metadata.Name != "johndoe@provider.com" {
|
||||
t.Errorf("incorrect user names returned when listing; expected '%v' and '%v'; got '%v' and '%v'", "johndoe@provider.com", "johndoe@provider.com", userlist.Items[0].Metadata.Name, userlist.Items[1].Metadata.Name)
|
||||
}
|
||||
if len(userlist.Items[0].GetSpec().GetGroups()) != 1 {
|
||||
t.Errorf("invalid number of groups returned for user, expected 1; got '%v'", len(userlist.Items[0].GetSpec().GetGroups()))
|
||||
}
|
||||
|
||||
if len(userlist.Items[0].GetSpec().GetProjectNamespaceRoles()) != 6 {
|
||||
t.Errorf("invalid number of roles returned for user, expected 6; got '%v'", len(userlist.Items[0].GetSpec().GetProjectNamespaceRoles()))
|
||||
}
|
||||
if userlist.Items[0].GetSpec().GetProjectNamespaceRoles()[2].GetNamespace() != 9 {
|
||||
t.Errorf("invalid namespace in role returned for user, expected 9; got '%v'", userlist.Items[0].GetSpec().GetProjectNamespaceRoles()[2].Namespace)
|
||||
}
|
||||
|
||||
performBasicAuthProviderChecks(t, *ap, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
func TestUserFiltered(t *testing.T) {
|
||||
db, mock := getDB(t)
|
||||
defer db.Close()
|
||||
|
||||
Reference in New Issue
Block a user