gitlab-dashboard icon indicating copy to clipboard operation
gitlab-dashboard copied to clipboard

Q: How to get up and running against private repositories on gitlab.com/<org>?

Open norrs opened this issue 7 years ago • 3 comments

I seem to be getting cors or 401 unauthorized issues when trying this towards a private organization. Demo host works with the public gitlab for public projects.

Any idea how to get this working for private organization? :-)

norrs avatar Sep 19 '18 09:09 norrs

Hi @norrs! I assume you added a private token to the page query params? (that should take care of the 401)

Re CORS: can you share the exact error you're getting? Is it related to "Credential" as mentioned in this issue? (the code for Gitlab CORS is here)

f-f avatar Sep 19 '18 11:09 f-f

@f-f : So if I understand this correctly, the current limitation lies here https://github.com/KSF-Media/gitlab-dashboard/blob/master/src/Gitlab.purs#L148 as this only lists the projects at a given gitlab hosted server.

So when we are using hosted gitlab at gitlab.com and have a dedicated group foo, the logic in the line above probably need to issue API calls towards:

https://gitlab.com/api/v4/groups/<main_group>/projects?private_token=<token>&simple=true&per_page=20&order_by=last_activity_at" to fetch groups project (https://docs.gitlab.com/ee/api/groups.html#list-a-group-s-projects) and then you would want to recursively fetch subgroups for all groups and it's subgroups again for getting a list over all projects before it would continue with fetching it jobs as usual.

https://docs.gitlab.com/ee/api/groups.html#list-a-group-s-subgroups https://docs.gitlab.com/ee/api/groups.html#list-a-group-s-projects

Because you could have a group foo , with subgroup bar where this subgroup bar has another subgroup zar

foo (/foo)
|--> bar (/foo/bar)
|------|--> zar   (/foo/bar/zar)

So API url for zar would be https://gitlab.com/api/v4/groups/foo%2Fbar%2Fzar/projects

Sadly my haskell skillset is rather limited, and this also looks like an interesting project with haskell to javascript magic! (:-D)

norrs avatar Sep 19 '18 16:09 norrs

@norrs nice, that's a really good analysis 👍

I'll consider this a bug, but we'll get around to fixing this probably in some weeks (we have some things to ship in the next weeks here at work)

So I'll leave the outline of a possible implementation for the fix if you'd like to try to do it:

  • you can get a live-reloading setup with the instructions in README. In this way you'll have the compiler running and telling you about any errors before reloading the code in the browser
  • Then: I'd add a function called getAllSubgroups of type getAllSubgroups :: GroupId -> Token -> Aff (Array Group) (you'd have to define the GroupId and Group types, instances, etc), that does all the API calls and returns a list containing the main group you passed in and all its subgroups and their subgroups (it would call itself recursively)
  • Once you have that, you can make another function called getHostedProjects of type getHostedProjects :: GroupId -> Token -> Aff Projects. And this would be basically a copy of getProjects, except we replace the AJAX call with a call to getAllSubgroups to get a list of Groups, and then have a for in which we call the API to get a list of Project for every group. Then we concat the results, and we have our list of Projects. Pseudocode:
    getHostedProjects :: GroupId -> Token -> Aff Projects
    getHostedProjects groupId token = do
      allGroups <- getAllSubgroups groupId token
      allProjects <- for allGroups \g -> do
        -- ... call API here, decode json, handle errors, etc.
        pure projects
      pure $ concat allProjects)
    
  • In the function that calls getProjects (here) I'd add a check on the provided baseUrl: if it contains gitlab.com (you can use contains) and we got a groupId query parameter (this handling needs to happen here), we call getHostedProjects instead. In pseudocode (this would probably compile though):
    -- I'm assuming that we got the a `Maybe GroupId` passed in the component state, 
    -- and we can access it:
    let Gitlab.BaseUrl url = baseUrl
    let isHosted = contains (Pattern "gitlab.com") url
    case (maybeGroupId, isHosted) of
      -- If we both got the group id and we matched the url
      (Just id, true) -> Gitlab.getHostedProjects id token
      -- otherwise
      _               -> Gitlab.getProjects baseUrl token
    

If you have any questions comment here or we can chat on twitter (I have open messages)

Hope it helps! :)

f-f avatar Sep 20 '18 12:09 f-f