gitea: use custom http request for get tokens

Since the get tokens gitea api is used to do auth by username password we need
to know the api status code to detect if it's an unauthorized error (wrong
username/password) or another error.

Since the gitea client doesn't return the http response to inspect the status
code we'll use our own api call.
This commit is contained in:
Simone Gotti 2019-05-13 14:21:41 +02:00
parent 8331c43a18
commit a7ecfee795
2 changed files with 37 additions and 7 deletions

View File

@ -17,6 +17,8 @@ package gitea
import (
"context"
"crypto/tls"
"encoding/base64"
"encoding/json"
"fmt"
"net"
"net/http"
@ -54,6 +56,7 @@ type Opts struct {
type Client struct {
client *gitea.Client
httpClient *http.Client
URL string
oauth2ClientID string
oauth2Secret string
@ -103,6 +106,7 @@ func New(opts Opts) (*Client, error) {
return &Client{
client: client,
httpClient: httpClient,
URL: opts.URL,
oauth2ClientID: opts.Oauth2ClientID,
oauth2Secret: opts.Oauth2Secret,
@ -145,14 +149,37 @@ func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error)
func (c *Client) LoginPassword(username, password, tokenName string) (string, error) {
// try to get agola access token if it already exists
// use custom http call since gitea api client doesn't provide an easy way to
// guess if the username/password login failed
var accessToken string
tokens, err := c.client.ListAccessTokens(username, password)
if err == nil {
for _, token := range tokens {
if token.Name == tokenName {
accessToken = token.Sha1
break
}
tokens := make([]*gitea.AccessToken, 0, 10)
req, err := http.NewRequest("GET", c.URL+"/api/v1"+fmt.Sprintf("/users/%s/tokens", username), nil)
if err != nil {
return "", err
}
req.Header.Set("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(username+":"+password)))
resp, err := c.httpClient.Do(req)
if err != nil {
return "", err
}
if resp.StatusCode == http.StatusUnauthorized {
return "", gitsource.ErrUnauthorized
}
if resp.StatusCode/100 != 2 {
return "", errors.Errorf("gitea api status code %d", resp.StatusCode)
}
defer resp.Body.Close()
dec := json.NewDecoder(resp.Body)
if err := dec.Decode(&tokens); err != nil {
return "", err
}
for _, token := range tokens {
if token.Name == tokenName {
accessToken = token.Sha1
break
}
}

View File

@ -15,6 +15,7 @@
package gitsource
import (
"errors"
"net/http"
"github.com/sorintlab/agola/internal/services/types"
@ -29,6 +30,8 @@ const (
CommitStatusFailed CommitStatus = "failed"
)
var ErrUnauthorized = errors.New("unauthorized")
type GitSource interface {
GetRepoInfo(repopath string) (*RepoInfo, error)
GetFile(repopath, commit, file string) ([]byte, error)