Skip to content

Commit c442be4

Browse files
authored
Merge branch 'master' into update-gitlab-php-client
2 parents d2f08c8 + 00ea572 commit c442be4

6 files changed

Lines changed: 1128 additions & 545 deletions

File tree

README.md

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
1-
# LDAP users and groups sync script for Gitlab-CE and Gitlab-EE
1+
# LDAP users and groups sync script for GitLab-CE and GitLab-EE
22

3-
This nifty little PHP-CLI tool will synchronise users and user groups from an LDAP server to Gitlab community edition instance(s). This also works on enterprise editions on the free tier, of which has identical functionality to the community edition.
3+
This nifty little PHP-CLI tool will synchronise users and user groups from an LDAP server to GitLab community edition instance(s). This also works on enterprise editions on the free tier, of which has identical functionality to the community edition.
44

5-
Though this functionality is available out of the box with (non-free) Gitlab enterprise edition the pricing model is completely infeasible for teams of hobbyists working on non-revenue based projects but need to use a centralised authentication base.
5+
Though this functionality is available out of the box with (non-free) GitLab enterprise edition the pricing model is completely infeasible for teams of hobbyists working on non-revenue based projects but need to use a centralised authentication base.
66

7-
As a bonus it can also do a light rake of LDAP users not currently in Gitlab, so those that haven't signed in for their first time can still have projects and permissions assigned to them. **This may make the tool unsuitable git Gitlab-EE as this would certainly impact its licensing fees!**
7+
As a bonus it can also do a light rake of LDAP users not currently in GitLab, so those that haven't signed in for their first time can still have projects and permissions assigned to them. **This may make the tool unsuitable git GitLab-EE as this would certainly impact its licensing fees!**
88

99
## **This tool has had basic community quality assurance.**
1010

1111
**Use in production environment at your own risk.**
1212

13-
Though all of this tool's features are now implemented, very limited testing has happened, so don't expect a perfect experience. You should therefore only use this on test Gitlab CE/EE instances, or if you must use this on your production environment, at the very least take a backup of your Gitlab data before using this.
13+
Though all of this tool's features are now implemented, very limited testing has happened, so don't expect a perfect experience. You should therefore only use this on test GitLab CE/EE instances, or if you must use this on your production environment, at the very least take a backup of your GitLab data before using this.
1414

1515
Features implemented:
1616

1717
* Reading users from LDAP
1818
* Reading groups from LDAP
19-
* Synchronising users to Gitlab
20-
* Synchronising groups to Gitlab
21-
* Synchronising Gitlab group memberships based on LDAP group memberships
19+
* Synchronising users to GitLab
20+
* Synchronising groups to GitLab
21+
* Synchronising GitLab group memberships based on LDAP group memberships
2222

2323
Not implemented:
2424

2525
* Sub-group handling
26-
* ~~SSH key importing *(in progress)*~~: No longer required: Gitlab has a [native configuration option](https://docs.gitlab.com/ee/administration/auth/ldap/#ldap-sync-configuration-settings) "sync_ssh_keys" to specify a user attribute to synchronise keys from.
26+
* ~~SSH key importing *(in progress)*~~: No longer required: GitLab has a [native configuration option](https://docs.gitlab.com/ee/administration/auth/ldap/#ldap-sync-configuration-settings) "sync_ssh_keys" to specify a user attribute to synchronise keys from.
2727

28-
If in doubt use the dry run `-d` option to prevent writing to Gitlab first, combined with `-vv` to see exactly what would happen.
28+
If in doubt use the dry run `-d` option to prevent writing to GitLab first, combined with `-vv` to see exactly what would happen.
2929

3030
**You have been warned!**
3131

@@ -38,15 +38,15 @@ These instructions will get you a copy of the project up and running on your loc
3838
Requirements for running this tool from a management station:
3939

4040
* Any system that can run PHP-CLI will do. (Even Windows.)
41-
* [PHP](https://www.php.net) version 8.1 or later: Available to most Linux distributions via `apt-get` or `yum`/`dnf`. You don't need anything web related, but you will need the command line interface.
41+
* [PHP](https://www.php.net) version 8.2 or later: Available to most Linux distributions via `apt-get` or `yum`/`dnf`. You don't need anything web related, but you will need the command line interface.
4242
* [PHP's LDAP functions](http://php.net/manual/en/book.ldap.php): Usually installed with PHP as standard, but the LDAP module/functions may not be enabled by default.
4343
* [Composer](https://getcomposer.org/): Available to most Linux distributions via `apt-get` or `yum`/`dnf`, or manually download it as `composer.phar` alongside this tool.
44-
* LDAP instance: Used for Gitlab's authentication. It can (likely) be Microsoft Active Directory, OpenLDAP, 389-DS (including FreeIPA), and any other LDAP system, though **most of my testing is with 389-DS (without FreeIPA)**.
45-
* [Gitlab community edition](https://about.gitlab.com/install/?version=ce) or [Gitlab community edition](https://about.gitlab.com/install/?version=ee) self-hosted: This must be configured to authenticate against an LDAP instance already.
44+
* LDAP instance: Used for GitLab's authentication. It can (likely) be Microsoft Active Directory, OpenLDAP, 389-DS (including FreeIPA), and any other LDAP system, though **most of my testing is with 389-DS (without FreeIPA)**.
45+
* [GitLab community edition](https://about.gitlab.com/install/?version=ce) or [GitLab community edition](https://about.gitlab.com/install/?version=ee) self-hosted: This must be configured to authenticate against an LDAP instance already.
4646

4747
## Installing
4848

49-
Either checkout this project or download it in ZIP form and extract it somewhere safe. The configuration will later contain an LDAP password and Gitlab API secret keys, so do put some protection in place to ensure only you can access it.
49+
Either checkout this project or download it in ZIP form and extract it somewhere safe. The configuration will later contain an LDAP password and GitLab API secret keys, so do put some protection in place to ensure only you can access it.
5050

5151
After this you will need to install PHP components delivered via [Composer](https://getcomposer.org/). To do this open a terminal and change the working directory to this tool's location. (Or add the `-d`/`--working-dir=` option to run from another working directory.)
5252

@@ -154,15 +154,15 @@ Default: "(objectClass=inetOrgPerson)"
154154

155155
##### userUniqueAttribute *(string|null)*
156156

157-
Specify the attribute used to uniquely identify a user by their user name. Their values must be a simple name of which the user would typically type to login to Gitlab or any other application interfacing with the same directory.
157+
Specify the attribute used to uniquely identify a user by their user name. Their values must be a simple name of which the user would typically type to login to GitLab or any other application interfacing with the same directory.
158158

159159
Default: "uid"
160160

161161
##### userMatchAttribute *(string|null)*
162162

163163
By default, it is assumed that the **userUniqueAttribute** is a user name that can be used to unambiguously determine group membership of individual persons as well as being used for login credentials. If this is the case with your LDAP structure, set **userMatchAttribute** to be empty.
164164

165-
If that is not the case, **userMatchAttribute** can be used to separate these two functions. Specify **userMatchAttribute** to the feature of your user that determines his membership in a group and **userUniqueAttribute** to the user name attribute used for Gitlab login credentials. For instance, in some Microsoft Active Directory versions, groups possess a "member" attribute that lists the "distinguishedName" attributes of each member of the group. The user name however is a different attribute of each user being attributed to that group. In this case, set **userMatchAttribute** to "distinguishedName" and **userUniqueAttribute** to your user name attribute.
165+
If that is not the case, **userMatchAttribute** can be used to separate these two functions. Specify **userMatchAttribute** to the feature of your user that determines his membership in a group and **userUniqueAttribute** to the user name attribute used for GitLab login credentials. For instance, in some Microsoft Active Directory versions, groups possess a "member" attribute that lists the "distinguishedName" attributes of each member of the group. The user name however is a different attribute of each user being attributed to that group. In this case, set **userMatchAttribute** to "distinguishedName" and **userUniqueAttribute** to your user name attribute.
166166

167167
This attribute only makes sense if **groupMemberAttribute** is "memberUid".
168168

@@ -220,7 +220,7 @@ Default: "memberUid"
220220

221221
### gitlab
222222

223-
This section configures how to communicate with your Gitlab-CE/EE instance.
223+
This section configures how to communicate with your GitLab-CE/EE instance.
224224

225225
#### options
226226

@@ -242,7 +242,7 @@ userNamesToIgnore:
242242
- "Guest"
243243
```
244244
245-
User name "root" will always be ignored because this is the built-in Gitlab root user. This tool will not attempt to create/delete/sync this user name.
245+
User name "root" will always be ignored because this is the built-in GitLab root user. This tool will not attempt to create/delete/sync this user name.
246246
247247
Default: *null*
248248
@@ -264,25 +264,25 @@ groupNamesToIgnore:
264264
- "Marketing Staff"
265265
```
266266
267-
Group names "Root" and "Users" will always be ignored because they are built-in Gitlab groups. This will will not attempt to create/delete/sync these group names.
267+
Group names "Root" and "Users" will always be ignored because they are built-in GitLab groups. This will will not attempt to create/delete/sync these group names.
268268
269269
Default: *null*
270270
271271
##### createEmptyGroups *(bool|null)*
272272
273-
Specify whether groups containing no LDAP users should still be created in Gitlab.
273+
Specify whether groups containing no LDAP users should still be created in GitLab.
274274
275-
You should enable this if you want to specify permissions for groups in advance so they'll be ready when the first user is added to that group. If your directory has a lot of empty groups enabling this would only replicate the clutter to Gitlab, so should be used with care for large directories.
275+
You should enable this if you want to specify permissions for groups in advance so they'll be ready when the first user is added to that group. If your directory has a lot of empty groups enabling this would only replicate the clutter to GitLab, so should be used with care for large directories.
276276
277277
Default: *false*
278278
279279
##### deleteExtraGroups *(bool|null)*
280280
281-
Specify whether Gitlab groups not found in LDAP should be deleted.
281+
Specify whether GitLab groups not found in LDAP should be deleted.
282282
283-
You should only enable this if you don't like empty groups being left over in Gitlab after doing a purge in your directory. Consider if such groups still contain projects you need to keep. (This scenario remains untested!)
283+
You should only enable this if you don't like empty groups being left over in GitLab after doing a purge in your directory. Consider if such groups still contain projects you need to keep. (This scenario remains untested!)
284284
285-
Only empty Gitlab groups will ever be deleted. If there are extra groups with members still in them they will not be deleted.
285+
Only empty GitLab groups will ever be deleted. If there are extra groups with members still in them they will not be deleted.
286286
287287
Default: *false*
288288
@@ -296,15 +296,15 @@ The access level to provide users when added to groups.
296296
* 40: Maintainer
297297
* 50: Owner
298298
299-
This will not interfere with existing group members, so you can adjust user permissions in Gitlab later on.
299+
This will not interfere with existing group members, so you can adjust user permissions in GitLab later on.
300300
301301
Default: 30
302302
303303
##### groupNamesOfAdministrators *(array|null)*
304304
305305
Specify a list of group names of which members should be granted administrator access.
306306
307-
This varies not only according to which directory software you're using, but also how your directory has been structured. Users that have directory administrator access may not necessarily have Gitlab administrator access too, so this one is up to you.
307+
This varies not only according to which directory software you're using, but also how your directory has been structured. Users that have directory administrator access may not necessarily have GitLab administrator access too, so this one is up to you.
308308
309309
* For Microsoft Active Directory this is could be "Domain Admins" and "Enterprise Admins".
310310
* OpenLDAP and 389-DS do not ship with such a group out of the box as they typically offer a "Directory Administrator" non-user object or similar for administrative purposes via bind DN.
@@ -340,23 +340,23 @@ Default: *null*
340340
341341
#### instances *(array)*
342342
343-
Declare one or more Gitlab instances to sync with. Each array key represents the instance name, which can be used later on to only sync with a particular instance (out of multiple) when running this tool.
343+
Declare one or more GitLab instances to sync with. Each array key represents the instance name, which can be used later on to only sync with a particular instance (out of multiple) when running this tool.
344344
345345
##### your-instance-name-here *(array)*
346346
347-
Make up an instance name. For example if you had multiple Gitlab installations on servers named "Athena" and "Demeter" it would be sensible to tag them as "athena" and "demeter" in your configuration. All sub-sections of this configuration will be repeated for each instance.
347+
Make up an instance name. For example if you had multiple GitLab installations on servers named "Athena" and "Demeter" it would be sensible to tag them as "athena" and "demeter" in your configuration. All sub-sections of this configuration will be repeated for each instance.
348348
349349
###### url *(string)*
350350
351-
Specify the full HTTP/HTTPS URL to this Gitlab instance, e.g. "https://athena.gitlab.example.com" or "https://demeter.gitlab.example.com". This is the same URL you use to really visit this Gitlab installation from your web browser.
351+
Specify the full HTTP/HTTPS URL to this GitLab instance, e.g. "<https://athena.gitlab.example.com>" or "<https://demeter.gitlab.example.com>". This is the same URL you use to really visit this GitLab installation from your web browser.
352352
353353
###### token *(string)*
354354
355-
Specify an API token (usually a personal token or impersonation token) this tool can use to interface with the Gitlab instance's API. This token will need to have the "api" and "sudo" flags available.
355+
Specify an API token (usually a personal token or impersonation token) this tool can use to interface with the GitLab instance's API. This token will need to have the "api" and "sudo" flags available.
356356
357357
###### ldapServerName *(string)*
358358
359-
Specify the LDAP server name used by this Gitlab instance. You can find this in the "ldap_servers" section of the "gitlab.rb" configuration file, which represents an array of data specifying how to interface with LDAP such as server host address, bind DN, encryption, base, etc.
359+
Specify the LDAP server name used by this GitLab instance. You can find this in the "ldap_servers" section of the "gitlab.rb" configuration file, which represents an array of data specifying how to interface with LDAP such as server host address, bind DN, encryption, base, etc.
360360
361361
**You may need to put "ldap" before this value!** This hasn't been tested across different installation types, but using the Omnibus package it appears if your "gitlab.rb" has the following...
362362
@@ -380,7 +380,7 @@ php bin/console ldap:sync -d
380380

381381
Depending on your system's PHP installation you may need to use `php-cli` instead of `php`. (This typically only occurs on WHM/cPanel based servers configured to host PHP via the fast process manager, PHP-FPM.)
382382

383-
**The `-d` option is important for your first run.** This enables "dry run" mode, meaning no changes will be persisted to your Gitlab instances. After running this tool you should evaluate the changes that will be made based on the output, then run it again without the `-d` option to persist the changes.
383+
**The `-d` option is important for your first run.** This enables "dry run" mode, meaning no changes will be persisted to your GitLab instances. After running this tool you should evaluate the changes that will be made based on the output, then run it again without the `-d` option to persist the changes.
384384

385385
If you'd like to see more verbose output you can add up to 3 `-v` switches, for example:
386386

@@ -390,7 +390,7 @@ php bin/console ldap:sync -vv
390390
php bin/console ldap:sync -vvv
391391
```
392392

393-
If you'd like to only sync with a single Gitlab instance you can specify the name of it as per your configuration as an argument, for example:
393+
If you'd like to only sync with a single GitLab instance you can specify the name of it as per your configuration as an argument, for example:
394394

395395
```console
396396
php bin/console ldap:sync athena
@@ -410,10 +410,10 @@ PHP source code must comply with [PHP-FIG PSRs](https://www.php-fig.org/psr/) 1,
410410

411411
### Potential features
412412

413-
* Specifying an attribute on the LDAP user in which this script could write back a user ID for each Gitlab instance.
413+
* Specifying an attribute on the LDAP user in which this script could write back a user ID for each GitLab instance.
414414
* This would mean user name (UID) changes in LDAP could be detected and synchronised automatically without user duplication happening.
415415
* It would likely be a string attribute in the form of `instanceName:userId`, for example `athena:3` and `demeter:15`.
416-
* It could either be a multi-value attribute to handle multiple Gitlab instances, or a single-value attribute split by a semi-colon, for example `athena:3;demeter:15`.
416+
* It could either be a multi-value attribute to handle multiple GitLab instances, or a single-value attribute split by a semi-colon, for example `athena:3;demeter:15`.
417417
* Likely the same as the above but for groups too. (Group renaming.)
418418

419419
## Versioning

bin/console

100644100755
File mode changed.

composer.json

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,35 @@
11
{
22
"name": "adam-reece/gitlab-ce-ldap-group-sync",
3+
"description": "PHP-CLI tool to synchronise users and user groups from an LDAP server to GitLab community edition instance(s).",
34
"type": "project",
45
"license": "Apache-2.0",
6+
"keywords": [
7+
"gitlab",
8+
"ldap"
9+
],
510
"require": {
611
"php": ">=8.1",
7-
"cocur/slugify": "^4.6.0",
8-
"http-interop/http-factory-guzzle": "^1.2",
12+
"cocur/slugify": "^4.7.1",
13+
"http-interop/http-factory-guzzle": "^1.2.1",
914
"m4tthumphrey/php-gitlab-api": "^12.1.0",
10-
"monolog/monolog": "^3.9.0",
15+
"monolog/monolog": "^3.10.0",
1116
"php-http/guzzle6-adapter": "^2.0.2",
12-
"symfony/console": "^6.4.27",
13-
"symfony/polyfill-php82": "^1.33.0",
14-
"symfony/polyfill-php83": "^1.33.0",
15-
"symfony/polyfill-php84": "^1.33.0",
16-
"symfony/polyfill-php85": "^1.33.0",
17-
"symfony/yaml": "^6.4.26"
17+
"symfony/console": "^6.4.39",
18+
"symfony/polyfill-php82": "^1.37.0",
19+
"symfony/polyfill-php83": "^1.37.0",
20+
"symfony/polyfill-php84": "^1.37.0",
21+
"symfony/polyfill-php85": "^1.37.0",
22+
"symfony/yaml": "^6.4.38"
1823
},
1924
"require-dev": {
20-
"phpstan/phpstan": "^2.1.28",
21-
"phpstan/phpstan-symfony": "^2.0.8"
25+
"phpstan/phpstan": "^2.1.54",
26+
"phpstan/phpstan-deprecation-rules": "^2.0.4",
27+
"phpstan/phpstan-strict-rules": "^2.0.11",
28+
"phpstan/phpstan-symfony": "^2.0.17"
2229
},
2330
"autoload": {
2431
"psr-4": {
25-
"AdamReece\\GitlabCeLdapGroupSync\\": "src"
32+
"AdamReece\\GitLabCeLdapGroupSync\\": "src"
2633
},
2734
"classmap": ["src"]
2835
},
@@ -31,5 +38,11 @@
3138
"allow-plugins": {
3239
"php-http/discovery": true
3340
}
34-
}
41+
},
42+
"scripts": {
43+
"launch": "bin/console ldap:sync",
44+
"stan": "phpstan analyse"
45+
},
46+
"minimum-stability": "stable",
47+
"prefer-stable": true
3548
}

0 commit comments

Comments
 (0)