Refresh tokens before any requests to remote

This commit is contained in:
Kirill Zaitsev 2015-01-27 02:32:42 +03:00
parent 9aa6c92e90
commit d225181a0f
11 changed files with 112 additions and 11 deletions

View file

@ -275,3 +275,7 @@ func (r *Bitbucket) ParseHook(req *http.Request) (*model.Hook, error) {
func (r *Bitbucket) OpenRegistration() bool {
return r.Open
}
func (r *Bitbucket) GetToken(user *model.User) (*model.Token, error) {
return nil, nil
}

View file

@ -311,3 +311,7 @@ func (r *GitHub) ParsePullRequestHook(req *http.Request) (*model.Hook, error) {
func (r *GitHub) OpenRegistration() bool {
return r.Open
}
func (r *GitHub) GetToken(user *model.User) (*model.Token, error) {
return nil, nil
}

View file

@ -6,9 +6,10 @@ import (
"net/http"
"net/url"
"strconv"
"time"
"code.google.com/p/goauth2/oauth"
"github.com/Bugagazavr/go-gitlab-client"
"github.com/drone/drone/plugin/remote/github/oauth"
"github.com/drone/drone/shared/httputil"
"github.com/drone/drone/shared/model"
)
@ -34,14 +35,8 @@ func New(url string, skipVerify, open bool, client, secret string) *Gitlab {
// Authorize handles authentication with thrid party remote systems,
// such as github or bitbucket, and returns user data.
func (r *Gitlab) Authorize(res http.ResponseWriter, req *http.Request) (*model.Login, error) {
var config = &oauth.Config{
ClientId: r.Client,
ClientSecret: r.Secret,
Scope: "api",
AuthURL: fmt.Sprintf("%s/oauth/authorize", r.url),
TokenURL: fmt.Sprintf("%s/oauth/token", r.url),
RedirectURL: fmt.Sprintf("%s/api/auth/%s", httputil.GetURL(req), r.GetKind()),
}
host := httputil.GetURL(req)
config := NewOauthConfig(r, host)
var code = req.FormValue("code")
var state = req.FormValue("state")
@ -75,6 +70,7 @@ func (r *Gitlab) Authorize(res http.ResponseWriter, req *http.Request) (*model.L
var login = new(model.Login)
login.ID = int64(user.Id)
login.Access = token.AccessToken
login.Secret = token.RefreshToken
login.Login = user.Username
login.Email = user.Email
return login, nil
@ -232,3 +228,24 @@ func (r *Gitlab) ParseHook(req *http.Request) (*model.Hook, error) {
func (r *Gitlab) OpenRegistration() bool {
return r.Open
}
func (r *Gitlab) GetToken(user *model.User) (*model.Token, error) {
expiry := time.Now().Truncate(7200 * time.Second)
t := &oauth.Transport{
Config: NewOauthConfig(r, ""),
Token: &oauth.Token{
AccessToken: user.Access,
RefreshToken: user.Secret,
Expiry: expiry,
},
}
if err := t.Refresh(); err != nil {
return nil, err
}
var token = new(model.Token)
token.AccessToken = t.Token.AccessToken
token.RefreshToken = t.Token.RefreshToken
return token, nil
}

View file

@ -5,14 +5,26 @@ import (
"fmt"
"net/url"
"code.google.com/p/goauth2/oauth"
"github.com/Bugagazavr/go-gitlab-client"
"github.com/gorilla/securecookie"
)
func NewOauthConfig(g *Gitlab, host string) *oauth.Config {
return &oauth.Config{
ClientId: g.Client,
ClientSecret: g.Secret,
Scope: "api",
AuthURL: fmt.Sprintf("%s/oauth/authorize", g.url),
TokenURL: fmt.Sprintf("%s/oauth/token", g.url),
RedirectURL: fmt.Sprintf("%s/api/auth/%s", host, g.GetKind()),
}
}
// NewClient is a helper function that returns a new GitHub
// client using the provided OAuth token.
func NewClient(uri, token string, skipVerify bool) *gogitlab.Gitlab {
client := gogitlab.NewGitlabCert(uri, "/api/v3", token, skipVerify)
func NewClient(url, accessToken string, skipVerify bool) *gogitlab.Gitlab {
client := gogitlab.NewGitlabCert(url, "/api/v3", accessToken, skipVerify)
client.Bearer = true
return client
}

View file

@ -186,3 +186,7 @@ func (r *Gogs) ParseHook(req *http.Request) (*model.Hook, error) {
func (r *Gogs) OpenRegistration() bool {
return r.Open
}
func (r *Gogs) GetToken(user *model.User) (*model.Token, error) {
return nil, nil
}

View file

@ -35,6 +35,9 @@ type Remote interface {
// Registration returns true if open registration is allowed
OpenRegistration() bool
// Get token
GetToken(*model.User) (*model.Token, error)
}
// List of registered plugins.

View file

@ -4,6 +4,7 @@ import (
"encoding/json"
"net/http"
"github.com/drone/drone/plugin/remote"
"github.com/drone/drone/server/datastore"
"github.com/drone/drone/server/worker"
"github.com/drone/drone/shared/httputil"
@ -65,7 +66,9 @@ func PostCommit(c web.C, w http.ResponseWriter, r *http.Request) {
var (
branch = c.URLParams["branch"]
hash = c.URLParams["commit"]
host = c.URLParams["host"]
repo = ToRepo(c)
remote = remote.Lookup(host)
)
commit, err := datastore.GetCommitSha(ctx, repo, branch, hash)
@ -95,6 +98,17 @@ func PostCommit(c web.C, w http.ResponseWriter, r *http.Request) {
return
}
// Request a new token and update
user_token, err := remote.GetToken(owner)
if user_token != nil {
owner.Access = user_token.AccessToken
owner.Secret = user_token.RefreshToken
datastore.PutUser(ctx, owner)
} else if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
// drop the items on the queue
go worker.Do(ctx, &worker.Work{
User: owner,

View file

@ -76,6 +76,17 @@ func PostHook(c web.C, w http.ResponseWriter, r *http.Request) {
return
}
// Request a new token and update
user_token, err := remote.GetToken(user)
if user_token != nil {
user.Access = user_token.AccessToken
user.Secret = user_token.RefreshToken
datastore.PutUser(ctx, user)
} else if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
// featch the .drone.yml file from the database
yml, err := remote.GetScript(user, repo, hook)
if err != nil {

View file

@ -104,6 +104,17 @@ func PostRepo(c web.C, w http.ResponseWriter, r *http.Request) {
return
}
// Request a new token and update
user_token, err := remote.GetToken(user)
if user_token != nil {
user.Access = user_token.AccessToken
user.Secret = user_token.RefreshToken
datastore.PutUser(ctx, user)
} else if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}
// setup the post-commit hook with the remote system and
// if necessary, register the public key
var hook = fmt.Sprintf("%s/api/hook/%s/%s", httputil.GetURL(r), repo.Remote, repo.Token)

View file

@ -158,6 +158,16 @@ func PostUserSync(c web.C, w http.ResponseWriter, r *http.Request) {
return
}
// Request a new token and update
user_token, err := remote.GetToken(user)
if user_token != nil {
user.Access = user_token.AccessToken
user.Secret = user_token.RefreshToken
} else if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
user.Syncing = true
if err := datastore.PutUser(ctx, user); err != nil {
w.WriteHeader(http.StatusNotFound)

11
shared/model/token.go Normal file
View file

@ -0,0 +1,11 @@
package model
import (
"time"
)
type Token struct {
AccessToken string
RefreshToken string
Expiry time.Time
}