diff --git a/server/service/core/action/author/list.go b/server/service/core/action/author/list.go index d0573a2a..4198443a 100644 --- a/server/service/core/action/author/list.go +++ b/server/service/core/action/author/list.go @@ -1,7 +1,6 @@ package author import ( - "log" "net/http" "github.com/factly/dega-server/config" @@ -67,7 +66,7 @@ func list(w http.ResponseWriter, r *http.Request) { } // get users details from zitadel - zitadelUsers, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorization"), authCtx.OrganisationID, uIDs, nil) + res, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorization"), authCtx.OrganisationID, uIDs, nil) if err != nil { loggerx.Error(err) @@ -75,9 +74,7 @@ func list(w http.ResponseWriter, r *http.Request) { return } - log.Println(zitadelUsers) - - for _, zitadelUser := range zitadelUsers { + for _, zitadelUser := range res.Result { authors = append(authors, model.Author{ ID: zitadelUser.ID, DisplayName: zitadelUser.Human.Profile.DisplayName, @@ -87,6 +84,7 @@ func list(w http.ResponseWriter, r *http.Request) { } result.Nodes = authors + result.Total = res.Total renderx.JSON(w, http.StatusOK, result) } @@ -125,9 +123,9 @@ func PublicList(w http.ResponseWriter, r *http.Request) { } // get users details from zitadel - zitadelUsers, _ := zitadel.GetOrganisationUsers(viper.GetString("ZITADEL_PERSONAL_ACCESS_TOKEN"), authCtx.OrganisationID, uIDs, nil) + res, _ := zitadel.GetOrganisationUsers(viper.GetString("ZITADEL_PERSONAL_ACCESS_TOKEN"), authCtx.OrganisationID, uIDs, nil) - for _, zitadelUser := range zitadelUsers { + for _, zitadelUser := range res.Result { authors = append(authors, model.Author{ ID: zitadelUser.ID, DisplayName: zitadelUser.Human.Profile.DisplayName, @@ -137,6 +135,7 @@ func PublicList(w http.ResponseWriter, r *http.Request) { } result.Nodes = authors + result.Total = res.Total renderx.JSON(w, http.StatusOK, result) } diff --git a/server/service/core/action/policy/create.go b/server/service/core/action/policy/create.go index 248e6839..4a1f82e2 100644 --- a/server/service/core/action/policy/create.go +++ b/server/service/core/action/policy/create.go @@ -60,7 +60,7 @@ func create(w http.ResponseWriter, r *http.Request) { SpaceID: authCtx.SpaceID, } - users, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorization"), authCtx.OrganisationID, policyReq.Users, nil) + res, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorization"), authCtx.OrganisationID, policyReq.Users, nil) if err != nil { loggerx.Error(err) @@ -68,7 +68,7 @@ func create(w http.ResponseWriter, r *http.Request) { return } - if len(users) != len(policyReq.Users) { + if int(res.Total) != len(policyReq.Users) { errorx.Render(w, errorx.Parser(errorx.DecodeError())) return } @@ -134,7 +134,7 @@ func create(w http.ResponseWriter, r *http.Request) { Users: []policyUser{}, } - for _, user := range users { + for _, user := range res.Result { policyUser := policyUser{ UserID: user.ID, DisplayName: user.Human.Profile.DisplayName, diff --git a/server/service/core/action/policy/details.go b/server/service/core/action/policy/details.go index 7ffa7674..f28623bb 100644 --- a/server/service/core/action/policy/details.go +++ b/server/service/core/action/policy/details.go @@ -93,14 +93,14 @@ func details(w http.ResponseWriter, r *http.Request) { uIDs = append(uIDs, policyUser.UserID) } - users, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorisation"), authCtx.OrganisationID, uIDs, nil) + res, err := zitadel.GetOrganisationUsers(r.Header.Get("Authorisation"), authCtx.OrganisationID, uIDs, nil) if err != nil { errorx.Render(w, errorx.Parser(errorx.InternalServerError())) return } - if len(users) != len(uIDs) { + if int(res.Total) != len(uIDs) { errorx.Render(w, errorx.Parser(errorx.InternalServerError())) return } @@ -131,7 +131,7 @@ func details(w http.ResponseWriter, r *http.Request) { Users: []policyUser{}, } - for _, user := range users { + for _, user := range res.Result { result.Users = append(result.Users, policyUser{ UserID: user.ID, DisplayName: user.Human.Profile.DisplayName, diff --git a/server/service/core/action/space/user.go b/server/service/core/action/space/user.go index bf79c428..a5b1baf1 100644 --- a/server/service/core/action/space/user.go +++ b/server/service/core/action/space/user.go @@ -34,6 +34,6 @@ func usersList(w http.ResponseWriter, r *http.Request) { var users []model.SpaceUser - zitadel.GetOrganisationUsers(r.Header.Get("authorization"), space.OrganisationID, []string{authCtx.UserID}, nil) + zitadel.GetOrganisationGrants(r.Header.Get("authorization"), space.OrganisationID) renderx.JSON(w, http.StatusOK, users) } diff --git a/server/service/core/action/space/users/list.go b/server/service/core/action/space/users/list.go index 71558240..06d0b16c 100644 --- a/server/service/core/action/space/users/list.go +++ b/server/service/core/action/space/users/list.go @@ -66,7 +66,7 @@ func list(w http.ResponseWriter, r *http.Request) { users := make([]user, 0) for _, id := range uIDs { - for _, u := range res { + for _, u := range res.Result { if u.ID == id { users = append(users, user{ ID: u.ID, diff --git a/server/service/core/action/space/users/update.go b/server/service/core/action/space/users/update.go index 34fd4c77..59f8b942 100644 --- a/server/service/core/action/space/users/update.go +++ b/server/service/core/action/space/users/update.go @@ -37,7 +37,7 @@ func update(w http.ResponseWriter, r *http.Request) { return } - users, err := zitadel.GetOrganisationUsers(r.Header.Get("authorization"), authCtx.OrganisationID, req.IDs, nil) + orgsResult, err := zitadel.GetOrganisationUsers(r.Header.Get("authorization"), authCtx.OrganisationID, req.IDs, nil) if err != nil { loggerx.Error(err) @@ -45,7 +45,7 @@ func update(w http.ResponseWriter, r *http.Request) { return } - if len(users) != len(req.IDs) { + if int(orgsResult.Total) != len(req.IDs) { errorx.Render(w, errorx.Parser(errorx.DecodeError())) return } @@ -54,7 +54,7 @@ func update(w http.ResponseWriter, r *http.Request) { spaceUsers := make([]model.SpaceUser, 0) - for _, user := range users { + for _, user := range orgsResult.Result { spaceUsers = append(spaceUsers, model.SpaceUser{ SpaceID: authCtx.SpaceID, UserID: user.ID, diff --git a/server/service/core/action/user/list.go b/server/service/core/action/user/list.go index bacbfd16..a01330da 100644 --- a/server/service/core/action/user/list.go +++ b/server/service/core/action/user/list.go @@ -52,7 +52,7 @@ func list(w http.ResponseWriter, r *http.Request) { // Get organisation ID - res, err := zitadel.GetOrganisationUsers(r.Header.Get("authorization"), authCtx.OrganisationID, []string{}, nil) + res, err := zitadel.GetOrganisationGrants(r.Header.Get("authorization"), authCtx.OrganisationID) if err != nil { loggerx.Error(err) errorx.Render(w, errorx.Parser(errorx.DBError())) @@ -60,16 +60,16 @@ func list(w http.ResponseWriter, r *http.Request) { } result := paging{ - Total: int64(len(res)), + Total: res.Total, } users := make([]user, 0) - for _, u := range res { + for _, u := range res.Result { users = append(users, user{ - ID: u.ID, - DisplayName: u.Human.Profile.DisplayName, - Email: u.Human.Email.Email, + ID: u.UserID, + DisplayName: u.DisplayName, + Email: u.Email, }) } diff --git a/server/util/authors.go b/server/util/authors.go index 173a46be..e20f3269 100644 --- a/server/util/authors.go +++ b/server/util/authors.go @@ -10,7 +10,7 @@ func GetAuthors(token, orgID string, ids, userNames []string) (map[string]model. if token == "" { token = viper.GetString("ZITADEL_PERSONAL_ACCESS_TOKEN") } - zitadelUsers, err := zitadel.GetOrganisationUsers(token, orgID, ids, userNames) + res, err := zitadel.GetOrganisationUsers(token, orgID, ids, userNames) if err != nil { return nil, err @@ -18,7 +18,7 @@ func GetAuthors(token, orgID string, ids, userNames []string) (map[string]model. // Adding author authors := make(map[string]model.Author) - for _, zitadelUser := range zitadelUsers { + for _, zitadelUser := range res.Result { author := model.Author{ ID: zitadelUser.ID, DisplayName: zitadelUser.Human.Profile.DisplayName, diff --git a/server/util/zitadel/getOrganisationGrants.go b/server/util/zitadel/getOrganisationGrants.go new file mode 100644 index 00000000..6589732e --- /dev/null +++ b/server/util/zitadel/getOrganisationGrants.go @@ -0,0 +1,111 @@ +package zitadel + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "net/http" + "strconv" + + "github.com/factly/x/loggerx" + "github.com/spf13/viper" +) + +type OrganisationGrantsResponse struct { + Result []OrganisationGrant `json:"result"` + Details Details `json:"details"` +} + +type Details struct { + TotalResult string `json:"totalResult"` +} + +type OrganisationGrant struct { + UserID string `json:"userId"` + DisplayName string `json:"displayName"` + FirstName string `json:"firstName"` + LastName string `json:"lastName"` + Email string `json:"email"` + RoleKeys []string `json:"roleKeys"` +} + +type OrganisationGrants struct { + Result []OrganisationGrant `json:"result"` + Total int64 `json:"total"` +} + +func GetOrganisationGrants(token, orgID string) (OrganisationGrants, error) { + url := viper.GetString("zitadel_protocol") + "://" + viper.GetString("zitadel_domain") + "/management/v1/users/grants/_search" + method := "POST" + + payload := ZitadelQueryPayload{ + Query: Query{ + Offset: 0, + Asc: true, + }, + } + payload.Queries = make([]interface{}, 0) + + payload.Queries = append(payload.Queries, map[string]interface{}{ + "userTypeQuery": UserTypeQuery{ + Type: "TYPE_HUMAN", + }}) + + allOrgs := OrganisationGrants{} + resp := OrganisationGrantsResponse{} + + buf := new(bytes.Buffer) + json.NewEncoder(buf).Encode(payload) + + client := &http.Client{} + req, err := http.NewRequest(method, url, buf) + + if err != nil { + loggerx.Error(err) + return allOrgs, err + } + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + if token != "" { + req.Header.Add("Authorization", "Bearer "+getBearerToken(token)) + } else { + req.Header.Add("Authorization", "Bearer "+getBearerToken(viper.GetString("ZITADEL_PERSONAL_ACCESS_TOKEN"))) + } + + req.Header.Add("x-zitadel-orgid", orgID) + + res, err := client.Do(req) + if err != nil { + loggerx.Error(err) + return allOrgs, err + } + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + if err != nil { + fmt.Println(err) + return allOrgs, err + } + + err = json.Unmarshal(body, &resp) + if err != nil { + loggerx.Error(err) + return allOrgs, err + } + + allOrgs.Result = resp.Result + + // covert string to int64 + if resp.Details.TotalResult == "" { + return allOrgs, nil + } + + total, err := strconv.ParseInt(resp.Details.TotalResult, 10, 64) + if err != nil { + return allOrgs, err + } + allOrgs.Total = int64(total) + + return allOrgs, nil +} diff --git a/server/util/zitadel/getOrganisationUsers.go b/server/util/zitadel/getOrganisationUsers.go index e9ff8bc8..96958890 100644 --- a/server/util/zitadel/getOrganisationUsers.go +++ b/server/util/zitadel/getOrganisationUsers.go @@ -6,26 +6,33 @@ import ( "fmt" "io" "net/http" + "strconv" "github.com/factly/x/loggerx" "github.com/spf13/viper" ) -type OrganisationUsers struct { - Result []OrganisationUserResult `json:"result"` +type OrganisationUsersResponse struct { + Result []OrganisationUserResult `json:"result"` + Details Details `json:"details"` } type OrganisationUserResult struct { - ID string `json:"id"` + ID string `json:"userId"` Name string `json:"name"` PrimaryDomain string `json:"primaryDomain"` Human Human `json:"human"` } +type OrganisationUsers struct { + Result []OrganisationUserResult `json:"result"` + Total int64 `json:"total"` +} + type OrganisationUsersQuery struct { } -func GetOrganisationUsers(token, orgID string, userIDs, userNames []string) ([]OrganisationUserResult, error) { +func GetOrganisationUsers(token, orgID string, userIDs, userNames []string) (OrganisationUsers, error) { url := viper.GetString("zitadel_protocol") + "://" + viper.GetString("zitadel_domain") + "/v2/users" method := "POST" @@ -37,14 +44,17 @@ func GetOrganisationUsers(token, orgID string, userIDs, userNames []string) ([]O }, } + payload.Queries = make([]interface{}, 0) + payload.Queries = append(payload.Queries, map[string]interface{}{ + "typeQuery": UserTypeQuery{ + Type: "TYPE_HUMAN", + }}) + if len((userIDs)) != 0 { - payload.Queries = []Queries{ - { - InUserIdsQuery: InUserIdsQuery{ - UserIds: userIDs, - }, - }, - } + payload.Queries = append(payload.Queries, map[string]interface{}{ + "inUserIdsQuery": InUserIdsQuery{ + UserIds: userIDs, + }}) } if len((userNames)) != 0 { @@ -56,15 +66,16 @@ func GetOrganisationUsers(token, orgID string, userIDs, userNames []string) ([]O }, } } - payload.Queries = []Queries{ - { - OrQuery: OrQuery{ - Queries: userNamesQuery, - }, + payload.Queries = append(payload.Queries, map[string]interface{}{"orQuery": Queries{ + OrQuery: OrQuery{ + Queries: userNamesQuery, }, - } + }}) } + allOrgs := OrganisationUsers{} + resp := OrganisationUsersResponse{} + buf := new(bytes.Buffer) json.NewEncoder(buf).Encode(payload) @@ -73,34 +84,41 @@ func GetOrganisationUsers(token, orgID string, userIDs, userNames []string) ([]O if err != nil { loggerx.Error(err) - return []OrganisationUserResult{}, err + return allOrgs, err } req.Header.Add("Content-Type", "application/json") req.Header.Add("Accept", "application/json") - req.Header.Add("Authorization", "Bearer "+getBearerToken(token)) + req.Header.Add("Authorization", "Bearer "+viper.GetString("ZITADEL_PERSONAL_ACCESS_TOKEN")) res, err := client.Do(req) if err != nil { loggerx.Error(err) - return []OrganisationUserResult{}, err + return allOrgs, err } defer res.Body.Close() body, err := io.ReadAll(res.Body) if err != nil { fmt.Println(err) - return []OrganisationUserResult{}, err + return allOrgs, err } - allOrgs := OrganisationUsers{} - - err = json.Unmarshal(body, &allOrgs) + err = json.Unmarshal(body, &resp) if err != nil { loggerx.Error(err) - return []OrganisationUserResult{}, err + return allOrgs, err } - fmt.Println(string(body)) + // covert string to int64 + if resp.Details.TotalResult == "" { + return allOrgs, nil + } - return allOrgs.Result, nil + total, err := strconv.ParseInt(resp.Details.TotalResult, 10, 64) + if err != nil { + return allOrgs, err + } + allOrgs.Result = resp.Result + allOrgs.Total = int64(total) + return allOrgs, nil } diff --git a/server/util/zitadel/getOrganisations.go b/server/util/zitadel/getOrganisations.go index b39c82cb..8a55b6bf 100644 --- a/server/util/zitadel/getOrganisations.go +++ b/server/util/zitadel/getOrganisations.go @@ -18,8 +18,8 @@ type Query struct { } type ZitadelQueryPayload struct { - Query Query `json:"query"` - Queries []Queries `json:"queries"` + Query Query `json:"query"` + Queries []interface{} `json:"queries"` } type Result struct { @@ -33,8 +33,9 @@ type Organisations struct { } type Queries struct { - InUserIdsQuery InUserIdsQuery `json:"inUserIdsQuery"` - OrQuery OrQuery `json:"orQuery"` + InUsersIdsQuery InUserIdsQuery `json:"inUsersIdsQuery"` + UserTypeQuery UserTypeQuery `json:"userTypeQuery"` + OrQuery OrQuery `json:"orQuery"` } type InUserIdsQuery struct { @@ -45,6 +46,10 @@ type UserNamesQuery struct { UserName string `json:"userName"` } +type UserTypeQuery struct { + Type string `json:"type"` +} + type OrQuery struct { Queries []map[string]interface{} `json:"queries"` }