2020-11-16 15:16:51 +00:00
|
|
|
// Copyright (C) 2020 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
import { BaseGql } from '@/api/baseGql';
|
2021-03-16 19:43:02 +00:00
|
|
|
import { ErrorUnauthorized } from '@/api/errors/ErrorUnauthorized';
|
2020-11-24 22:29:19 +00:00
|
|
|
import {
|
|
|
|
AccessGrant,
|
|
|
|
AccessGrantCursor,
|
|
|
|
AccessGrantsApi,
|
|
|
|
AccessGrantsPage,
|
|
|
|
GatewayCredentials,
|
|
|
|
} from '@/types/accessGrants';
|
|
|
|
import { HttpClient } from '@/utils/httpClient';
|
|
|
|
import { MetaUtils } from '@/utils/meta';
|
2020-11-16 15:16:51 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* AccessGrantsApiGql is a graphql implementation of Access Grants API.
|
|
|
|
* Exposes all access grants-related functionality
|
|
|
|
*/
|
|
|
|
export class AccessGrantsApiGql extends BaseGql implements AccessGrantsApi {
|
2020-11-24 22:29:19 +00:00
|
|
|
private readonly client: HttpClient = new HttpClient();
|
2021-03-16 19:43:02 +00:00
|
|
|
private readonly ROOT_PATH: string = '/api/v0/api-keys';
|
2020-11-24 22:29:19 +00:00
|
|
|
|
2020-11-16 15:16:51 +00:00
|
|
|
/**
|
|
|
|
* Fetch access grants.
|
|
|
|
*
|
|
|
|
* @returns AccessGrantsPage
|
|
|
|
* @throws Error
|
|
|
|
*/
|
|
|
|
public async get(projectId: string, cursor: AccessGrantCursor): Promise<AccessGrantsPage> {
|
|
|
|
const query =
|
|
|
|
`query($projectId: String!, $limit: Int!, $search: String!, $page: Int!, $order: Int!, $orderDirection: Int!) {
|
|
|
|
project (
|
|
|
|
id: $projectId,
|
|
|
|
) {
|
|
|
|
apiKeys (
|
|
|
|
cursor: {
|
|
|
|
limit: $limit,
|
|
|
|
search: $search,
|
|
|
|
page: $page,
|
|
|
|
order: $order,
|
|
|
|
orderDirection: $orderDirection
|
|
|
|
}
|
|
|
|
) {
|
|
|
|
apiKeys {
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
createdAt
|
|
|
|
}
|
|
|
|
search,
|
|
|
|
limit,
|
|
|
|
order,
|
|
|
|
pageCount,
|
|
|
|
currentPage,
|
|
|
|
totalCount
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`;
|
|
|
|
|
|
|
|
const variables = {
|
|
|
|
projectId: projectId,
|
|
|
|
limit: cursor.limit,
|
|
|
|
search: cursor.search,
|
|
|
|
page: cursor.page,
|
|
|
|
order: cursor.order,
|
|
|
|
orderDirection: cursor.orderDirection,
|
|
|
|
};
|
|
|
|
|
|
|
|
const response = await this.query(query, variables);
|
|
|
|
|
|
|
|
return this.getAccessGrantsPage(response.data.project.apiKeys);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to create access grant.
|
|
|
|
*
|
|
|
|
* @param projectId - stores current project id
|
|
|
|
* @param name - name of access grant that will be created
|
|
|
|
* @returns AccessGrant
|
|
|
|
* @throws Error
|
|
|
|
*/
|
|
|
|
public async create(projectId: string, name: string): Promise<AccessGrant> {
|
|
|
|
const query =
|
|
|
|
`mutation($projectId: String!, $name: String!) {
|
|
|
|
createAPIKey(
|
|
|
|
projectID: $projectId,
|
|
|
|
name: $name
|
|
|
|
) {
|
|
|
|
key,
|
|
|
|
keyInfo {
|
|
|
|
id,
|
|
|
|
name,
|
|
|
|
createdAt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}`;
|
|
|
|
|
|
|
|
const variables = {
|
|
|
|
projectId,
|
|
|
|
name,
|
|
|
|
};
|
|
|
|
|
|
|
|
const response = await this.mutate(query, variables);
|
|
|
|
const key: any = response.data.createAPIKey.keyInfo;
|
|
|
|
const secret: string = response.data.createAPIKey.key;
|
|
|
|
|
|
|
|
return new AccessGrant(key.id, key.name, key.createdAt, secret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used to delete access grant.
|
|
|
|
*
|
|
|
|
* @param ids - ids of access grants that will be deleted
|
|
|
|
* @throws Error
|
|
|
|
*/
|
|
|
|
public async delete(ids: string[]): Promise<void> {
|
|
|
|
const query =
|
|
|
|
`mutation($id: [String!]!) {
|
|
|
|
deleteAPIKeys(id: $id) {
|
|
|
|
id
|
|
|
|
}
|
|
|
|
}`;
|
|
|
|
|
|
|
|
const variables = {
|
|
|
|
id: ids,
|
|
|
|
};
|
|
|
|
|
|
|
|
const response = await this.mutate(query, variables);
|
|
|
|
|
|
|
|
return response.data.deleteAPIKeys;
|
|
|
|
}
|
|
|
|
|
2021-03-16 19:43:02 +00:00
|
|
|
/**
|
|
|
|
* Used to delete access grant access grant by name and project ID.
|
|
|
|
*
|
|
|
|
* @param name - name of the access grant that will be deleted
|
|
|
|
* @param projectID - id of the project where access grant was created
|
|
|
|
* @throws Error
|
|
|
|
*/
|
|
|
|
public async deleteByNameAndProjectID(name: string, projectID: string): Promise<void> {
|
|
|
|
const path = `${this.ROOT_PATH}/delete-by-name?name=${name}&projectID=${projectID}`;
|
|
|
|
const response = await this.client.delete(path);
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (response.status === 401) {
|
|
|
|
throw new ErrorUnauthorized();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new Error('can not delete access grant');
|
|
|
|
}
|
|
|
|
|
2020-11-24 22:29:19 +00:00
|
|
|
/**
|
|
|
|
* Used to get gateway credentials using access grant.
|
|
|
|
*
|
|
|
|
* @param accessGrant - generated access grant
|
2021-03-18 19:22:46 +00:00
|
|
|
* @param optionalURL - optional requestURL
|
2020-11-24 22:29:19 +00:00
|
|
|
* @throws Error
|
|
|
|
*/
|
2021-03-18 19:22:46 +00:00
|
|
|
public async getGatewayCredentials(accessGrant: string, optionalURL?: string): Promise<GatewayCredentials> {
|
|
|
|
const requestURL: string = optionalURL || MetaUtils.getMetaContent('gateway-credentials-request-url');
|
2020-11-24 22:29:19 +00:00
|
|
|
if (!requestURL) throw new Error('Cannot get gateway credentials: request URL is not provided');
|
|
|
|
|
|
|
|
const path = `${requestURL}/v1/access`;
|
|
|
|
const body = {
|
|
|
|
access_grant: accessGrant,
|
|
|
|
public: false,
|
|
|
|
};
|
|
|
|
const response = await this.client.post(path, JSON.stringify(body));
|
|
|
|
if (!response.ok) {
|
|
|
|
throw new Error('Cannot get gateway credentials');
|
|
|
|
}
|
|
|
|
|
|
|
|
const result = await response.json();
|
|
|
|
|
|
|
|
return new GatewayCredentials(
|
|
|
|
result.id,
|
|
|
|
new Date(result.created_at),
|
|
|
|
result.access_key_id,
|
|
|
|
result.secret_key,
|
|
|
|
result.endpoint,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-11-16 15:16:51 +00:00
|
|
|
/**
|
|
|
|
* Method for mapping access grants page from json to AccessGrantsPage type.
|
|
|
|
*
|
|
|
|
* @param page anonymous object from json
|
|
|
|
*/
|
|
|
|
private getAccessGrantsPage(page: any): AccessGrantsPage {
|
|
|
|
if (!page) {
|
|
|
|
return new AccessGrantsPage();
|
|
|
|
}
|
|
|
|
|
|
|
|
const accessGrantsPage: AccessGrantsPage = new AccessGrantsPage();
|
|
|
|
|
|
|
|
accessGrantsPage.accessGrants = page.apiKeys.map(key => new AccessGrant(
|
|
|
|
key.id,
|
|
|
|
key.name,
|
|
|
|
new Date(key.createdAt),
|
|
|
|
'',
|
|
|
|
));
|
|
|
|
|
|
|
|
accessGrantsPage.search = page.search;
|
|
|
|
accessGrantsPage.limit = page.limit;
|
|
|
|
accessGrantsPage.order = page.order;
|
|
|
|
accessGrantsPage.orderDirection = page.orderDirection;
|
|
|
|
accessGrantsPage.pageCount = page.pageCount;
|
|
|
|
accessGrantsPage.currentPage = page.currentPage;
|
|
|
|
accessGrantsPage.totalCount = page.totalCount;
|
|
|
|
|
|
|
|
return accessGrantsPage;
|
|
|
|
}
|
|
|
|
}
|