Circle-token param ignored when using API URL to fetch latest artifact

artifacts

#1

I’ve noticed when I use this URL:

https://circle-artifacts.com/gh/Myorg/boilerplate-app-ember/93/artifacts/0/tmp/circle-artifacts.fs6GeoP/homepage.png?circle-token=myvalidtoken

everything works well, but the following URL:

https://circleci.com/api/v1/project/Myorg/boilerplate-app-ember/latest/artifacts/0/$CIRCLE_ARTIFACTS/homepage.png?circle-token=myvalidtoken

only works if I’m in a browser with an authenticated session. If I, for example, open a new Chrome incognito window, I get must be logged in. It looks like the latter URL only checks for a valid session and does not use the circle-token param.


Circle Artifacts API Generating Errors When I Try To getData From A URL
#2

Thank you for this bug report!

cc @KunalJain


#3

Current implementation does not support circle-token. Unfortunately, you need to be authenticated to use the new end point.


#4

Should we make this into a feature request instead?


#5

I’m voting +1 for this feature, since I’m generating git diffs as artifacts and making the endpoint accessible via token will allow me to apply those patches locally and directly from CLI. By instance:

$ wget -q -O - https://circle-artifacts.com/gh/Myorg/boilerplate-app/93/artifacts/0/tmp/circle-artifacts.fs6GeoP/git-diff.patch?circle-token=myvalidtoken | git apply -v

#6

+1 from me for turning this into a feature request.

Similar to how you can use the circle-token param to display a status badge in a README, I think there is enormous value in being able to display the latest artifact in a direct link, without needing authentication.

Thanks for investigating this so promptly!


#7

Thanks for all the feedback, I made this into a feature request. Be sure to click on the heart to show your “official” support. :slight_smile: Thanks!


#8

Seems it’s not only circle-token as a query param, I also tried using the token as curl --location-trusted -u ${CIRCLE_TOKEN}: and it did not work either :frowning: - redirected twice and ended in a 400 error response, even with cookies.

Is there another way to do authenticated API access or does this endpoint not support any access to private repos?

EDIT

Seems there’s one way that works, as a two-step process that involves parsing an intermediate JSON response:

curl https://circleci.com/api/v1.1/project/github/myOrg/myProject/latest/artifacts?circle-token=$TOKEN
# this returns a JSON array with multiple entries
# find the artifact you're interested in, `pretty_path` will look like what you see in the UI.  
# then take the `url` property of that entry and do a second request:
curl https://3-8029013-gh.circle-artifacts.com/0/tmp/circle-artifacts.asdflkdsf/myfile.txt?circle-token=$TOKEN

#9

Hi all, if anyone is interested I made an AWS lambda function that constructs a proper 302 redirect response with a correct Location header that includes the circle-token. Uses claudia.js

Use like this:

curl -vOL https://asdfasdf.execute-api.us-east-1.amazonaws.com/latest/artifact/myOrg/myRepo/myFile.txt\?token\=$TOKEN

You will get a 302 redirect response with a Location URL like https://3-1231231-gh.circle-artifacts.com/0/tmp/circle-artifacts.asfdasd/myFile.txt?circle-token=asdf It does a little bit of hand-waving by just matching on the file name (not path) but good enough for most purposes.

Code:

import API from 'claudia-api-builder';
import http from 'axios';

const api = new API();
function circleArtifactsURL(opts) {
  const { org, repo, token } = opts;
  return `https://circleci.com/api/v1.1/project/github/${org}/${repo}/latest/artifacts?circle-token=${token}`;
}

// test route to make sure everything is working correctly.
api.get('/hello', () => 'Hello');

api.get('/artifact/{org}/{repo}/{name}', request => new Promise((resolve,reject) => {
  const {token} = request.queryString;
  const {org, repo, name} = request.pathParams;

  // make HTTP request to CircleCI REST API:
  // https://circleci.com/docs/build-artifacts/
  http.get(circleArtifactsURL({org, repo, token}))
    .then(resp => {
      // find artifact based on {name} param.
      // Note we are testing *just the name* for a match, not the whole path!
      const artifactObj = resp.data.find( artifact => {
        const path = artifact.pretty_path;
        return path.substring(path.length-name.length) === name;
      });

      // artifact not found
      if ( ! artifactObj ) {
        return resolve(new api.ApiResponse('', {}, 404));
      }

      // send HTTP redirect
      const downloadURL = `${artifactObj.url}?circle-token=${token}`;
      resolve(new api.ApiResponse('', {'Location': downloadURL}, 302));
    })
    .catch(err => {
      if (err.response) {
        resolve(new api.ApiResponse('', {}, err.response.status));
      }
      reject(err);
    });
}),
{
  requestParameters: {
    querystring: { token: true },
  },
});

module.exports = api;

#10

This appears to be broken across the board.

Note that neither of the two documented ways to authenticate to the API (here: https://circleci.com/docs/1.0/api/#authentication) actually work on one of the most basic routes:

https://circleci.com/docs/1.0/api/#user

curl https://circleci.com/api/v1.1/me?circle-token=<valid token>
{
  "message" : "You must log in first."
}

curl -u <valid token>: https://circleci.com/api/v1.1/me
{
  "message" : "You must log in first."
}

Navigating to that URL in a browser with a logged in CircleCI user loads info. This is a pretty big issue IMO, as the documented methods for authentication are not honored. Session cookies are a pretty lousy way to try to interface with an API programatically.


#11

@KunalJain @levlaz were the docs ever correct?


#12

Hey Matt!

So I just tried this myself and it works just fine.

Are you using a user token found here: https://circleci.com/account/api?

Keep in mind there are user tokens and project tokens. Project tokens are specific to a single project. For general usage of the API I would suggest using the user token.

If you are in fact using a user token, let me know and we will dig further.

Best,
Lev


#13

Hey, you’re right - that definitely works with a user token. Thanks for jumping on it! I have to ask you to keep digging though, because the actual endpoint I am interested in is the environment variables endpoint, which doesn’t appear to work with the user token:

https://circleci.com/docs/1.0/api/#list-environment-variables

That was my original attempt which failed, and I have just re-checked with the user token that clearly works on the “me” endpoint with no luck. When I was creating the bug report, I generated a fresh token which was of the wrong kind, and I thought I was being clever by reporting the “me” endpoint as broken since it seemed like a more straightforward debug case than the project-specific “envvar” endpoint. Unfortunately I think I just muddied the waters more.

So, long story long, it’s great that the “me” endpoint works when sending the right token, but how about the “envvar” endpoint?


#14

Hey Matt,

One thing that is super confusing is :vcs-type you must use github or bitbucket instead of gh or bb. I know this is not the same as our UI and we have a ticket internally to make both work.

Can you double check the URL? If that still does not work, can you paste the full URL that you are using (without the token)?

Thanks!
Lev


#15

That was exactly it! Even documented here: https://circleci.com/docs/1.0/api/#version-control-system-vcs-type which I of course didn’t read before I started complaining.

Thanks @levlaz and co. for fixing this squeaky wheel.


#16

Happy to help!

I have spent hours and hours dealing with this issue because I keep forgetting about gh and github. I will admit its super annoying. I will keep bothering people to fix this. :slight_smile:


#17

Hey Matt,

I was able to get this working for the list of circle ci artifacts for the latest build, however when I try this for downloading the XCode Raw Log file for the latest successful build I continue to get the “must be logged in” error when in incognito mode even though I’ve tried to pass in the user token with both “view-builds” & “All” privileges. I should be able to download XCode Raw Log file through Circle CI API correct?

Cheers


Referencing Latest Build Artifacts
#18