Skip to content

Commit c6b1736

Browse files
authored
Merge pull request #85 from ConductorOne/bugfix/user_provisioning
[BB-858] fix user provisioning existing user
2 parents bac8ab5 + b1c401b commit c6b1736

File tree

3 files changed

+66
-1
lines changed

3 files changed

+66
-1
lines changed

pkg/client/client.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ func (client *Client) ListAllRoles(ctx context.Context) ([]RolesAPIData, error)
298298
// GetUser
299299
// Returns specific users.
300300
func (client *Client) GetUser(ctx context.Context, userName string) (jira.User, error) {
301+
l := ctxzap.Extract(ctx)
301302
var usersAPIData []UsersAPIData
302303
req, err := getRequest(ctx, client, allUsersV2, Query{
303304
"username": userName,
@@ -308,16 +309,27 @@ func (client *Client) GetUser(ctx context.Context, userName string) (jira.User,
308309

309310
resp, err := client.httpClient.Do(req, uhttp.WithJSONResponse(&usersAPIData))
310311
if err != nil {
312+
l.Debug("error fetching user", zap.String("username", userName), zap.Error(err))
311313
return jira.User{}, err
312314
}
313315

314316
defer resp.Body.Close()
315317

316318
if len(usersAPIData) == 0 {
319+
l.Debug("user not found error", zap.String("username", userName))
317320
return jira.User{}, fmt.Errorf("%w: %s", ErrUserNotFound, userName)
318321
}
319322

323+
if len(usersAPIData) > 1 {
324+
l.Debug("multiple users found for username", zap.String("username", userName))
325+
return jira.User{}, fmt.Errorf("%w: more than one result for %s", ErrUserNotFound, userName)
326+
}
327+
320328
user := usersAPIData[0]
329+
if user.Name != userName && user.EmailAddress != userName {
330+
l.Debug("user not found error, no exact match for username", zap.String("username", userName))
331+
return jira.User{}, fmt.Errorf("%w: no exact match for username %s", ErrUserNotFound, userName)
332+
}
321333

322334
return jira.User{
323335
Self: user.Self,
@@ -374,6 +386,27 @@ func (client *Client) GetProjectRoles(ctx context.Context, projectId string) (ma
374386
return projectRolesAPIData, err
375387
}
376388

389+
func (client *Client) GetProjectRoleDetailsById(ctx context.Context, projectId string, roleId string) (*RolesAPIData, error) {
390+
var projectRoleDetailsAPIData RolesAPIData
391+
endpointUrl, err := url.JoinPath(allProjects, projectId, "role", roleId)
392+
if err != nil {
393+
return nil, err
394+
}
395+
396+
req, err := getRequest(ctx, client, endpointUrl, nil)
397+
if err != nil {
398+
return nil, err
399+
}
400+
401+
resp, err := client.httpClient.Do(req, uhttp.WithJSONResponse(&projectRoleDetailsAPIData))
402+
if err != nil {
403+
return nil, err
404+
}
405+
406+
defer resp.Body.Close()
407+
return &projectRoleDetailsAPIData, err
408+
}
409+
377410
// GetProjectRoleDetails
378411
// Returns all role details that are present in specific project.
379412
func (client *Client) GetProjectRoleDetails(ctx context.Context, urlApi string) (RolesAPIData, error) {

pkg/connector/project.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,22 @@ func (p *projectBuilder) Grant(ctx context.Context, principal *v2.Resource, enti
213213
return nil, err
214214
}
215215

216+
// // Verify the user is not already a member of the project role
217+
roleDetails, err := p.client.GetProjectRoleDetailsById(ctx, projectId, roleId)
218+
if err != nil {
219+
return nil, fmt.Errorf("failed to fetch role details, %w", err)
220+
}
221+
for _, actor := range roleDetails.Actors {
222+
if actor.Name == userName {
223+
l.Debug("Project Membership already exists.",
224+
zap.String("userName", userName),
225+
zap.String("projectId", projectId),
226+
zap.String("roleId", roleId),
227+
)
228+
return annotations.New(&v2.GrantAlreadyExists{}), nil
229+
}
230+
}
231+
216232
body := client.BodyActors{
217233
User: []string{
218234
userName,

pkg/connector/users.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,18 @@ func (u *userBuilder) CreateAccount(
165165
username = email
166166
}
167167

168-
if existingUser, err := u.client.GetUser(ctx, email); err == nil {
168+
existingUser, err := u.client.GetUser(ctx, username)
169+
if err != nil && username != email {
170+
// If the username is not found, try to get the user by email
171+
l.Debug("username not found, attempting to get user by email",
172+
zap.String("username", username),
173+
zap.String("email", email),
174+
zap.Error(err),
175+
)
176+
existingUser, err = u.client.GetUser(ctx, email)
177+
}
178+
179+
if err == nil {
169180
l.Info("user already exists in Jira DC, returning existing user resource",
170181
zap.String("email", email),
171182
zap.String("user_id", existingUser.Key),
@@ -177,6 +188,11 @@ func (u *userBuilder) CreateAccount(
177188
createdAccount = false
178189
username = existingUser.Name
179190
} else {
191+
l.Debug("user does not exist in Jira DC, creating new user",
192+
zap.String("email", email),
193+
zap.String("username", username),
194+
zap.Error(err),
195+
)
180196
firstName, _ := profile["first_name"].(string)
181197
lastName, _ := profile["last_name"].(string)
182198

0 commit comments

Comments
 (0)