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:
parent
8331c43a18
commit
a7ecfee795
|
@ -17,6 +17,8 @@ package gitea
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -54,6 +56,7 @@ type Opts struct {
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
client *gitea.Client
|
client *gitea.Client
|
||||||
|
httpClient *http.Client
|
||||||
URL string
|
URL string
|
||||||
oauth2ClientID string
|
oauth2ClientID string
|
||||||
oauth2Secret string
|
oauth2Secret string
|
||||||
|
@ -103,6 +106,7 @@ func New(opts Opts) (*Client, error) {
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
client: client,
|
client: client,
|
||||||
|
httpClient: httpClient,
|
||||||
URL: opts.URL,
|
URL: opts.URL,
|
||||||
oauth2ClientID: opts.Oauth2ClientID,
|
oauth2ClientID: opts.Oauth2ClientID,
|
||||||
oauth2Secret: opts.Oauth2Secret,
|
oauth2Secret: opts.Oauth2Secret,
|
||||||
|
@ -145,16 +149,39 @@ func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error)
|
||||||
|
|
||||||
func (c *Client) LoginPassword(username, password, tokenName string) (string, error) {
|
func (c *Client) LoginPassword(username, password, tokenName string) (string, error) {
|
||||||
// try to get agola access token if it already exists
|
// 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
|
var accessToken string
|
||||||
tokens, err := c.client.ListAccessTokens(username, password)
|
|
||||||
if err == nil {
|
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 {
|
for _, token := range tokens {
|
||||||
if token.Name == tokenName {
|
if token.Name == tokenName {
|
||||||
accessToken = token.Sha1
|
accessToken = token.Sha1
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// create access token
|
// create access token
|
||||||
if accessToken == "" {
|
if accessToken == "" {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
package gitsource
|
package gitsource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/sorintlab/agola/internal/services/types"
|
"github.com/sorintlab/agola/internal/services/types"
|
||||||
|
@ -29,6 +30,8 @@ const (
|
||||||
CommitStatusFailed CommitStatus = "failed"
|
CommitStatusFailed CommitStatus = "failed"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrUnauthorized = errors.New("unauthorized")
|
||||||
|
|
||||||
type GitSource interface {
|
type GitSource interface {
|
||||||
GetRepoInfo(repopath string) (*RepoInfo, error)
|
GetRepoInfo(repopath string) (*RepoInfo, error)
|
||||||
GetFile(repopath, commit, file string) ([]byte, error)
|
GetFile(repopath, commit, file string) ([]byte, error)
|
||||||
|
|
Loading…
Reference in New Issue