GitLabのAPIを利用して、ユーザが参照できるプロジェクト一覧を作成する

GitLab上で、誰がどのプロジェクトを参照可能かを一覧化したかったので、GitLabのAPIを利用して一覧化してみます。

GitLab Community Editionを利用して確認しました。

GItLabのAPI

APIの情報は下記ドキュメントにまとまっています。

認証方法はいくつかありますが、今回はPersonal access tokenを利用してアクセスしてみます。Personal access tokenはUser Settingsから作成可能です。

Scopeはapiにしました。

グループメンバーの取得

プロジェクトを参照できるのは、下記の2パターンとなります。

  1. 上位のグループのメンバー
  2. プロジェクトのメンバー

そのため、単にプロジェクトのメンバーの情報だけでアクセス可否が決まるのではなく、グループのメンバーの情報も考慮する必要があります。

ということで、まずはAPIでグループ一覧を取得します。

GET http://gitlab.example.com/api/v4/groups?access_token=<access token>

下記のようにグループ一覧が取得できました。

[
  {
    "id": 5,
    "web_url": "http://gitlab.example.com/groups/group1",
    "name": "group1",
    "path": "group1",
    "description": "",
    "visibility": "private",
    "share_with_group_lock": false,
    "require_two_factor_authentication": false,
    "two_factor_grace_period": 48,
    "project_creation_level": "developer",
    "auto_devops_enabled": null,
    "subgroup_creation_level": "maintainer",
    "emails_disabled": null,
    "lfs_enabled": true,
    "avatar_url": null,
    "request_access_enabled": true,
    "full_name": "group1",
    "full_path": "group1",
    "parent_id": null
  },
  {
    "id": 6,
    "web_url": "http://gitlab.example.com/groups/group2",
    "name": "group2",
    "path": "group2",
    "description": "",
    "visibility": "private",
    "share_with_group_lock": false,
    "require_two_factor_authentication": false,
    "two_factor_grace_period": 48,
    "project_creation_level": "developer",
    "auto_devops_enabled": null,
    "subgroup_creation_level": "maintainer",
    "emails_disabled": null,
    "lfs_enabled": true,
    "avatar_url": null,
    "request_access_enabled": true,
    "full_name": "group2",
    "full_path": "group2",
    "parent_id": null
  }
]

ここからさらにグループのメンバーを取得します。

GET http://gitlab.example.com/api/v4/groups/5/members?access_token=<access token>
[
  {
    "id": 1,
    "name": "Administrator",
    "username": "root",
    "state": "active",
    "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
    "web_url": "http://gitlab.example.com/root",
    "access_level": 50,
    "expires_at": null
  },
  {
    "id": 3,
    "name": "user2",
    "username": "user2",
    "state": "active",
    "avatar_url": "https://www.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?s=80&d=identicon",
    "web_url": "http://gitlab.example.com/user2",
    "access_level": 30,
    "expires_at": null
  }
]

これを繰り返し取得することによって、各グループのメンバー一覧が作成できます。

プロジェクトメンバーの取得

プロジェクト一覧を取得します。なお、グループから辿っていく方法もありますが、ユーザが持つプロジェクトも含めたかったので、プロジェクト一覧から辿るようにしました。

GET http://gitlab.example.com/api/v4/projects?simple=true&access_token=<access token>

プロジェクト一覧は下記のようになります。

[
  {
    "id": 3,
    "description": "",
    "name": "my-project",
    "name_with_namespace": "Administrator / my-project",
    "path": "my-project",
    "path_with_namespace": "root/my-project",
    "created_at": "2019-11-16T13:48:47.727Z",
    "default_branch": null,
    "tag_list": [],
    "ssh_url_to_repo": "git@gitlab.example.com:root/my-project.git",
    "http_url_to_repo": "http://gitlab.example.com/root/my-project.git",
    "web_url": "http://gitlab.example.com/root/my-project",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-11-16T13:48:47.727Z",
    "namespace": {
      "id": 1,
      "name": "Administrator",
      "path": "root",
      "kind": "user",
      "full_path": "root",
      "parent_id": null,
      "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
      "web_url": "http://gitlab.example.com/root"
    }
  },
  {
    "id": 2,
    "description": "",
    "name": "project-b",
    "name_with_namespace": "group1 / project-b",
    "path": "project-b",
    "path_with_namespace": "group1/project-b",
    "created_at": "2019-11-16T13:48:11.161Z",
    "default_branch": null,
    "tag_list": [],
    "ssh_url_to_repo": "git@gitlab.example.com:group1/project-b.git",
    "http_url_to_repo": "http://gitlab.example.com/group1/project-b.git",
    "web_url": "http://gitlab.example.com/group1/project-b",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-11-16T13:48:11.161Z",
    "namespace": {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "kind": "group",
      "full_path": "group1",
      "parent_id": null,
      "avatar_url": null,
      "web_url": "http://gitlab.example.com/groups/group1"
    }
  },
  {
    "id": 1,
    "description": "",
    "name": "project-a",
    "name_with_namespace": "group1 / project-a",
    "path": "project-a",
    "path_with_namespace": "group1/project-a",
    "created_at": "2019-11-16T13:44:20.849Z",
    "default_branch": null,
    "tag_list": [],
    "ssh_url_to_repo": "git@gitlab.example.com:group1/project-a.git",
    "http_url_to_repo": "http://gitlab.example.com/group1/project-a.git",
    "web_url": "http://gitlab.example.com/group1/project-a",
    "readme_url": null,
    "avatar_url": null,
    "star_count": 0,
    "forks_count": 0,
    "last_activity_at": "2019-11-16T13:44:20.849Z",
    "namespace": {
      "id": 5,
      "name": "group1",
      "path": "group1",
      "kind": "group",
      "full_path": "group1",
      "parent_id": null,
      "avatar_url": null,
      "web_url": "http://gitlab.example.com/groups/group1"
    }
  }
]

ここからさらにプロジェクトのメンバーを取得します。

GET http://gitlab.example.com/api/v4/projects/1/members?access_token=<access token>
[
  {
    "id": 2,
    "name": "user1",
    "username": "user1",
    "state": "active",
    "avatar_url": "https://www.gravatar.com/avatar/111d68d06e2d317b5a59c2c6c5bad808?s=80&d=identicon",
    "web_url": "http://gitlab.example.com/user1",
    "access_level": 40,
    "expires_at": null
  }
]

この情報に、さらに上位のグループのメンバーの情報を付与することによって、プロジェクトにアクセス可能なユーザ一覧を作ることができます。

おわりに

今回調べた情報を元にツールを作成予定です。作成出来たら追記します。