-
Notifications
You must be signed in to change notification settings - Fork 959
Can i get private-token with my password? #267
Comments
@LiangXugang you should be able to use your a private or personal token without any issues: https://docs.gitlab.com/ce/api/#personal-access-tokens |
I think his requirement is to use the password to retrieve the token, as the token is not available at the time. This was achieved before GitLab 10.2.0 (2017-11-22) using the Session API which was recently removed. At the moment I don't think this is possible. |
@clns yep, i use the Session API in v3-Gitlab. But it's removed in v4-Gitlab. As my user is just a general user(not admin), I cannot create a impersonation token too. |
It’s removed in v3 as well, I think it’s removed in all api versions. |
I'm really sorry, but I fail to understand what the actual problem is here. If I login to I can create EDIT: I also noticed this in the docs:
So it seems that using a session cookie is no longer supported and is also no longer intended to be used by client applications. |
@svanharmelen there are a lot of use-cases when it's not possible to obtain Suppose you're writing a service which interacts with
PR #269 adopts the third approach. I agree that it doesn't fit good to the purpose of this library (to support only API specification), but, as we can see, it can solve problems of many users of this library. |
@vitalyisaev2 ok, I understand your use case. I do think it's kind of a corner case and I wonder if we should solve this in the But on the other hand I think I can probably create a solution which would allow you to use this package with either a token or your username/password. So let me have a look at that instead, as I believe that would be the real solution right? |
Hmm... One more question to understand your use case. If you spin up a new Gitlab setup in a container, then how do you get your username/password? |
@svanharmelen yes, I think, we are actually looking for a way to access API only with login / password. |
@svanharmelen It's possible to set up root password via Docker environment variables (https://github.com/sameersbn/docker-gitlab) |
Ok... So I've spent a reasonable amount of time on this today, only to come to the conclusion that it is not possible (given the current options the Gitlab API offers us) to create a decent way to support your use case. I suggest you open an issue with Gitlab and explain them your use case to see if they can come up with either a solution or an API change (if they're willing to go that far) to support your use case. Another solution could be that you add some logic to your CI setup so that it makes these additional calls to create and retrieve a personal token after spinning the Gitlab container, which it can than pass on the your application when starting it next. If all else fails, I guess the only way forward is to add the function you showed in PR #269 in your own application, as I just don't feel comfortable with adding such a hacky function to this API client package. |
@svanharmelen thanks for your effort in investigation of this issue :) There's a thread on Gitlab forum where several users are wondering how to work around it. I'll try to issue a feature request to Gitlab, but I'm sure they have reasons not to implement this feature, otherwise it should have been implemented a long time ago. |
Hope anything useful comes out of it 👍 |
Maybe this SO post can be used as a foundation for how to get the access token / session token via curl requests https://stackoverflow.com/a/47952043/1549950 The session token should be usable for authenticating API requests as well - see https://docs.gitlab.com/ce/api/README.html#session-cookie |
@michaellihs thanks for the reference. This is more of less what I tried last time I worked on this (see the last commit in this branch: https://github.com/xanzy/go-gitlab/tree/f-session), but I didn't quite get it working. But now looking at it again, I think I see what I did wrong. So let me try to update my last attempt just a bit... |
Yeah, so I didn't do anything wrong... The problem is that the CSRF token is only set in the metadata and not in a header. So in order to retrieve that value we would need to parse/scrape the returned webpage. And I really don't want to go that route. To me that just feels too bad/ugly 😞 |
Ok... This is still ugly, but it does work... So maybe we should merge this to offer users a solution to login using username password (see the last commit in the |
@LiangXugang @michaellihs @vitalyisaev2 could you guys please give this a good test run to make sure it works as expected? Both the new My own quick tests seem to indicate it should be good now... |
@svanharmelen thank you, I haven't seen |
Oh oh - my comment was not intended to trigger so much work... I had a different problem regarding the question how to get a plain Gitlab Docker image configured in such a way that I can use it for end2end testing in Travis CI - therefore the hacky bash solution was fine... but it's great that you provide a way to do this through go-gitlab now, this offers me the possibility to login to Gitlab with username and password from the command line. I will give it a try the next couple of days. Thanks a lot for your effort! |
No worries... I’ve looked at this a little while ago (when this issue was opened), but stopped when I found it to become too ugly. So your comment only triggered me to look at that commit again and think about the options. So it wasn’t that much work to be honest, and I guess it adds some value. So all is good 👍 |
Hm - regarding the title of the issue, I have to admit that I was expecting a little "extra functionality" in the There seems to be another implementation now, that follows the approach I did with |
I was thinking about adding this API endpoint to the package: https://docs.gitlab.com/ce/api/users.html#create-an-impersonation-token When being able to use the package with username and password, then you can create a token using a stabdard API call. Together that should solve this issue, right? |
Impersonation token endpoints are already implemented, I think: https://github.com/xanzy/go-gitlab/blob/master/users.go#L596 ff - but I didn't know that one can use them as a replacement for the auth tokens... so it's all there, I guess :) |
@svanharmelen I tested your new basic auth client via func getImpersonationToken(host string, username string, password string) (string, error) {
baseUrl, err := url.Parse(host)
if err != nil {
return "", errors.New(fmt.Sprintf("could not parse given host '%s': %s", baseUrl, err))
}
client, err := initHttpClient()
if err != nil {
return "", err
}
loginClient, err := gitlab.NewBasicAuthClient(client, host, username, password)
user, _, err := gitlabClient.Users.CurrentUser()
if err != nil {
return "", err
}
tokenName := "golab"
scopes := []string{"api"}
opts := &gitlab.CreateImpersonationTokenOptions{
Name: &tokenName,
Scopes: &scopes,
}
token, _, err := loginClient.Users.CreateImpersonationToken(user.ID, opts)
if err != nil {
return "", err
}
return token.Token, nil
} The first (
My assumption was, that every API request that is session-authenticated needs to pass a CSRF check, since GitLab assumes, that such a request comes from the frontend (UI), hence has a valid CSRF token. That is also the reason, why the GET request works whereas the POST/PUT doesn't. Dirty fix: get yourself ANY CSRF token before you send a POST/PUT request and add it to the request: func getImpersonationToken(host string, username string, password string) (string, error) {
// ... like before
csrfToken, err := getCsrfToken(host+"/profile", client)
setCsrfToken := func(req *http.Request) error {
req.Header.Set("X-CSRF-Token", csrfToken)
return nil
}
token, _, err := loginClient.Users.CreateImpersonationToken(user.ID, opts, setCsrfToken)
if err != nil {
return "", err
}
return token.Token, nil
}
func getCsrfToken(url string, client *http.Client) (string, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
}
resp, err := client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
match := regexp.MustCompile(`"csrf-token" content="(.*?)"`).FindSubmatch(body)
if len(match) != 2 {
return "", fmt.Errorf("unable to retieve CSRF token")
}
return string(match[1]), nil
} Since this solution is quite flaky, I assume that you should not merge the current implementation yet. At least the CSRF generation / addition to header should be added to the client or much facilitated by the library... Related: |
Oh, that’s a shame (that all session based API calls require an updated CSRF token)... I was under the impression it was only needed when POSTing to website endpoints (so everything not starting with https://gitlab.com/api/v4). In this case I again very much doubt if we should this at all. It’s just plain hacking around the API, instead of using the API. And this is suppose to be an API client... So going to sleep over it, but think we should close this as a |
Thought about it, but unless someone else comes up with a proper solution I don't think this code should be added to |
@LiangXugang this should now be possible using the |
I can get my username&password only, and how can i create the go-gitlab client??
In my app, i cannot use OAUTH2.0 token anymore.
The text was updated successfully, but these errors were encountered: