Implement filtering of users and groups via sentry

Drop the previous implementationusing custom code
This commit is contained in:
Abin Simon
2022-03-28 22:06:00 +05:30
parent cf0b830924
commit e8cc7d2f1c
14 changed files with 554 additions and 274 deletions

View File

@@ -505,47 +505,60 @@ func (s *userService) List(ctx context.Context, opts ...query.Option) (*userv3.U
opt(&queryOptions)
}
// TODO: group relation stuff
// TODO: This is kinda expensive to compute
upr, err := getUserProjectRoles(ctx, s.db)
partnerId, orgId, err := getPartnerOrganization(ctx, s.db, queryOptions.Partner, queryOptions.Organization)
if err != nil {
return &userv3.UserList{}, err
return &userv3.UserList{}, fmt.Errorf("unable to find role partner and org")
}
fmt.Println("upr:", upr)
projects := []string{}
fmt.Println("queryOptions.Project:", queryOptions.Project)
roleName := queryOptions.Role
roleId := uuid.Nil
if roleName != "" {
role, err := dao.GetIdByName(ctx, s.db, roleName, &models.Role{})
if err != nil {
return &userv3.UserList{}, fmt.Errorf("unable to find role '%v'", roleName)
}
if rle, ok := role.(*models.Role); ok {
roleId = rle.ID
}
}
groupName := queryOptions.Group
groupId := uuid.Nil
if groupName != "" {
group, err := dao.GetIdByName(ctx, s.db, groupName, &models.Group{})
if err != nil {
return &userv3.UserList{}, fmt.Errorf("unable to find group '%v'", groupName)
}
if grp, ok := group.(*models.Group); ok {
groupId = grp.ID
}
}
projectIds := []uuid.UUID{}
if queryOptions.Project != "" {
projects = strings.Split(queryOptions.Project, ",")
for _, p := range strings.Split(queryOptions.Project, ",") {
if p == "ALL" {
projectIds = append(projectIds, uuid.Nil)
} else {
project, err := dao.GetIdByName(ctx, s.db, p, &models.Project{})
if err != nil {
return &userv3.UserList{}, fmt.Errorf("unable to find project '%v'", p)
}
if prj, ok := project.(*models.Project); ok {
projectIds = append(projectIds, prj.ID)
}
}
}
}
// TODO: make this a single big query
fupr, err := filterUserProjectRoles(upr,
projects,
"role-name", // TODO: add role to QueryOptions
// queryOptions.Role,
)
uids, err := dao.GetQueryFilteredUsers(ctx, s.db, partnerId, orgId, groupId, roleId, projectIds)
if err != nil {
return &userv3.UserList{}, err
}
fmt.Println("fupr:", fupr)
uids := []uuid.UUID{}
for k := range fupr {
uids = append(uids, k)
}
// TODO: add gorup to search
if queryOptions.Group {
// partnerId, organizationId, err := s.getPartnerOrganization(ctx, s.db, group)
// if err != nil {
// return nil, fmt.Errorf("unable to get partner and org id")
// }
ga := []models.GroupAccount{}
g, err := dao.Get(ctx, )
}
if len(fupr) != 0 {
if len(uids) != 0 {
var accs []models.KratosIdentities
// TODO: maybe merge this with the previous one into single sql
usrs, err := dao.ListFilteredUsers(ctx, s.db, &accs,
uids, queryOptions.Q,
queryOptions.OrderBy, queryOptions.Order,

View File

@@ -38,61 +38,15 @@ func remove(l []string, item string) []string {
return l
}
type projectRole struct {
Project *string
Role string
}
type userProjectRoles map[uuid.UUID][]projectRole
func getUserProjectRoles(ctx context.Context, db bun.IDB) (userProjectRoles, error) {
roles, err := dao.ListUserRoles(ctx, db)
func getPartnerOrganization(ctx context.Context, db bun.IDB, partner, org string) (uuid.UUID, uuid.UUID, error) {
partnerId, err := dao.GetPartnerId(ctx, db, partner)
if err != nil {
return userProjectRoles{}, err
return uuid.Nil, uuid.Nil, err
}
upr := userProjectRoles{}
for _, role := range roles {
upr[role.AccountId] = append(upr[role.AccountId], projectRole{Project: role.Project, Role: role.Role})
organizationId, err := dao.GetOrganizationId(ctx, db, org)
if err != nil {
return partnerId, uuid.Nil, err
}
return partnerId, organizationId, nil
return upr, nil
}
func projectAvailable(r []projectRole, projects []string) bool {
// This is an OR internally
// ALL is when the permissions is not project bound
all := false
if contains(projects, "ALL") {
all = true
projects = remove(projects, "ALL")
}
for _, pr := range r {
if pr.Project != nil {
if contains(projects, *pr.Project) {
return true
}
} else if all {
return true
}
}
return false
}
func roleAvailable(r []projectRole, role string) bool {
for _, pr := range r {
if pr.Role == role {
return true
}
}
return false
}
func filterUserProjectRoles(upr userProjectRoles, projects []string, role string) (userProjectRoles, error) {
fupr := userProjectRoles{}
for u, r := range upr {
if (len(projects) == 0 || projectAvailable(r, projects)) && (role == "" || roleAvailable(r, role)) {
fupr[u] = r
}
}
return fupr, nil
}