github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/pkg/platform/model/organizations.go (about) 1 package model 2 3 import ( 4 "strings" 5 6 "github.com/go-openapi/strfmt" 7 "github.com/thoas/go-funk" 8 9 "github.com/ActiveState/cli/internal/errs" 10 "github.com/ActiveState/cli/internal/locale" 11 "github.com/ActiveState/cli/internal/logging" 12 "github.com/ActiveState/cli/pkg/platform/api" 13 "github.com/ActiveState/cli/pkg/platform/api/graphql" 14 "github.com/ActiveState/cli/pkg/platform/api/graphql/model" 15 "github.com/ActiveState/cli/pkg/platform/api/graphql/request" 16 clientOrgs "github.com/ActiveState/cli/pkg/platform/api/mono/mono_client/organizations" 17 "github.com/ActiveState/cli/pkg/platform/api/mono/mono_models" 18 "github.com/ActiveState/cli/pkg/platform/authentication" 19 ) 20 21 var ErrMemberNotFound = errs.New("member not found") 22 23 // FetchOrganizations fetches all organizations for the current user. 24 func FetchOrganizations(auth *authentication.Auth) ([]*mono_models.Organization, error) { 25 authClient, err := auth.Client() 26 if err != nil { 27 return nil, errs.Wrap(err, "Could not get auth client") 28 } 29 params := clientOrgs.NewListOrganizationsParams() 30 memberOnly := true 31 params.SetMemberOnly(&memberOnly) 32 res, err := authClient.Organizations.ListOrganizations(params, auth.ClientAuth()) 33 34 if err != nil { 35 return nil, processOrgErrorResponse(err) 36 } 37 38 return res.Payload, nil 39 } 40 41 // FetchOrgByURLName fetches an organization accessible to the current user by it's URL Name. 42 func FetchOrgByURLName(urlName string, auth *authentication.Auth) (*mono_models.Organization, error) { 43 authClient, err := auth.Client() 44 if err != nil { 45 return nil, errs.Wrap(err, "Could not get auth client") 46 } 47 params := clientOrgs.NewGetOrganizationParams() 48 params.OrganizationIdentifier = urlName 49 resOk, err := authClient.Organizations.GetOrganization(params, auth.ClientAuth()) 50 if err != nil { 51 return nil, processOrgErrorResponse(err) 52 } 53 return resOk.Payload, nil 54 } 55 56 // FetchOrgMembers fetches the members of an organization accessible to the current user by it's URL Name. 57 func FetchOrgMembers(urlName string, auth *authentication.Auth) ([]*mono_models.Member, error) { 58 authClient, err := auth.Client() 59 if err != nil { 60 return nil, errs.Wrap(err, "Could not get auth client") 61 } 62 params := clientOrgs.NewGetOrganizationMembersParams() 63 params.OrganizationName = urlName 64 resOk, err := authClient.Organizations.GetOrganizationMembers(params, auth.ClientAuth()) 65 if err != nil { 66 return nil, processOrgErrorResponse(err) 67 } 68 return resOk.Payload, nil 69 } 70 71 // FetchOrgMember fetches the member of an organization accessible to the current user by it's URL Name. 72 func FetchOrgMember(orgName, name string, auth *authentication.Auth) (*mono_models.Member, error) { 73 members, err := FetchOrgMembers(orgName, auth) 74 if err != nil { 75 return nil, err 76 } 77 78 for _, member := range members { 79 if strings.EqualFold(name, member.User.Username) { 80 return member, nil 81 } 82 } 83 84 return nil, locale.WrapError(ErrMemberNotFound, "err_api_member_not_found") 85 } 86 87 // InviteUserToOrg invites a single user (via email address) to a given 88 // organization. 89 // 90 // # The invited user can be added as an owner or a member 91 // 92 // Note: This method only returns the invitation for the new user, not existing 93 // users. 94 func InviteUserToOrg(orgName string, asOwner bool, email string, auth *authentication.Auth) (*mono_models.Invitation, error) { 95 authClient, err := auth.Client() 96 if err != nil { 97 return nil, errs.Wrap(err, "Could not get auth client") 98 } 99 params := clientOrgs.NewInviteOrganizationParams() 100 role := mono_models.RoleReader 101 if asOwner { 102 role = mono_models.RoleAdmin 103 } 104 body := clientOrgs.InviteOrganizationBody{ 105 AddedOnly: true, 106 Role: &role, 107 } 108 params.SetOrganizationName(orgName) 109 params.SetAttributes(body) 110 params.SetEmail(email) 111 resOk, err := authClient.Organizations.InviteOrganization(params, auth.ClientAuth()) 112 if err != nil { 113 return nil, processInviteErrorResponse(err) 114 } 115 if len(resOk.Payload) != 1 { 116 return nil, locale.NewError("err_api_org_invite_expected_one_invite") 117 } 118 return resOk.Payload[0], nil 119 120 } 121 122 // FetchOrganizationsByIDs fetches organizations by their IDs 123 func FetchOrganizationsByIDs(ids []strfmt.UUID, auth *authentication.Auth) ([]model.Organization, error) { 124 ids = funk.Uniq(ids).([]strfmt.UUID) 125 request := request.OrganizationsByIDs(ids) 126 127 gql := graphql.New(auth) 128 response := model.Organizations{} 129 err := gql.Run(request, &response) 130 if err != nil { 131 return nil, errs.Wrap(err, "gql.Run failed") 132 } 133 134 if len(response.Organizations) != len(ids) { 135 logging.Debug("Organization membership mismatch: %d members returned for %d members requested. Caller must account for this.", len(response.Organizations), len(ids)) 136 } 137 138 return response.Organizations, nil 139 } 140 141 func processOrgErrorResponse(err error) error { 142 switch statusCode := api.ErrorCode(err); statusCode { 143 case 401: 144 return locale.NewExternalError("err_api_not_authenticated") 145 case 404: 146 return locale.NewExternalError("err_api_org_not_found") 147 default: 148 return err 149 } 150 } 151 152 func processInviteErrorResponse(err error) error { 153 switch statusCode := api.ErrorCode(err); statusCode { 154 case 400: 155 return locale.WrapExternalError(err, "err_api_invite_400", "Invalid request, did you enter a valid email address?") 156 case 401: 157 return locale.NewExternalError("err_api_not_authenticated") 158 case 404: 159 return locale.NewExternalError("err_api_org_not_found") 160 default: 161 return locale.WrapError(err, api.ErrorMessageFromPayload(err)) 162 } 163 }