Page MenuHomePhabricator

0001-wikitech-Un-block-GitLab-accounts-when-un-blocked-on.patch

Authored By
bd808
May 21 2024, 4:49 PM
Size
5 KB
Referenced Files
None
Subscribers
None

0001-wikitech-Un-block-GitLab-accounts-when-un-blocked-on.patch

From 20a6e1020214a919fa4a59784b96797d203402d3 Mon Sep 17 00:00:00 2001
From: Bryan Davis <bd808@wikimedia.org>
Date: Wed, 21 Feb 2024 16:24:26 -0700
Subject: [PATCH] wikitech: (Un)block GitLab accounts when (un)blocked on
wikitech
Block and unblock GitLab accounts when the associated Developer account
is blocked/unblocked on Wikitech.
Bug: T316418
Change-Id: Ia5fd3dc1f458d4d4d062ed6a31db71756b592efb
---
wmf-config/wikitech.php | 153 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 153 insertions(+)
diff --git a/wmf-config/wikitech.php b/wmf-config/wikitech.php
index 7c8b8a0c5..9d91e4f6d 100644
--- a/wmf-config/wikitech.php
+++ b/wmf-config/wikitech.php
@@ -84,6 +84,11 @@ $wmgPhabricatorApiToken = false;
$wmgGerritApiUser = false;
$wmgGerritApiPassword = false;
+// Dummy setting for GitLab api access to be used by the BlockIpComplete
+// hook that tries to disable GitLab accounts. Real value should be provided
+// by /etc/mediawiki/WikitechPrivateSettings.php
+$wmgGitLabApiToken = false;
+
# This must be loaded AFTER OSM, to overwrite it's defaults
# Except when we're not an OSM host and we're running like a maintenance script.
if ( file_exists( '/etc/mediawiki/WikitechPrivateSettings.php' ) ) {
@@ -460,3 +465,151 @@ $wgAuthManagerAutoConfig['secondaryauth'][DisallowLdapChangesSecondaryAuthentica
$wgHooks['GetPreferences'][] = static function ( $user, &$preferences ) {
unset( $preferences['emailauthentication'] );
};
+
+/**
+ * Make arbitrary API requests to the Wikimedia GitLab instance
+ *
+ * @param string $apiToken
+ * @param string $path
+ * @param array|null $query
+ * @param bool $postVerb
+ * @return mixed|false Result of the API request or false on error
+ */
+function wmfGitLabClient(
+ string $apiToken,
+ string $path,
+ $query = null,
+ $postVerb = false
+) {
+ $headers = [
+ "PRIVATE-TOKEN: {$apiToken}",
+ 'Content-Type: application/json',
+ ];
+ $gitlabUrl = 'https://gitlab.wikimedia.org';
+ $url = "{$gitlabUrl}/api/v4/{$path}";
+
+ if ( $query !== null ) {
+ $url = $url . '?' . http_build_query($query);
+ }
+
+ $ch = curl_init( $url );
+ curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
+ curl_setopt( $ch, CURLOPT_POST, $postVerb );
+ $ret = curl_exec( $ch );
+ $status = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
+ curl_close( $ch );
+ if ( $ret ) {
+ $resp = json_decode( $ret, true );
+ if ( $status >= 200 && $status <= 300 ) {
+ return $resp;
+ }
+ }
+ wfDebugLog(
+ 'WikitechGitLabBan',
+ "GitLab {$path} error " . var_export( $ret, true )
+ );
+ return false;
+}
+
+/**
+ * Lookup a GitLab account ID.
+ *
+ * @param string $apiToken
+ * @param string $cn Developer account username (LDAP `cn` attribute)
+ * @return int|null null on failure, or numeric account ID on success
+ */
+function wmfGitLabFindAccountId( string $apiToken, string $cn ) {
+ $resp = wmfGitLabClient(
+ $apiToken,
+ 'users',
+ [ 'provider' => 'openid_connect', 'extern_uid' => $cn ]
+ );
+ if ( $resp ) {
+ return $resp[ 0 ][ 'id' ];
+ }
+ return null;
+}
+
+$wgHooks['BlockIpComplete'][] = static function ( $block, $user, $prior ) use ( $wmgGitLabApiToken ) {
+ if ( !$wmgGitLabApiToken
+ // 1 is the value of Block::TYPE_USER
+ || $block->getType() !== 1
+ || $block->getExpiry() !== 'infinity'
+ || !$block->isSitewide()
+ ) {
+ // Nothing to do if we don't have config or if the block is not
+ // a site-wide indefinite block of a named user.
+ return;
+ }
+ try {
+ $userIdent = $block->getTargetUserIdentity();
+ if ( !$userIdent ) {
+ return;
+ }
+ $username = $userIdent->getName();
+ $gitlabId = wmfGitLabFindAccountId( $wmgGitLabApiToken, $username );
+ if ( $gitlabId === null ) {
+ return;
+ }
+
+ $resp = wmfGitLabClient(
+ $wmgGitLabApiToken,
+ "users/{$gitlabId}/block",
+ null,
+ true
+ );
+ if ( $resp !== false ) {
+ wfDebugLog(
+ 'WikitechGitLabBan',
+ "GitLab block of {$username} failed"
+ );
+ }
+ } catch ( Throwable $t ) {
+ wfDebugLog(
+ 'WikitechGitLabBan',
+ "Unhandled error blocking GitLab user: {$t}"
+ );
+ }
+};
+$wgHooks['UnblockUserComplete'][] = static function ( $block, $user ) use ( $wmgGitLabApiToken ) {
+ if ( !$wmgGitLabApiToken
+ // 1 is the value of Block::TYPE_USER
+ || $block->getType() !== 1
+ || $block->getExpiry() !== 'infinity'
+ || !$block->isSitewide()
+ ) {
+ // Nothing to do if we don't have config or if the block is not
+ // a site-wide indefinite block of a named user.
+ return;
+ }
+ try {
+ $userIdent = $block->getTargetUserIdentity();
+ if ( !$userIdent ) {
+ return;
+ }
+ $username = $userIdent->getName();
+ $gitlabId = wmfGitLabFindAccountId( $wmgGitLabApiToken, $username );
+ if ( $gitlabId === null ) {
+ return;
+ }
+
+ $resp = wmfGitLabClient(
+ $wmgGitLabApiToken,
+ "users/{$gitlabId}/unblock",
+ null,
+ true
+ );
+ if ( $resp !== false ) {
+ wfDebugLog(
+ 'WikitechGitLabBan',
+ "GitLab block of {$username} failed"
+ );
+ }
+ } catch ( Throwable $t ) {
+ wfDebugLog(
+ 'WikitechGitLabBan',
+ "Unhandled error unblocking GitLab user: {$t}"
+ );
+ }
+};
--
2.45.0

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17641881
Default Alt Text
0001-wikitech-Un-block-GitLab-accounts-when-un-blocked-on.patch (5 KB)

Event Timeline