Skip to content

Commit

Permalink
Bitbucket Cloud:Fetching UUID from API instead
Browse files Browse the repository at this point in the history
  • Loading branch information
HelloCore committed Dec 6, 2019
1 parent 377d18f commit 8368d7e
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 4 deletions.
32 changes: 28 additions & 4 deletions source/platforms/bitbucket_cloud/BitBucketCloudAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ interface BitBucketCloudCredentialsPassword {

export function bitbucketCloudCredentialsFromEnv(env: Env): BitBucketCloudCredentials {
const uuid = `${env["DANGER_BITBUCKETCLOUD_UUID"]}`
if (!uuid.startsWith("{") || !uuid.endsWith("}")) {
throw new Error(`DANGER_BITBUCKETCLOUD_UUID must be wraped with brackets`)
if (uuid.length > 0) {
if (!uuid.startsWith("{") || !uuid.endsWith("}")) {
throw new Error(`DANGER_BITBUCKETCLOUD_UUID must be wraped with brackets`)
}
}

if (env["DANGER_BITBUCKETCLOUD_OAUTH_KEY"]) {
Expand Down Expand Up @@ -67,6 +69,7 @@ export function bitbucketCloudCredentialsFromEnv(env: Env): BitBucketCloudCreden
export class BitBucketCloudAPI {
fetch: typeof fetch
accessToken: string | undefined
uuid: string | undefined

private readonly d = debug("BitBucketCloudAPI")
private pr: BitBucketCloudPRDSL | undefined
Expand All @@ -78,6 +81,11 @@ export class BitBucketCloudAPI {
// This allows Peril to DI in a new Fetch function
// which can handle unique API edge-cases around integrations
this.fetch = fetch

// Backward compatible,
if (credentials.uuid.length > 0) {
this.uuid = credentials.uuid
}
}

getBaseRepoURL() {
Expand Down Expand Up @@ -214,7 +222,7 @@ export class BitBucketCloudAPI {

return comments
.filter(comment => comment.content.raw.includes(dangerIDMessage))
.filter(comment => comment.user.uuid === this.credentials.uuid)
.filter(comment => comment.user.uuid === this.uuid)
.filter(comment => comment.content.raw.includes("Generated by"))
}

Expand All @@ -224,7 +232,7 @@ export class BitBucketCloudAPI {

return comments.filter(comment => comment.inline).map(comment => ({
id: comment.id.toString(),
ownedByDanger: comment.content.raw.includes(dangerIDMessage) && comment.user.uuid === this.credentials.uuid,
ownedByDanger: comment.content.raw.includes(dangerIDMessage) && comment.user.uuid === this.uuid,
body: comment.content.raw,
}))
}
Expand Down Expand Up @@ -309,6 +317,7 @@ export class BitBucketCloudAPI {
).toString("base64")}`
} else {
if (this.accessToken == null) {
this.d(`accessToken not found, trying to get from ${this.oauthURL}.`)
const params = new URLSearchParams()

params.append("grant_type", "client_credentials")
Expand Down Expand Up @@ -337,6 +346,21 @@ export class BitBucketCloudAPI {
headers["Authorization"] = `Bearer ${this.accessToken}`
}

if (this.uuid == null) {
this.d(`UUID not found, trying to get from ${this.baseURL}/user`)
const profileResponse = await this.performAPI(`${this.baseURL}/user`, headers, null, "GET", suppressErrors)
if (profileResponse.ok) {
const jsonResp = await profileResponse.json()
this.uuid = jsonResp["uuid"]
} else {
let message = `${profileResponse.status} - ${profileResponse.statusText}`
if (profileResponse.status >= 400 && profileResponse.status < 500) {
message += ` (Have you allowed permission 'account' for this credential?)`
}
throw new Error(message)
}
}

return this.performAPI(url, headers, body, method, suppressErrors)
}

Expand Down
139 changes: 139 additions & 0 deletions source/platforms/bitbucket_cloud/_tests_/_bitbucket_cloud_api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -382,4 +382,143 @@ describe("API testing - BitBucket Cloud", () => {

expect(result).toEqual({ pr: "info" })
})

it("should fetch uuid if not exists given username", async () => {
api = new BitBucketCloudAPI(
{ repoSlug: "foo/bar", pullRequestID: "1" },
{
type: "PASSWORD",
username: "foo",
password: "bar",
uuid: "",
}
)
let requestNo = 0
let fetch = jest.fn().mockReturnValue({
status: 200,
ok: true,
json: () => {
requestNo += 1
if (requestNo === 1) {
return {
uuid: "{1234-1234-1234-1234}",
}
} else {
return { pr: "info" }
}
},
text: () => textResult,
})

api.fetch = fetch

const result = await api.getPullRequestInfo()
expect(api.fetch).toBeCalledTimes(2)
expect(fetch.mock.calls[0][0]).toBe("https://api.bitbucket.org/2.0/user")
expect(result).toEqual({ pr: "info" })
})

it("should fetch uuid if not exists given oauth key", async () => {
api = new BitBucketCloudAPI(
{ repoSlug: "foo/bar", pullRequestID: "1" },
{
type: "OAUTH",
oauthSecret: "superSecretOAUTH",
oauthKey: "superOAUTHKey",
uuid: "",
}
)
let requestNo = 0
let fetch = jest.fn().mockReturnValue({
status: 200,
ok: true,
json: () => {
requestNo += 1
if (requestNo === 1) {
return {
access_token: "bla bla bla bla",
}
} else if (requestNo === 2) {
return {
uuid: "{1234-1234-1234-1234}",
}
} else {
return { pr: "info" }
}
},
text: () => textResult,
})

api.fetch = fetch

const result = await api.getPullRequestInfo()
expect(api.fetch).toBeCalledTimes(3)
expect(fetch.mock.calls[1][0]).toBe("https://api.bitbucket.org/2.0/user")
expect(result).toEqual({ pr: "info" })
})

it("should fetch uuid if not exists given accessToken", async () => {
api = new BitBucketCloudAPI(
{ repoSlug: "foo/bar", pullRequestID: "1" },
{
type: "OAUTH",
oauthSecret: "superSecretOAUTH",
oauthKey: "superOAUTHKey",
uuid: "",
}
)
let requestNo = 0
let fetch = jest.fn().mockReturnValue({
status: 200,
ok: true,
json: () => {
requestNo += 1
if (requestNo === 1) {
return {
uuid: "{1234-1234-1234-1234}",
}
} else {
return { pr: "info" }
}
},
text: () => textResult,
})

api.fetch = fetch
api.accessToken = "bla bla bla bla"

const result = await api.getPullRequestInfo()
expect(api.fetch).toBeCalledTimes(2)
expect(fetch.mock.calls[0][0]).toBe("https://api.bitbucket.org/2.0/user")
expect(result).toEqual({ pr: "info" })
})

it("shouldn't fetch uuid if uuid exists (from api calling)", async () => {
api = new BitBucketCloudAPI(
{ repoSlug: "foo/bar", pullRequestID: "1" },
{
type: "OAUTH",
oauthSecret: "superSecretOAUTH",
oauthKey: "superOAUTHKey",
uuid: "",
}
)

let fetch = jest.fn().mockReturnValue({
status: 200,
ok: true,
json: () => {
return { pr: "info" }
},
text: () => textResult,
})

api.fetch = fetch
api.accessToken = "bla bla bla bla"
api.uuid = "{1234-1234-1234-1234}"

const result = await api.getPullRequestInfo()
expect(api.fetch).toBeCalledTimes(1)
expect(result).toEqual({ pr: "info" })
})
})

0 comments on commit 8368d7e

Please sign in to comment.