Implement Refresher for GitLab and refactor nits (#1031)

* refactor & update gitea remote

* refactor & update gitlab remote

* gitlab remote: add Refresh()

* change as suggested by @dsanader
This commit is contained in:
6543 2022-08-24 15:46:11 +02:00 committed by GitHub
parent 770cd1bd95
commit a4453dc5af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 18 deletions

View file

@ -42,7 +42,7 @@ const (
authorizeTokenURL = "%s/login/oauth/authorize" authorizeTokenURL = "%s/login/oauth/authorize"
accessTokenURL = "%s/login/oauth/access_token" accessTokenURL = "%s/login/oauth/access_token"
perPage = 50 perPage = 50
giteaDevVersion = "v1.17.0" giteaDevVersion = "v1.18.0"
) )
type Gitea struct { type Gitea struct {
@ -84,10 +84,8 @@ func (c *Gitea) Name() string {
return "gitea" return "gitea"
} }
// Login authenticates an account with Gitea using basic authentication. The func (c *Gitea) oauth2Config() *oauth2.Config {
// Gitea account details are returned when the user is successfully authenticated. return &oauth2.Config{
func (c *Gitea) Login(ctx context.Context, w http.ResponseWriter, req *http.Request) (*model.User, error) {
config := &oauth2.Config{
ClientID: c.ClientID, ClientID: c.ClientID,
ClientSecret: c.ClientSecret, ClientSecret: c.ClientSecret,
Endpoint: oauth2.Endpoint{ Endpoint: oauth2.Endpoint{
@ -96,6 +94,12 @@ func (c *Gitea) Login(ctx context.Context, w http.ResponseWriter, req *http.Requ
}, },
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.OAuthHost), RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.OAuthHost),
} }
}
// Login authenticates an account with Gitea using basic authentication. The
// Gitea account details are returned when the user is successfully authenticated.
func (c *Gitea) Login(ctx context.Context, w http.ResponseWriter, req *http.Request) (*model.User, error) {
config := c.oauth2Config()
// get the OAuth errors // get the OAuth errors
if err := req.FormValue("error"); err != "" { if err := req.FormValue("error"); err != "" {
@ -154,14 +158,9 @@ func (c *Gitea) Auth(ctx context.Context, token, secret string) (string, error)
// Refresh refreshes the Gitea oauth2 access token. If the token is // Refresh refreshes the Gitea oauth2 access token. If the token is
// refreshed the user is updated and a true value is returned. // refreshed the user is updated and a true value is returned.
func (c *Gitea) Refresh(ctx context.Context, user *model.User) (bool, error) { func (c *Gitea) Refresh(ctx context.Context, user *model.User) (bool, error) {
config := &oauth2.Config{ config := c.oauth2Config()
ClientID: c.ClientID, config.RedirectURL = ""
ClientSecret: c.ClientSecret,
Endpoint: oauth2.Endpoint{
AuthURL: fmt.Sprintf(authorizeTokenURL, c.URL),
TokenURL: fmt.Sprintf(accessTokenURL, c.URL),
},
}
source := config.TokenSource(ctx, &oauth2.Token{RefreshToken: user.Secret}) source := config.TokenSource(ctx, &oauth2.Token{RefreshToken: user.Secret})
token, err := source.Token() token, err := source.Token()

View file

@ -22,6 +22,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"time"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/xanzy/go-gitlab" "github.com/xanzy/go-gitlab"
@ -74,10 +75,8 @@ func (g *Gitlab) Name() string {
return "gitlab" return "gitlab"
} }
// Login authenticates the session and returns the func (g *Gitlab) oauth2Config() *oauth2.Config {
// remote user details. return &oauth2.Config{
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
config := &oauth2.Config{
ClientID: g.ClientID, ClientID: g.ClientID,
ClientSecret: g.ClientSecret, ClientSecret: g.ClientSecret,
Scope: defaultScope, Scope: defaultScope,
@ -85,6 +84,12 @@ func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.R
TokenURL: fmt.Sprintf("%s/oauth/token", g.URL), TokenURL: fmt.Sprintf("%s/oauth/token", g.URL),
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.OAuthHost), RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.OAuthHost),
} }
}
// Login authenticates the session and returns the
// remote user details.
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
config := g.oauth2Config()
// get the OAuth errors // get the OAuth errors
if err := req.FormValue("error"); err != "" { if err := req.FormValue("error"); err != "" {
@ -98,7 +103,7 @@ func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.R
// get the OAuth code // get the OAuth code
code := req.FormValue("code") code := req.FormValue("code")
if len(code) == 0 { if len(code) == 0 {
authCodeURL, err := config.AuthCodeURL("drone") authCodeURL, err := config.AuthCodeURL("woodpecker")
if err != nil { if err != nil {
return nil, fmt.Errorf("authCodeURL error: %v", err) return nil, fmt.Errorf("authCodeURL error: %v", err)
} }
@ -139,6 +144,35 @@ func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.R
return user, nil return user, nil
} }
// Refresh refreshes the Gitlab oauth2 access token. If the token is
// refreshed the user is updated and a true value is returned.
func (g *Gitlab) Refresh(ctx context.Context, user *model.User) (bool, error) {
config := g.oauth2Config()
config.RedirectURL = ""
trans := &oauth2.Transport{
Config: config,
Token: &oauth2.Token{
AccessToken: user.Token,
RefreshToken: user.Secret,
Expiry: time.Unix(user.Expiry, 0),
},
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
Proxy: http.ProxyFromEnvironment,
},
}
if err := trans.Refresh(); err != nil {
return false, err
}
user.Token = trans.Token.AccessToken
user.Secret = trans.Token.RefreshToken
user.Expiry = trans.Token.Expiry.UTC().Unix()
return true, nil
}
// Auth authenticates the session and returns the remote user login for the given token // Auth authenticates the session and returns the remote user login for the given token
func (g *Gitlab) Auth(ctx context.Context, token, _ string) (string, error) { func (g *Gitlab) Auth(ctx context.Context, token, _ string) (string, error) {
client, err := newClient(g.URL, token, g.SkipVerify) client, err := newClient(g.URL, token, g.SkipVerify)