Jira - User-Migration zwischen Authentifizierungs-Directories

Im Rahmen der Einführung von jira als Issue-Tracking-System habe ich zu Anfangs neue Useraccounts unter Verwendung des lokalen Jira User Directories zu Authentifizierungszwecken angelegt.

Wie aber nun mal so der Lauf der Dinge ist wächst die Anwenderanzahl ebenso stetig wie die Frage nach der Anbindung eines zentralen Authentifizierungssystems ala LDAP oder AD :-). Aktuellere Versionen von Jira bieten ein Feature mit dem man alle Benutzer eines Authentifizierungsdirectories in ein anderes überführen kann, allerdings kann von dieser Option auf Grund eines gemischten Anwenderkreises  (lokale/externe User) nicht Gebrauch gemacht werden.

Daher im Folgenden eine kurze Beschreibung, wie man ein "Delegated LDAP Authentication Directory" einrichtet (in meinem Fall ein AD Server) und bestehende Accounts dahin migriert.

Zu Beginn legt man den entsprechenden Eintrag unterhalb der Konfiguration der User Directories an.

Bei der Auswahl des Typs wählt man "Internal with LDAP Authentication"

und spezifiziert im folgenden Fenster die entsprechenden Konfigurationsparameter. Ein Hinweis an dieser Stelle, ist die AD-Struktur relativ groß bzw. tief verschachtelt, und man wählt eine Base-DB auf einer oberen Ebene, so kann die Suche ggf. relativ lange dauern und zu Timeouts beim Anmelden in Jira führen. In diesem Fall (wie es bei mir nötig war :-)) ist es ratsam mehrere User-Directories mit feiner spezifizierten Base-DB anzulegen.

Sprich statt

DC=mobux,DC=DE

lieber

OU=Development,DC=mobux,DC=de

Um nun das Authentifizierungsschema an das neue Directory zu binden, muß man folgende Anpassungen in der Jira Datenbank vornehmen. Wichtig hierbei ist, daß man die Jira-Instanz anhalten sollte bevor man beginnt, um konkurrierende Einträge und Probleme durch das Jira-Interne Caching zu vermeiden.

  • Spezifizieren des Accountnamen der migriert werden soll. Da wir den Namen an mehreren Stellen brauchen, hinterlegen wir ihn sql-seitig in einer Variablen.
SELECT @username := "ktklin";
  • Ermitteln der ID des neu angelegten Authentifizierungsdirectory. Innerhalb der Jira-DB sind die Infos bzgl. der Authentifizierungsmöglichkeiten in erster Linie in den Tabellen cwd_directory und cwd_directory_attribute hinterlegt. Obwohl es an sich ausreichen würde, die directory_id (basierend auf der entsprechenden Where-Clause) aus der cwd_directory_attribute Tabelle zu ermitteln, joine ich die cwd_directory Tabelle mit dazu, sicher ist sicher :-)
SELECT @directory_id := cw.id
FROM cwd_directory cw, cwd_directory_attribute cwa  
WHERE cw.directory_type='delegating' 
AND cw.id = cwa.directory_id 
AND cwa.attribute_name = "ldap.basedn" 
AND cwa.attribute_value= "OU=XXX,DC=YYY,DC=ZZZ";
  • Jira verwaltet Gruppenzugehörigkeiten pro Authentifizierungs-Directory, sprich wir müssen für unser neu angelegtes Verzeichnis entsprechende Zeilen erzeugen. Hierzu erzeugen wir als erstes eine Kopie der Tabelle cwd_group, die alle Einträge enthät, die am Jira-Internen-Directory hängen
CREATE TABLE cwd_group_help 
SELECT * FROM cwd_group 
WHERE directory_id = 1;
  • Setzen der directory_id in der Hilfstabelle auf den ermittelten Wert
UPDATE cwd_group_help 
SET directory_id = @directory_id;
  • Nachdem die Tabelle cwd_group für die Spalte id nicht mit dem Autoincrement Feature arbeitet, müssen wir uns darum kümmern, sprich in der Hilfstabelle wird die ID auf Werte höher des Maxwertes gesetzt.
SELECT @i:=max(id) 
FROM cwd_group;
UPDATE cwd_group_help 
SET id = @i:=@i+1;
  • Die neuen Einträge werden zurück in die Tabelle cwd_group überführt
INSERT INTO cwd_group
SELECT * FROM cwd_group_help
WHERE cwd_group_help.group_name NOT IN (SELECT group_name FROM cwd_group WHERE directory_id = @directory_id);
  • Für die entsprechenden Anwender wird das directory auf die ermittelte Variante umgestellt (in der Tabelle cwd_user & cwd_user_attribute)
UPDATE cwd_user 
SET directory_id=@directory_id 
WHERE user_name = @username;
UPDATE cwd_user_attributes 
SET directory_id=@directory_id 
WHERE user_id IN (SELECT id FROM cwd_user WHERE user_name = @username);
  • Aktualisieren der Gruppenzugehörigkeit. Basierend auf unseren neuen Enträgen in der cwd_group und der ermittelten DirectoryID werden die Mitgliedschaftsinfos des User aktualisiert.
UPDATE cwd_membership, cwd_group 
SET cwd_membership.parent_id = cwd_group.id,
    cwd_membership.directory_id = @directory_id
WHERE cwd_membership.lower_parent_name = cwd_group.lower_group_name
AND cwd_membership.child_id IN (SELECT id FROM cwd_user WHERE user_name = @username) 
AND cwd_group.directory_id = @directory_id;
  • Nachdem Jira die maximale Gruppen-ID nicht aus der Tabelle cwd_group ermittelt, sondern in der SEQUENCE_VALUE_ITEM Tabelle hinterlegt, müssen wir diese ebenfalls pflegen, da sonst die reguläre Neuanlage von Gruppen zu einem Primary-Key Fehler führt
UPDATE sequence_value_item 
SET seq_id = (SELECT MAX(id)+1 FROM cwd_group) 
WHERE seq_name = "group";