func SetUser() gin.HandlerFunc { return func(c *gin.Context) { var user *model.User t, err := token.ParseRequest(c.Request, func(t *token.Token) (string, error) { var err error user, err = store.GetUserLogin(c, t.Text) return user.Hash, err }) if err == nil { confv := c.MustGet("config") if conf, ok := confv.(*model.Config); ok { user.Admin = conf.IsAdmin(user) } c.Set("user", user) // if this is a session token (ie not the API token) // this means the user is accessing with a web browser, // so we should implement CSRF protection measures. if t.Kind == token.SessToken { err = token.CheckCsrf(c.Request, func(t *token.Token) (string, error) { return user.Hash, nil }) // if csrf token validation fails, exit immediately // with a not authorized error. if err != nil { c.AbortWithStatus(http.StatusUnauthorized) return } } } c.Next() } }
// Refresh refreshes an oauth token and expiration for the given // user. It returns true if the token was refreshed, false if the // token was not refreshed, and error if it failed to refersh. func (bb *Bitbucket) Refresh(user *model.User) (bool, error) { config := &oauth2.Config{ ClientID: bb.Client, ClientSecret: bb.Secret, Endpoint: bitbucket.Endpoint, } // creates a token source with just the refresh token. // this will ensure an access token is automatically // requested. source := config.TokenSource( oauth2.NoContext, &oauth2.Token{RefreshToken: user.Secret}) // requesting the token automatically refreshes and // returns a new access token. token, err := source.Token() if err != nil || len(token.AccessToken) == 0 { return false, err } // update the user to include tne new access token user.Token = token.AccessToken user.Secret = token.RefreshToken user.Expiry = token.Expiry.UTC().Unix() return true, nil }
// Login authenticates the session and returns the // remote user details. func (g *Github) Login(res http.ResponseWriter, req *http.Request) (*model.User, bool, error) { var config = &oauth2.Config{ ClientId: g.Client, ClientSecret: g.Secret, Scope: DefaultScope, AuthURL: fmt.Sprintf("%s/login/oauth/authorize", g.URL), TokenURL: fmt.Sprintf("%s/login/oauth/access_token", g.URL), RedirectURL: fmt.Sprintf("%s/authorize", httputil.GetURL(req)), } // get the OAuth code var code = req.FormValue("code") if len(code) == 0 { var random = GetRandom() http.Redirect(res, req, config.AuthCodeURL(random), http.StatusSeeOther) return nil, false, nil } var trans = &oauth2.Transport{ Config: config, } if g.SkipVerify { trans.Transport = &http.Transport{ Proxy: http.ProxyFromEnvironment, TLSClientConfig: &tls.Config{ InsecureSkipVerify: true, }, } } var token, err = trans.Exchange(code) if err != nil { return nil, false, fmt.Errorf("Error exchanging token. %s", err) } var client = NewClient(g.API, token.AccessToken, g.SkipVerify) var useremail, errr = GetUserEmail(client) if errr != nil { return nil, false, fmt.Errorf("Error retrieving user or verified email. %s", errr) } if len(g.Orgs) > 0 { allowedOrg, err := UserBelongsToOrg(client, g.Orgs) if err != nil { return nil, false, fmt.Errorf("Could not check org membership. %s", err) } if !allowedOrg { return nil, false, fmt.Errorf("User does not belong to correct org. Must belong to %v", g.Orgs) } } user := model.User{} user.Login = *useremail.Login user.Email = *useremail.Email user.Token = token.AccessToken user.Avatar = *useremail.AvatarURL return &user, g.Open, nil }
// Login authenticates the session and returns the // remote user details. func (g *Gogs) Login(res http.ResponseWriter, req *http.Request) (*model.User, bool, error) { var ( username = req.FormValue("username") password = req.FormValue("password") ) // if the username or password doesn't exist we re-direct // the user to the login screen. if len(username) == 0 || len(password) == 0 { http.Redirect(res, req, "/login/form", http.StatusSeeOther) return nil, false, nil } client := gogs.NewClient(g.URL, "") // try to fetch drone token if it exists var accessToken string tokens, err := client.ListAccessTokens(username, password) if err != nil { return nil, false, err } for _, token := range tokens { if token.Name == "drone" { accessToken = token.Sha1 break } } // if drone token not found, create it if accessToken == "" { token, err := client.CreateAccessToken(username, password, gogs.CreateAccessTokenOption{Name: "drone"}) if err != nil { return nil, false, err } accessToken = token.Sha1 } client = gogs.NewClient(g.URL, accessToken) userInfo, err := client.GetUserInfo(username) if err != nil { return nil, false, err } user := model.User{} user.Token = accessToken user.Login = userInfo.UserName user.Email = userInfo.Email user.Avatar = expandAvatar(g.URL, userInfo.AvatarUrl) return &user, g.Open, nil }
// Login authenticates the session and returns the // remote user details. func (bb *Bitbucket) Login(res http.ResponseWriter, req *http.Request) (*model.User, bool, error) { config := &oauth2.Config{ ClientID: bb.Client, ClientSecret: bb.Secret, Endpoint: bitbucket.Endpoint, RedirectURL: fmt.Sprintf("%s/authorize", httputil.GetURL(req)), } // get the OAuth code var code = req.FormValue("code") if len(code) == 0 { http.Redirect(res, req, config.AuthCodeURL("drone"), http.StatusSeeOther) return nil, false, nil } var token, err = config.Exchange(oauth2.NoContext, code) if err != nil { return nil, false, fmt.Errorf("Error exchanging token. %s", err) } client := NewClient(config.Client(oauth2.NoContext, token)) curr, err := client.FindCurrent() if err != nil { return nil, false, err } // convers the current bitbucket user to the // common drone user structure. user := model.User{} user.Login = curr.Login user.Token = token.AccessToken user.Secret = token.RefreshToken user.Expiry = token.Expiry.UTC().Unix() user.Avatar = curr.Links.Avatar.Href // gets the primary, confirmed email from bitbucket emails, err := client.ListEmail() if err != nil { return nil, false, err } for _, email := range emails.Values { if email.IsPrimary && email.IsConfirmed { user.Email = email.Email break } } // if the installation is restricted to a subset // of organizations, get the orgs and verify the // user is a member. if len(bb.Orgs) != 0 { resp, err := client.ListTeams(&ListTeamOpts{Page: 1, PageLen: 100, Role: "member"}) if err != nil { return nil, false, err } var member bool for _, team := range resp.Values { for _, team_ := range bb.Orgs { if team.Login == team_ { member = true break } } } if !member { return nil, false, fmt.Errorf("User does not belong to correct org. Must belong to %v", bb.Orgs) } } return &user, bb.Open, nil }