Page MenuHomePhabricator

Figure out workflow for programatically adding GitLab users
Closed, ResolvedPublic3 Estimated Story Points

Description

As part of our migration to GitLab (from Differential and from Gerrit) we'll need to create users.

Striker will need this so we can create a repo in GitLab and give a user owner permissions on that repo.

While GitLab supports API user creation there is a problem with creating ldap users in GitLab before their first login. There may be workarounds or other possibilities for a smooth workflow.

Acceptance criteria

  • Evaluation of user creation possibilities
  • Workflow design

Event Timeline

I wrote this horrible POC client for creating accounts via the API:

attach-gitlab-user.py
#!/usr/bin/env python3
# SPDX: GPL-3.0-or-later
import argparse
import json
import requests


parser = argparse.ArgumentParser(description="Attach a user to gitlab")
parser.add_argument("--uid", help="LDAP uid (shellname)", required=True)
parser.add_argument("--cn", help="LDAP cn (wiki name)", required=True)
parser.add_argument("--email", help="Email address", required=True)
parser.add_argument("--token", help="Admin account API token", required=True)
parser.add_argument("--url", help="Server URL", default="https://gitlab.wikimedia.org")
args = parser.parse_args()

session = requests.Session()
headers = {
    "PRIVATE-TOKEN": args.token,
    "Content-Type": "application/json",
}
payload = {
    "provider": "cas3",
    "extern_uid": args.uid,
    "username": args.uid,
    "name": args.cn,
    "email": args.email,
    "force_random_password": True,
    "note": "Created via API"
}
r = session.request(
    method="POST",
    url="{0}/api/v4/users".format(args.url),
    json=payload,
    headers=headers,
)
print(r)

Using this script I created the account for one of my testing Developer accounts:

$ ./attach-gitlab-user.py --uid unicodetest --email 'bdavis+T229227@wikimedia.org' --cn 'Tést őf Unícødë įn Usērnǎmė' --token 'not going to leak this value ;)'

This API call succeeded (but I didn't capture the API output). The gitlab server also sent me a "Confirmation instructions" email with a link to verify the email address. When I authenticated to gitlab via CAS I was met with a screen telling me that I needed to verify my email before I could finish logging in. Once I did that via the emailed link, I was able to authenticate successfully.

Having logged in, I wanted to see if I could setup 2FA for the account. This is the part that is said not to work for LDAP accounts created via the API in the upstream bug https://gitlab.com/gitlab-org/gitlab/-/issues/699.

I was able to both enable and later disable TOTP based 2FA for the account with no issues.

As another test, I created an account directly via CAS login. This allowed me to confirm that the email passed from CAS is trusted by gitlab without the confirmation email link being involved. It would be ideal for our API based creation to work in the same way, but we can probably live with the confirmation email workflow if we can't find a way around it.

I think this task can be resolved as we did figure out what the workflow itself will be -- we just need to create an account via a call to the API. For existing tools this will be done en masse, for new tools I'm guessing some work in tools/views/repo.py will need doing. I think that can be tracked easily enough in the parent task, T296893.

See https://gitlab.wikimedia.org/bd808/pre-account-creation-invite-test for another way this could be handled. The email that is sent when inviting an email address to join a project makes a lot more sense than the email sent prompting for email verification when a CAS account is attached without authenticating. The trade off is that the workflow is broken when using the invite link and authenticating via CAS. The invite URL must be used twice currently and of course there is no notification of that need.

I think this is actually what I'm going to use for the Striker changes because the notif email that is sent makes more sense and looks less like some kind of random phishing. Both methods have workflow drawbacks unfortunately.