From 78bff8c9a3bca6a1417b4d1f7ede1f416326276b Mon Sep 17 00:00:00 2001 From: Rodrigo Pombo Date: Thu, 21 Feb 2019 20:08:41 -0300 Subject: [PATCH 1/2] Add bitbucket provider --- src/git-providers/bitbucket-provider.js | 142 ++++++++++++++++++++++++ src/git-providers/providers.js | 2 + 2 files changed, 144 insertions(+) create mode 100644 src/git-providers/bitbucket-provider.js diff --git a/src/git-providers/bitbucket-provider.js b/src/git-providers/bitbucket-provider.js new file mode 100644 index 0000000..2b6eded --- /dev/null +++ b/src/git-providers/bitbucket-provider.js @@ -0,0 +1,142 @@ +import netlify from "netlify-auth-providers"; +import { Base64 } from "js-base64"; +import React from "react"; +const TOKEN_KEY = "bitbucket-token"; + +function getHeaders() { + const token = window.localStorage.getItem(TOKEN_KEY); + return token ? { Authorization: `Bearer ${token}` } : {}; +} + +function isLoggedIn() { + return !!window.localStorage.getItem(TOKEN_KEY); +} + +async function getContent(repo, sha, path) { + const contentResponse = await fetch( + `https://gitlab.com/api/v4/projects/${encodeURIComponent( + repo + )}/repository/files/${encodeURIComponent(path)}?ref=${sha}`, + { headers: getHeaders() } + ); + + if (!contentResponse.ok) { + throw contentResponse; + } + const contentJson = await contentResponse.json(); + const content = Base64.decode(contentJson.content); + return { content }; +} + +function getUrlParams() { + const [ + , + owner, + reponame, + action, + sha, + ...paths + ] = window.location.pathname.split("/"); + + // if (action !== "commits" && action !== "blob") { + // return []; + // } + + return [owner + "/" + reponame, sha, paths.join("/")]; +} + +function getPath() { + const [, , path] = getUrlParams(); + return path; +} + +function showLanding() { + const [repo, ,] = getUrlParams(); + return !repo; +} + +const cache = {}; + +async function getCommits(path, last) { + const [repo, sha] = getUrlParams(); + + if (!cache[path]) { + let fields = + "values.path,values.commit.date,values.commit.message,values.commit.hash,values.commit.author.*,values.commit.links.html, values.commit.author.user.nickname, values.commit.author.user.links.avatar.href, values.commit.links.html.href"; + // fields = "*.*.*.*.*"; + const commitsResponse = await fetch( + `https://api.bitbucket.org/2.0/repositories/${repo}/filehistory/${sha}/${path}?fields=${fields}`, + { headers: getHeaders() } + ); + if (!commitsResponse.ok) { + throw commitsResponse; + } + const commitsJson = await commitsResponse.json(); + + cache[path] = commitsJson.values.map(({ commit }) => ({ + sha: commit.hash, + date: new Date(commit.date), + author: { + login: commit.author.user + ? commit.author.user.nickname + : commit.author.raw, + avatar: commit.author.user && commit.author.user.links.avatar.href + }, + commitUrl: commit.links.html.href, + message: commit.message, + content: "foo" + })); + } + + const commits = cache[path].slice(0, last); + + // await Promise.all( + // commits.map(async commit => { + // if (!commit.content) { + // const info = await getContent(repo, commit.sha, path); + // commit.content = info.content; + // } + // }) + // ); + + return commits; +} + +function logIn() { + // return new Promise((resolve, reject) => { + var authenticator = new netlify({ + site_id: "ccf3a0e2-ac06-4f37-9b17-df1dd41fb1a6" + }); + authenticator.authenticate({ provider: "gitlab", scope: "api" }, function( + err, + data + ) { + if (err) { + console.error(err); + return; + } + window.localStorage.setItem(TOKEN_KEY, data.token); + window.location.reload(false); + }); + // }); +} + +function LogInButton() { + return ( + + ); +} + +export default { + showLanding, + getPath, + getCommits, + logIn, + isLoggedIn, + LogInButton +}; diff --git a/src/git-providers/providers.js b/src/git-providers/providers.js index f18a4de..5ed5d78 100644 --- a/src/git-providers/providers.js +++ b/src/git-providers/providers.js @@ -2,6 +2,7 @@ import cliProvider from "./cli-provider"; import githubProvider from "./github-provider"; import vscodeProvider from "./vscode-provider"; import gitlabProvider from "./gitlab-provider"; +import bitbucketProvider from "./bitbucket-provider"; export default function getGitProvider() { switch (process.env.REACT_APP_GIT_PROVIDER) { @@ -14,6 +15,7 @@ export default function getGitProvider() { if (cloud === "gitlab") { return gitlabProvider; } + return bitbucketProvider; return githubProvider; } } From 356c7269adc6c48c77a5aadec1a33e332619b48e Mon Sep 17 00:00:00 2001 From: Rodrigo Pombo Date: Fri, 22 Feb 2019 16:29:45 -0300 Subject: [PATCH 2/2] Add private bitbucket repos --- src/app-helpers.js | 1 + src/git-providers/bitbucket-provider.js | 39 ++++++++++++------------- src/git-providers/providers.js | 3 +- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/app-helpers.js b/src/app-helpers.js index 6832d79..d972037 100644 --- a/src/app-helpers.js +++ b/src/app-helpers.js @@ -31,6 +31,7 @@ export function Loading({ repo, path }) { export function Error({ error, gitProvider }) { const { LogInButton } = gitProvider; if (error.status === 403) { + // FIX bitbucket uses 403 for private repos return (

diff --git a/src/git-providers/bitbucket-provider.js b/src/git-providers/bitbucket-provider.js index 2b6eded..b7f253c 100644 --- a/src/git-providers/bitbucket-provider.js +++ b/src/git-providers/bitbucket-provider.js @@ -14,17 +14,20 @@ function isLoggedIn() { async function getContent(repo, sha, path) { const contentResponse = await fetch( - `https://gitlab.com/api/v4/projects/${encodeURIComponent( - repo - )}/repository/files/${encodeURIComponent(path)}?ref=${sha}`, + `https://api.bitbucket.org/2.0/repositories/${repo}/src/${sha}/${path}`, { headers: getHeaders() } ); + if (contentResponse.status === 404) { + return { content: "" }; + } + if (!contentResponse.ok) { throw contentResponse; } - const contentJson = await contentResponse.json(); - const content = Base64.decode(contentJson.content); + + const content = await contentResponse.text(); + // const content = Base64.decode(contentJson.content); return { content }; } @@ -83,21 +86,20 @@ async function getCommits(path, last) { avatar: commit.author.user && commit.author.user.links.avatar.href }, commitUrl: commit.links.html.href, - message: commit.message, - content: "foo" + message: commit.message })); } const commits = cache[path].slice(0, last); - // await Promise.all( - // commits.map(async commit => { - // if (!commit.content) { - // const info = await getContent(repo, commit.sha, path); - // commit.content = info.content; - // } - // }) - // ); + await Promise.all( + commits.map(async commit => { + if (!commit.content) { + const info = await getContent(repo, commit.sha, path); + commit.content = info.content; + } + }) + ); return commits; } @@ -107,10 +109,7 @@ function logIn() { var authenticator = new netlify({ site_id: "ccf3a0e2-ac06-4f37-9b17-df1dd41fb1a6" }); - authenticator.authenticate({ provider: "gitlab", scope: "api" }, function( - err, - data - ) { + authenticator.authenticate({ provider: "bitbucket" }, function(err, data) { if (err) { console.error(err); return; @@ -127,7 +126,7 @@ function LogInButton() { onClick={logIn} style={{ fontWeight: 600, padding: "0.5em 0.7em", cursor: "pointer" }} > -

Sign in with GitLab
+
Sign in with Bitbucket
); } diff --git a/src/git-providers/providers.js b/src/git-providers/providers.js index 5ed5d78..02e5a4b 100644 --- a/src/git-providers/providers.js +++ b/src/git-providers/providers.js @@ -14,8 +14,9 @@ export default function getGitProvider() { const [cloud] = window.location.host.split("."); if (cloud === "gitlab") { return gitlabProvider; + } else if (cloud === "bitbucket") { + return bitbucketProvider; } - return bitbucketProvider; return githubProvider; } }