mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 19:17:32 +00:00
feat: iam members in admin api (#272)
* feat: iam members in admin api * feat: add error id in translate error * fix: resolve merge conflicts
This commit is contained in:
@@ -9,8 +9,8 @@ type IamMember struct {
|
||||
Roles []string
|
||||
}
|
||||
|
||||
func NewIamMember(projectID, userID string) *IamMember {
|
||||
return &IamMember{ObjectRoot: es_models.ObjectRoot{AggregateID: projectID}, UserID: userID}
|
||||
func NewIamMember(iamID, userID string) *IamMember {
|
||||
return &IamMember{ObjectRoot: es_models.ObjectRoot{AggregateID: iamID}, UserID: userID}
|
||||
}
|
||||
|
||||
func (i *IamMember) IsValid() bool {
|
||||
|
58
internal/iam/model/iam_member_view.go
Normal file
58
internal/iam/model/iam_member_view.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
type IamMemberView struct {
|
||||
UserID string
|
||||
IamID string
|
||||
UserName string
|
||||
Email string
|
||||
FirstName string
|
||||
LastName string
|
||||
Roles []string
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
}
|
||||
|
||||
type IamMemberSearchRequest struct {
|
||||
Offset uint64
|
||||
Limit uint64
|
||||
SortingColumn IamMemberSearchKey
|
||||
Asc bool
|
||||
Queries []*IamMemberSearchQuery
|
||||
}
|
||||
|
||||
type IamMemberSearchKey int32
|
||||
|
||||
const (
|
||||
IamMemberSearchKeyUnspecified IamMemberSearchKey = iota
|
||||
IamMemberSearchKeyUserName
|
||||
IamMemberSearchKeyEmail
|
||||
IamMemberSearchKeyFirstName
|
||||
IamMemberSearchKeyLastName
|
||||
IamMemberSearchKeyIamID
|
||||
IamMemberSearchKeyUserID
|
||||
)
|
||||
|
||||
type IamMemberSearchQuery struct {
|
||||
Key IamMemberSearchKey
|
||||
Method model.SearchMethod
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
type IamMemberSearchResponse struct {
|
||||
Offset uint64
|
||||
Limit uint64
|
||||
TotalResult uint64
|
||||
Result []*IamMemberView
|
||||
}
|
||||
|
||||
func (r *IamMemberSearchRequest) EnsureLimit(limit uint64) {
|
||||
if r.Limit == 0 || r.Limit > limit {
|
||||
r.Limit = limit
|
||||
}
|
||||
}
|
59
internal/iam/repository/view/iam_member_view.go
Normal file
59
internal/iam/repository/view/iam_member_view.go
Normal file
@@ -0,0 +1,59 @@
|
||||
package view
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/iam/repository/view/model"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
func IamMemberByIDs(db *gorm.DB, table, orgID, userID string) (*model.IamMemberView, error) {
|
||||
member := new(model.IamMemberView)
|
||||
|
||||
orgIDQuery := &model.IamMemberSearchQuery{Key: iam_model.IamMemberSearchKeyIamID, Value: orgID, Method: global_model.SearchMethodEquals}
|
||||
userIDQuery := &model.IamMemberSearchQuery{Key: iam_model.IamMemberSearchKeyUserID, Value: userID, Method: global_model.SearchMethodEquals}
|
||||
query := repository.PrepareGetByQuery(table, orgIDQuery, userIDQuery)
|
||||
err := query(db, member)
|
||||
return member, err
|
||||
}
|
||||
|
||||
func SearchIamMembers(db *gorm.DB, table string, req *iam_model.IamMemberSearchRequest) ([]*model.IamMemberView, int, error) {
|
||||
members := make([]*model.IamMemberView, 0)
|
||||
query := repository.PrepareSearchQuery(table, model.IamMemberSearchRequest{Limit: req.Limit, Offset: req.Offset, Queries: req.Queries})
|
||||
count, err := query(db, &members)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
return members, count, nil
|
||||
}
|
||||
func IamMembersByUserID(db *gorm.DB, table string, userID string) ([]*model.IamMemberView, error) {
|
||||
members := make([]*model.IamMemberView, 0)
|
||||
queries := []*iam_model.IamMemberSearchQuery{
|
||||
{
|
||||
Key: iam_model.IamMemberSearchKeyUserID,
|
||||
Value: userID,
|
||||
Method: global_model.SearchMethodEquals,
|
||||
},
|
||||
}
|
||||
query := repository.PrepareSearchQuery(table, model.IamMemberSearchRequest{Queries: queries})
|
||||
_, err := query(db, &members)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return members, nil
|
||||
}
|
||||
|
||||
func PutIamMember(db *gorm.DB, table string, role *model.IamMemberView) error {
|
||||
save := repository.PrepareSave(table)
|
||||
return save(db, role)
|
||||
}
|
||||
|
||||
func DeleteIamMember(db *gorm.DB, table, orgID, userID string) error {
|
||||
member, err := IamMemberByIDs(db, table, orgID, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delete := repository.PrepareDeleteByObject(table, member)
|
||||
return delete(db)
|
||||
}
|
100
internal/iam/repository/view/model/iam_member.go
Normal file
100
internal/iam/repository/view/model/iam_member.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
es_model "github.com/caos/zitadel/internal/iam/repository/eventsourcing/model"
|
||||
"time"
|
||||
|
||||
"github.com/caos/logging"
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/models"
|
||||
"github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
const (
|
||||
IamMemberKeyUserID = "user_id"
|
||||
IamMemberKeyIamID = "org_id"
|
||||
IamMemberKeyUserName = "user_name"
|
||||
IamMemberKeyEmail = "email"
|
||||
IamMemberKeyFirstName = "first_name"
|
||||
IamMemberKeyLastName = "last_name"
|
||||
)
|
||||
|
||||
type IamMemberView struct {
|
||||
UserID string `json:"userId" gorm:"column:user_id;primary_key"`
|
||||
IamID string `json:"-" gorm:"column:iam_id"`
|
||||
UserName string `json:"-" gorm:"column:user_name"`
|
||||
Email string `json:"-" gorm:"column:email_address"`
|
||||
FirstName string `json:"-" gorm:"column:first_name"`
|
||||
LastName string `json:"-" gorm:"column:last_name"`
|
||||
Roles pq.StringArray `json:"roles" gorm:"column:roles"`
|
||||
Sequence uint64 `json:"-" gorm:"column:sequence"`
|
||||
|
||||
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
|
||||
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
|
||||
}
|
||||
|
||||
func IamMemberViewFromModel(member *model.IamMemberView) *IamMemberView {
|
||||
return &IamMemberView{
|
||||
UserID: member.UserID,
|
||||
IamID: member.IamID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
}
|
||||
}
|
||||
|
||||
func IamMemberToModel(member *IamMemberView) *model.IamMemberView {
|
||||
return &model.IamMemberView{
|
||||
UserID: member.UserID,
|
||||
IamID: member.IamID,
|
||||
UserName: member.UserName,
|
||||
Email: member.Email,
|
||||
FirstName: member.FirstName,
|
||||
LastName: member.LastName,
|
||||
Roles: member.Roles,
|
||||
Sequence: member.Sequence,
|
||||
CreationDate: member.CreationDate,
|
||||
ChangeDate: member.ChangeDate,
|
||||
}
|
||||
}
|
||||
|
||||
func IamMembersToModel(roles []*IamMemberView) []*model.IamMemberView {
|
||||
result := make([]*model.IamMemberView, len(roles))
|
||||
for i, r := range roles {
|
||||
result[i] = IamMemberToModel(r)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (r *IamMemberView) AppendEvent(event *models.Event) (err error) {
|
||||
r.Sequence = event.Sequence
|
||||
r.ChangeDate = event.CreationDate
|
||||
switch event.Type {
|
||||
case es_model.IamMemberAdded:
|
||||
r.setRootData(event)
|
||||
r.CreationDate = event.CreationDate
|
||||
err = r.SetData(event)
|
||||
case es_model.IamMemberChanged:
|
||||
err = r.SetData(event)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *IamMemberView) setRootData(event *models.Event) {
|
||||
r.IamID = event.AggregateID
|
||||
}
|
||||
|
||||
func (r *IamMemberView) SetData(event *models.Event) error {
|
||||
if err := json.Unmarshal(event.Data, r); err != nil {
|
||||
logging.Log("EVEN-Psl89").WithError(err).Error("could not unmarshal event data")
|
||||
return caos_errs.ThrowInternal(err, "MODEL-lub6s", "Could not unmarshal data")
|
||||
}
|
||||
return nil
|
||||
}
|
69
internal/iam/repository/view/model/iam_member_query.go
Normal file
69
internal/iam/repository/view/model/iam_member_query.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
global_model "github.com/caos/zitadel/internal/model"
|
||||
"github.com/caos/zitadel/internal/view/repository"
|
||||
)
|
||||
|
||||
type IamMemberSearchRequest iam_model.IamMemberSearchRequest
|
||||
type IamMemberSearchQuery iam_model.IamMemberSearchQuery
|
||||
type IamMemberSearchKey iam_model.IamMemberSearchKey
|
||||
|
||||
func (req IamMemberSearchRequest) GetLimit() uint64 {
|
||||
return req.Limit
|
||||
}
|
||||
|
||||
func (req IamMemberSearchRequest) GetOffset() uint64 {
|
||||
return req.Offset
|
||||
}
|
||||
|
||||
func (req IamMemberSearchRequest) GetSortingColumn() repository.ColumnKey {
|
||||
if req.SortingColumn == iam_model.IamMemberSearchKeyUnspecified {
|
||||
return nil
|
||||
}
|
||||
return IamMemberSearchKey(req.SortingColumn)
|
||||
}
|
||||
|
||||
func (req IamMemberSearchRequest) GetAsc() bool {
|
||||
return req.Asc
|
||||
}
|
||||
|
||||
func (req IamMemberSearchRequest) GetQueries() []repository.SearchQuery {
|
||||
result := make([]repository.SearchQuery, len(req.Queries))
|
||||
for i, q := range req.Queries {
|
||||
result[i] = IamMemberSearchQuery{Key: q.Key, Value: q.Value, Method: q.Method}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (req IamMemberSearchQuery) GetKey() repository.ColumnKey {
|
||||
return IamMemberSearchKey(req.Key)
|
||||
}
|
||||
|
||||
func (req IamMemberSearchQuery) GetMethod() global_model.SearchMethod {
|
||||
return req.Method
|
||||
}
|
||||
|
||||
func (req IamMemberSearchQuery) GetValue() interface{} {
|
||||
return req.Value
|
||||
}
|
||||
|
||||
func (key IamMemberSearchKey) ToColumnName() string {
|
||||
switch iam_model.IamMemberSearchKey(key) {
|
||||
case iam_model.IamMemberSearchKeyEmail:
|
||||
return IamMemberKeyEmail
|
||||
case iam_model.IamMemberSearchKeyFirstName:
|
||||
return IamMemberKeyFirstName
|
||||
case iam_model.IamMemberSearchKeyLastName:
|
||||
return IamMemberKeyLastName
|
||||
case iam_model.IamMemberSearchKeyUserName:
|
||||
return IamMemberKeyUserName
|
||||
case iam_model.IamMemberSearchKeyUserID:
|
||||
return IamMemberKeyUserID
|
||||
case iam_model.IamMemberSearchKeyIamID:
|
||||
return IamMemberKeyIamID
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user