212 lines
5.0 KiB
JavaScript
212 lines
5.0 KiB
JavaScript
import utils from '../../utils';
|
|
import networkSvc from '../../networkSvc';
|
|
import store from '../../../store';
|
|
import userSvc from '../../userSvc';
|
|
import badgeSvc from '../../badgeSvc';
|
|
|
|
const request = ({ accessToken, serverUrl }, options) => networkSvc.request({
|
|
...options,
|
|
url: `${serverUrl}/api/v4/${options.url}`,
|
|
headers: {
|
|
...options.headers || {},
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
})
|
|
.then(res => res.body);
|
|
|
|
const getCommitMessage = (name, path) => {
|
|
const message = store.getters['data/computedSettings'].git[name];
|
|
return message.replace(/{{path}}/g, path);
|
|
};
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/users.html#for-user
|
|
*/
|
|
const subPrefix = 'gl';
|
|
userSvc.setInfoResolver('gitlab', subPrefix, async (sub) => {
|
|
try {
|
|
const [, serverUrl, id] = sub.match(/^(.+)\/([^/]+)$/);
|
|
const user = (await networkSvc.request({
|
|
url: `${serverUrl}/api/v4/users/${id}`,
|
|
})).body;
|
|
const uniqueSub = `${serverUrl}/${user.id}`;
|
|
|
|
return {
|
|
id: `${subPrefix}:${uniqueSub}`,
|
|
name: user.username,
|
|
imageUrl: user.avatar_url || '',
|
|
};
|
|
} catch (err) {
|
|
if (err.status !== 404) {
|
|
throw new Error('RETRY');
|
|
}
|
|
throw err;
|
|
}
|
|
});
|
|
|
|
export default {
|
|
subPrefix,
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/oauth2.html
|
|
*/
|
|
async startOauth2(serverUrl, applicationId, sub = null, silent = false) {
|
|
const { accessToken } = await networkSvc.startOauth2(
|
|
`${serverUrl}/oauth/authorize`,
|
|
{
|
|
client_id: applicationId,
|
|
response_type: 'token',
|
|
scope: 'api',
|
|
},
|
|
silent,
|
|
);
|
|
|
|
// Call the user info endpoint
|
|
const user = await request({ accessToken, serverUrl }, {
|
|
url: 'user',
|
|
});
|
|
const uniqueSub = `${serverUrl}/${user.id}`;
|
|
userSvc.addUserInfo({
|
|
id: `${subPrefix}:${uniqueSub}`,
|
|
name: user.username,
|
|
imageUrl: user.avatar_url || '',
|
|
});
|
|
|
|
// Check the returned sub consistency
|
|
if (sub && uniqueSub !== sub) {
|
|
throw new Error('GitLab account ID not expected.');
|
|
}
|
|
|
|
// Build token object including scopes and sub
|
|
const token = {
|
|
accessToken,
|
|
name: user.username,
|
|
serverUrl,
|
|
sub: uniqueSub,
|
|
};
|
|
|
|
// Add token to gitlab tokens
|
|
store.dispatch('data/addGitlabToken', token);
|
|
return token;
|
|
},
|
|
async addAccount(serverUrl, applicationId, sub = null) {
|
|
const token = await this.startOauth2(serverUrl, applicationId, sub);
|
|
badgeSvc.addBadge('addGitLabAccount');
|
|
return token;
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/projects.html#get-single-project
|
|
*/
|
|
async getProjectId(token, { projectPath, projectId }) {
|
|
if (projectId) {
|
|
return projectId;
|
|
}
|
|
|
|
const project = await request(token, {
|
|
url: `projects/${encodeURIComponent(projectPath)}`,
|
|
});
|
|
return project.id;
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/repositories.html#list-repository-tree
|
|
*/
|
|
async getTree({
|
|
token,
|
|
projectId,
|
|
branch,
|
|
}) {
|
|
return request(token, {
|
|
url: `projects/${encodeURIComponent(projectId)}/repository/tree`,
|
|
params: {
|
|
ref: branch,
|
|
recursive: true,
|
|
per_page: 9999,
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/commits.html#list-repository-commits
|
|
*/
|
|
async getCommits({
|
|
token,
|
|
projectId,
|
|
branch,
|
|
path,
|
|
}) {
|
|
return request(token, {
|
|
url: `projects/${encodeURIComponent(projectId)}/repository/commits`,
|
|
params: {
|
|
ref_name: branch,
|
|
path,
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/repository_files.html#create-new-file-in-repository
|
|
* https://docs.gitlab.com/ee/api/repository_files.html#update-existing-file-in-repository
|
|
*/
|
|
async uploadFile({
|
|
token,
|
|
projectId,
|
|
branch,
|
|
path,
|
|
content,
|
|
sha,
|
|
}) {
|
|
return request(token, {
|
|
method: sha ? 'PUT' : 'POST',
|
|
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
|
|
body: {
|
|
commit_message: getCommitMessage(sha ? 'updateFileMessage' : 'createFileMessage', path),
|
|
content,
|
|
last_commit_id: sha,
|
|
branch,
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/repository_files.html#delete-existing-file-in-repository
|
|
*/
|
|
async removeFile({
|
|
token,
|
|
projectId,
|
|
branch,
|
|
path,
|
|
sha,
|
|
}) {
|
|
return request(token, {
|
|
method: 'DELETE',
|
|
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
|
|
body: {
|
|
commit_message: getCommitMessage('deleteFileMessage', path),
|
|
last_commit_id: sha,
|
|
branch,
|
|
},
|
|
});
|
|
},
|
|
|
|
/**
|
|
* https://docs.gitlab.com/ee/api/repository_files.html#get-file-from-repository
|
|
*/
|
|
async downloadFile({
|
|
token,
|
|
projectId,
|
|
branch,
|
|
path,
|
|
}) {
|
|
const res = await request(token, {
|
|
url: `projects/${encodeURIComponent(projectId)}/repository/files/${encodeURIComponent(path)}`,
|
|
params: { ref: branch },
|
|
});
|
|
return {
|
|
sha: res.last_commit_id,
|
|
data: utils.decodeBase64(res.content),
|
|
};
|
|
},
|
|
};
|