Hi, I'm trying to get the image file data (not just the URL) for a member's avatar. The URL returned the a user's avatarUrls along the lines of:
The CDN returns a 302 redirect back to our Atlassian site along the lines of:
The problem I'm running into is that the call to mydomain.atlassian.net needs to be authenticated, and I don't know how to do that via the API, without using cookies, which the API documentation recommends we avoid. So... what am I missing here?
Hi, here's what I got to work for our cloud account
Here is some TypeScript that demonstrates a class that handles the authentication and redirect required to get Avatar URLs...
import * as request from "request-promise-native";
export interface IAtlassianSiteProxy {
retrieveImage(url: string): Promise<IAtlassianAvatar>;
}
export interface IAtlassianAvatar {
readonly data: Buffer;
readonly contentType: string;
}
export class AtlassianSiteProxy implements IAtlassianSiteProxy {
private _atlassianDomain: string;
private _userName: string;
private _password: string;
private _apiUserName: string;
private _apiKey: string;
private _cookie: string = '';
public constructor(atlassianDomain: string, userName: string, password: string, apiUserName: string, apiKey: string) {
this._atlassianDomain = atlassianDomain;
this._userName = userName;
this._password = password;
this._apiUserName = apiUserName;
this._apiKey = apiKey;
}
/**
* Launch session to get cookie value
*/
private async getAtlassianCookie(): Promise<string> {
if (this._cookie) {
return this._cookie;
}
var options = {
uri: this._atlassianDomain + '/rest/auth/1/session',
method: 'POST',
headers: {
"Accept": "application/json",
"Content-type": "application/json"
},
auth: {
'user': this._apiUserName,
'pass': this._apiKey
},
body: {
username: this._userName,
password: this._password
},
json: true,
resolveWithFullResponse: true,
followRedirect: true,
followAllRedirects: true
};
let response = await request(options);
let headers = response.headers;
/* Flatten out cookies into a single string */
if (headers['set-cookie']) {
this._cookie = headers['set-cookie'].map(function (cookie: string) {
let i = cookie.indexOf(';');
let j = cookie.indexOf('=');
if (i > j && i > -1) {
let name = cookie.substr(0, j);
let value = cookie.substr(j + 1, i - j - 1);
return name + '=' + value;
} else {
return '';
}
}).join('; ').toString();
return this._cookie;
}
throw "Cookies not received from Atlassian session";
}
/**
* Retrieve the image specified by the URL, handling authentication and redirects
* @param url
*/
public async retrieveImage(url: string): Promise<IAtlassianAvatar> {
let cookie = await this.getAtlassianCookie();
let avatarOptions = {
method: 'GET',
uri: url,
headers: {
Connection: 'keep-alive',
Cookie: cookie
},
auth: {
'user': this._userName,
'pass': this._apiKey
},
encoding: null,
resolveWithFullResponse: true,
followRedirect: true
};
let response = await request(avatarOptions);
let contentType = response.headers['content-type'];
let data = response.body;
return {
contentType: contentType,
data: data
};
}
}
Hi @Thomas Deiler, I tried adding your suggested headers, to no avail. I suspect the problem is that the second URL, to get the avatar file, is not an API call, but a site call. Somehow, I have to get the cookies required to access the site, not just the API.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I reproduced your problems in my environment - I'll come back when I solved it.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi, first - thanks again for taking the time to look into this. I ran wget on my machine and ended up getting the "generic" icon.
The cookie file from wget looks like this:
````
.atlassian.com TRUE / TRUE 0 cloud.session.token deleted
id.atlassian.com FALSE / FALSE 0 atlassian.account.ffs.id (UUID)
.id.atlassian.com TRUE / TRUE 0 cloud.session.token deleted
id.atlassian.com FALSE / TRUE 0 atlassian.account.xsrf.token (HexOrBinStringLookingValue)
````
When I browse to the secure/useravatar in Jira (and we're using the hosted version, probably should have said that explicitly) and look at the cookies going over, there are a lot more cookies getting sent:
_utma, _utmz, ajx_user_id, ajs_group_id, ajs_anonymous_id, atlassian.xsrf.token, _utmb, &tmc, &tmt, cloud.session.token, _csrf
The interesting one to me is cloud.session.token, where wget was setting that as "deleted", whereas when hitting the Atlassian site in the browser it is a big long value.
I guess the next thing I'll try is injecting the cookeis in manually until I figure out which one/s are really required...
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando,
that sounds fine. Was my answer fine enough to be accepted?
Many thanks in advance
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando,
you have to do basic authentication (normally) and add a custom header (Content-Type: application/json), first. Then
GET /api/2/issue/<issue key>
should work.
For some API functions, it only works when adding additional headers:
accept: application/json
X-Atlassian-Token: nocheck
So long
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Dear @Jason Terando
Ok - got it. My solution is with wget, but this can be for sure adapted to any other program (like curl) or programming language.
I have looked at the source code of the login page of Jira. Username and password are stored in variables os_username and os_password. Additionally the 'save login on my computer' has to be checked. This is the variable os_cookie.
wget -d --save-cookies cookies.txt --keep-session-cookie --post-data 'os_username=admin&os_password=admin&os_cookie=true' http://localhost:8080/login.jsp -O login-result.html
This will authorize you, session saved to cookie.
wget -d --load-cookies cookies.txt http://localhost:8080/secure/useravatar?size=medium&avatarId=10122 -O avatar.png
This will download one avatar, taking the session from before. The '-d' option delivers more output, to see the HTTP header information.
Tell me, if you could reproduce what I found out.
So long
Thomas
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.