2017-02-28 08:19:32 -05:00
|
|
|
import {GithubApi} from './github-api';
|
2018-08-15 08:47:45 -04:00
|
|
|
import {assertNotMissingOrEmpty} from './utils';
|
2017-02-28 08:19:32 -05:00
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
export interface Team {
|
2017-02-28 08:19:32 -05:00
|
|
|
id: number;
|
|
|
|
slug: string;
|
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
export interface TeamMembership {
|
2017-02-28 08:19:32 -05:00
|
|
|
state: string;
|
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
export class GithubTeams {
|
|
|
|
/**
|
|
|
|
* Create an instance of this helper
|
|
|
|
* @param api An instance of the Github API helper.
|
|
|
|
* @param githubOrg The organisation on GitHub whose repo we will interrogate.
|
|
|
|
*/
|
|
|
|
constructor(private api: GithubApi, protected githubOrg: string) {
|
|
|
|
assertNotMissingOrEmpty('githubOrg', githubOrg);
|
2017-02-28 08:19:32 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Request information about all the organisation's teams in GitHub.
|
|
|
|
* @returns A promise that is resolved with information about the teams.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public fetchAll(): Promise<Team[]> {
|
2018-05-10 08:56:07 -04:00
|
|
|
return this.api.getPaginated<Team>(`/orgs/${this.githubOrg}/teams`);
|
2017-02-28 08:19:32 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Check whether the specified username is a member of the specified team.
|
|
|
|
* @param username The usernane to check for in the team.
|
|
|
|
* @param teamIds The team to check for the username.
|
|
|
|
* @returns a Promise that resolves to `true` if the username is a member of the team.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public async isMemberById(username: string, teamIds: number[]): Promise<boolean> {
|
2017-02-28 08:19:32 -05:00
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
const getMembership = async (teamId: number) => {
|
|
|
|
try {
|
|
|
|
const {state} = await this.api.get<TeamMembership>(`/teams/${teamId}/memberships/${username}`);
|
|
|
|
return state === 'active';
|
|
|
|
} catch (error) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
for (const teamId of teamIds) {
|
|
|
|
if (await getMembership(teamId)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2017-02-28 08:19:32 -05:00
|
|
|
}
|
|
|
|
|
2018-05-10 08:56:07 -04:00
|
|
|
/**
|
|
|
|
* Check whether the given username is a member of the teams specified by the team slugs.
|
|
|
|
* @param username The username to check for in the teams.
|
|
|
|
* @param teamSlugs A collection of slugs that represent the teams to check for the the username.
|
|
|
|
* @returns a Promise that resolves to `true` if the usernane is a member of at least one of the specified teams.
|
|
|
|
*/
|
2018-08-10 06:10:22 -04:00
|
|
|
public async isMemberBySlug(username: string, teamSlugs: string[]): Promise<boolean> {
|
2018-05-10 08:56:07 -04:00
|
|
|
try {
|
|
|
|
const teams = await this.fetchAll();
|
|
|
|
const teamIds = teams.filter(team => teamSlugs.includes(team.slug)).map(team => team.id);
|
|
|
|
return await this.isMemberById(username, teamIds);
|
|
|
|
} catch (error) {
|
|
|
|
return false;
|
|
|
|
}
|
2017-02-28 08:19:32 -05:00
|
|
|
}
|
|
|
|
}
|