gitsources: implement gitea oauth2 auth

As from https://github.com/go-gitea/gitea/pull/5378 gitea is an oauth2 provider.
This commit is contained in:
Simone Gotti 2019-05-09 14:14:13 +02:00
parent 4e785e4851
commit 92de7591da
3 changed files with 62 additions and 9 deletions

View File

@ -15,6 +15,7 @@
package gitea package gitea
import ( import (
"context"
"crypto/tls" "crypto/tls"
"fmt" "fmt"
"net" "net"
@ -25,6 +26,7 @@ import (
"time" "time"
gitsource "github.com/sorintlab/agola/internal/gitsources" gitsource "github.com/sorintlab/agola/internal/gitsources"
"golang.org/x/oauth2"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/pkg/errors" "github.com/pkg/errors"
@ -37,14 +39,24 @@ const (
ClientNotFound = "404 Not Found" ClientNotFound = "404 Not Found"
) )
var (
// gitea corrently doesn't have any auth scope
GiteaOauth2Scopes = []string{""}
)
type Opts struct { type Opts struct {
URL string URL string
Token string Token string
SkipVerify bool SkipVerify bool
Oauth2ClientID string
Oauth2Secret string
} }
type Client struct { type Client struct {
client *gitea.Client client *gitea.Client
URL string
oauth2ClientID string
oauth2Secret string
} }
// fromCommitStatus converts a gitsource commit status to a gitea commit status // fromCommitStatus converts a gitsource commit status to a gitea commit status
@ -90,10 +102,47 @@ func New(opts Opts) (*Client, error) {
client.SetHTTPClient(httpClient) client.SetHTTPClient(httpClient)
return &Client{ return &Client{
client: client, client: client,
URL: opts.URL,
oauth2ClientID: opts.Oauth2ClientID,
oauth2Secret: opts.Oauth2Secret,
}, nil }, nil
} }
func (c *Client) oauth2Config(callbackURL string) *oauth2.Config {
return &oauth2.Config{
ClientID: c.oauth2ClientID,
ClientSecret: c.oauth2Secret,
Scopes: GiteaOauth2Scopes,
Endpoint: oauth2.Endpoint{
AuthURL: fmt.Sprintf("%s/login/oauth/authorize", c.URL),
TokenURL: fmt.Sprintf("%s/login/oauth/access_token", c.URL),
},
RedirectURL: callbackURL,
}
}
func (c *Client) GetOauth2AuthorizationURL(callbackURL, state string) (string, error) {
var config = c.oauth2Config(callbackURL)
return config.AuthCodeURL(state), nil
}
func (c *Client) RequestOauth2Token(callbackURL, code string) (*oauth2.Token, error) {
var config = c.oauth2Config(callbackURL)
token, err := config.Exchange(context.TODO(), code)
if err != nil {
return nil, errors.Wrapf(err, "cannot get oauth2 token")
}
return token, nil
}
func (c *Client) RefreshOauth2Token(refreshToken string) (*oauth2.Token, error) {
var config = c.oauth2Config("")
token := &oauth2.Token{RefreshToken: refreshToken}
ts := config.TokenSource(context.TODO(), token)
return ts.Token()
}
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
var accessToken string var accessToken string

View File

@ -25,9 +25,11 @@ import (
func newGitea(rs *types.RemoteSource, accessToken string) (*gitea.Client, error) { func newGitea(rs *types.RemoteSource, accessToken string) (*gitea.Client, error) {
return gitea.New(gitea.Opts{ return gitea.New(gitea.Opts{
URL: rs.APIURL, URL: rs.APIURL,
SkipVerify: rs.SkipVerify, SkipVerify: rs.SkipVerify,
Token: accessToken, Token: accessToken,
Oauth2ClientID: rs.Oauth2ClientID,
Oauth2Secret: rs.Oauth2ClientSecret,
}) })
} }
@ -95,6 +97,8 @@ func GetOauth2Source(rs *types.RemoteSource, accessToken string) (gitsource.Oaut
var oauth2Source gitsource.Oauth2Source var oauth2Source gitsource.Oauth2Source
var err error var err error
switch rs.Type { switch rs.Type {
case types.RemoteSourceTypeGitea:
oauth2Source, err = newGitea(rs, accessToken)
case types.RemoteSourceTypeGitlab: case types.RemoteSourceTypeGitlab:
oauth2Source, err = newGitlab(rs, accessToken) oauth2Source, err = newGitlab(rs, accessToken)
default: default:

View File

@ -168,7 +168,7 @@ type RemoteSource struct {
func SourceSupportedAuthTypes(rsType RemoteSourceType) []RemoteSourceAuthType { func SourceSupportedAuthTypes(rsType RemoteSourceType) []RemoteSourceAuthType {
switch rsType { switch rsType {
case RemoteSourceTypeGitea: case RemoteSourceTypeGitea:
return []RemoteSourceAuthType{RemoteSourceAuthTypePassword} return []RemoteSourceAuthType{RemoteSourceAuthTypeOauth2, RemoteSourceAuthTypePassword}
case RemoteSourceTypeGithub: case RemoteSourceTypeGithub:
fallthrough fallthrough
case RemoteSourceTypeGitlab: case RemoteSourceTypeGitlab: