mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	first works oauth2(github). need to login with /user/login/github
This commit is contained in:
		@@ -1,6 +1,6 @@
 | 
			
		||||
package models
 | 
			
		||||
 | 
			
		||||
import "time"
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
// OT: Oauth2 Type
 | 
			
		||||
const (
 | 
			
		||||
@@ -14,5 +14,26 @@ type Oauth2 struct {
 | 
			
		||||
	Type     int    `xorm:"pk unique(oauth)"` // twitter,github,google...
 | 
			
		||||
	Identity string `xorm:"pk unique(oauth)"` // id..
 | 
			
		||||
	Token    string `xorm:"VARCHAR(200) not null"`
 | 
			
		||||
	RefreshTime time.Time `xorm:"created"`
 | 
			
		||||
	//RefreshTime time.Time `xorm:"created"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func AddOauth2(oa *Oauth2) (err error) {
 | 
			
		||||
	if _, err = orm.Insert(oa); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func GetOauth2User(identity string) (u *User, err error) {
 | 
			
		||||
	oa := &Oauth2{}
 | 
			
		||||
	oa.Identity = identity
 | 
			
		||||
	exists, err := orm.Get(oa)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if !exists {
 | 
			
		||||
		err = fmt.Errorf("not exists oauth2: %s", identity)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return GetUserById(oa.Uid)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,45 +5,114 @@ package user
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	"github.com/gogits/gogs/models"
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
	"github.com/gogits/gogs/modules/middleware"
 | 
			
		||||
	//"github.com/gogits/gogs/modules/oauth2"
 | 
			
		||||
 | 
			
		||||
	"code.google.com/p/goauth2/oauth"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
	"github.com/gogits/gogs/modules/oauth2"
 | 
			
		||||
	"github.com/martini-contrib/oauth2"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// github && google && ...
 | 
			
		||||
func SocialSignIn(tokens oauth2.Tokens) {
 | 
			
		||||
	transport := &oauth.Transport{}
 | 
			
		||||
	transport.Token = &oauth.Token{
 | 
			
		||||
		AccessToken:  tokens.Access(),
 | 
			
		||||
		RefreshToken: tokens.Refresh(),
 | 
			
		||||
		Expiry:       tokens.ExpiryTime(),
 | 
			
		||||
		Extra:        tokens.ExtraData(),
 | 
			
		||||
	}
 | 
			
		||||
type SocialConnector interface {
 | 
			
		||||
	Identity() string
 | 
			
		||||
	Type() int
 | 
			
		||||
	Name() string
 | 
			
		||||
	Email() string
 | 
			
		||||
	Token() string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	// Github API refer: https://developer.github.com/v3/users/
 | 
			
		||||
	// FIXME: need to judge url
 | 
			
		||||
	type GithubUser struct {
 | 
			
		||||
type SocialGithub struct {
 | 
			
		||||
	data struct {
 | 
			
		||||
		Id    int    `json:"id"`
 | 
			
		||||
		Name  string `json:"login"`
 | 
			
		||||
		Email string `json:"email"`
 | 
			
		||||
	}
 | 
			
		||||
	WebToken *oauth.Token
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
	// Make the request.
 | 
			
		||||
func (s *SocialGithub) Identity() string {
 | 
			
		||||
	return strconv.Itoa(s.data.Id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SocialGithub) Type() int {
 | 
			
		||||
	return models.OT_GITHUB
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SocialGithub) Name() string {
 | 
			
		||||
	return s.data.Name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SocialGithub) Email() string {
 | 
			
		||||
	return s.data.Email
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (s *SocialGithub) Token() string {
 | 
			
		||||
	data, _ := json.Marshal(s.WebToken)
 | 
			
		||||
	return string(data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Github API refer: https://developer.github.com/v3/users/
 | 
			
		||||
func (s *SocialGithub) Update() error {
 | 
			
		||||
	scope := "https://api.github.com/user"
 | 
			
		||||
	transport := &oauth.Transport{
 | 
			
		||||
		Token: s.WebToken,
 | 
			
		||||
	}
 | 
			
		||||
	log.Debug("update github info")
 | 
			
		||||
	r, err := transport.Client().Get(scope)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("connect with github error: %s", err)
 | 
			
		||||
		// FIXME: handle error page
 | 
			
		||||
		return
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer r.Body.Close()
 | 
			
		||||
 | 
			
		||||
	user := &GithubUser{}
 | 
			
		||||
	err = json.NewDecoder(r.Body).Decode(user)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Error("Get: %s", err)
 | 
			
		||||
	}
 | 
			
		||||
	log.Info("login: %s", user.Name)
 | 
			
		||||
	// FIXME: login here, user email to check auth, if not registe, then generate a uniq username
 | 
			
		||||
	return json.NewDecoder(r.Body).Decode(&s.data)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// github && google && ...
 | 
			
		||||
func SocialSignIn(ctx *middleware.Context, tokens oauth2.Tokens) {
 | 
			
		||||
	gh := &SocialGithub{
 | 
			
		||||
		WebToken: &oauth.Token{
 | 
			
		||||
			AccessToken:  tokens.Access(),
 | 
			
		||||
			RefreshToken: tokens.Refresh(),
 | 
			
		||||
			Expiry:       tokens.ExpiryTime(),
 | 
			
		||||
			Extra:        tokens.ExtraData(),
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	var err error
 | 
			
		||||
	var u *models.User
 | 
			
		||||
	if err = gh.Update(); err != nil {
 | 
			
		||||
		// FIXME: handle error page
 | 
			
		||||
		log.Error("connect with github error: %s", err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	var soc SocialConnector = gh
 | 
			
		||||
	log.Info("login: %s", soc.Name())
 | 
			
		||||
	// FIXME: login here, user email to check auth, if not registe, then generate a uniq username
 | 
			
		||||
	if u, err = models.GetOauth2User(soc.Identity()); err != nil {
 | 
			
		||||
		u = &models.User{
 | 
			
		||||
			Name:     soc.Name(),
 | 
			
		||||
			Email:    soc.Email(),
 | 
			
		||||
			Passwd:   "123456",
 | 
			
		||||
			IsActive: !base.Service.RegisterEmailConfirm,
 | 
			
		||||
		}
 | 
			
		||||
		if u, err = models.RegisterUser(u); err != nil {
 | 
			
		||||
			log.Error("register user: %v", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		oa := &models.Oauth2{}
 | 
			
		||||
		oa.Uid = u.Id
 | 
			
		||||
		oa.Type = soc.Type()
 | 
			
		||||
		oa.Token = soc.Token()
 | 
			
		||||
		oa.Identity = soc.Identity()
 | 
			
		||||
		log.Info("oa: %v", oa)
 | 
			
		||||
		if err = models.AddOauth2(oa); err != nil {
 | 
			
		||||
			log.Error("add oauth2 %v", err)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ctx.Session.Set("userId", u.Id)
 | 
			
		||||
	ctx.Session.Set("userName", u.Name)
 | 
			
		||||
	ctx.Redirect("/")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								web.go
									
									
									
									
									
								
							@@ -20,13 +20,16 @@ import (
 | 
			
		||||
	"github.com/gogits/gogs/modules/base"
 | 
			
		||||
	"github.com/gogits/gogs/modules/log"
 | 
			
		||||
	"github.com/gogits/gogs/modules/middleware"
 | 
			
		||||
	"github.com/gogits/gogs/modules/oauth2"
 | 
			
		||||
	//"github.com/gogits/gogs/modules/oauth2"
 | 
			
		||||
	"github.com/gogits/gogs/routers"
 | 
			
		||||
	"github.com/gogits/gogs/routers/admin"
 | 
			
		||||
	"github.com/gogits/gogs/routers/api/v1"
 | 
			
		||||
	"github.com/gogits/gogs/routers/dev"
 | 
			
		||||
	"github.com/gogits/gogs/routers/repo"
 | 
			
		||||
	"github.com/gogits/gogs/routers/user"
 | 
			
		||||
 | 
			
		||||
	"github.com/martini-contrib/oauth2"
 | 
			
		||||
	"github.com/martini-contrib/sessions"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var CmdWeb = cli.Command{
 | 
			
		||||
@@ -61,6 +64,7 @@ func runWeb(*cli.Context) {
 | 
			
		||||
 | 
			
		||||
	scope := "https://api.github.com/user"
 | 
			
		||||
	oauth2.PathCallback = "/oauth2callback"
 | 
			
		||||
	m.Use(sessions.Sessions("my_session", sessions.NewCookieStore([]byte("secret123"))))
 | 
			
		||||
	m.Use(oauth2.Github(&oauth2.Options{
 | 
			
		||||
		ClientId:     "09383403ff2dc16daaa1",
 | 
			
		||||
		ClientSecret: "5f6e7101d30b77952aab22b75eadae17551ea6b5",
 | 
			
		||||
@@ -88,7 +92,7 @@ func runWeb(*cli.Context) {
 | 
			
		||||
	m.Get("/avatar/:hash", avt.ServeHTTP)
 | 
			
		||||
 | 
			
		||||
	m.Group("/user", func(r martini.Router) {
 | 
			
		||||
		r.Any("/login/github", user.SocialSignIn)
 | 
			
		||||
		r.Any("/login/github", reqSignOut, oauth2.LoginRequired, user.SocialSignIn)
 | 
			
		||||
		r.Any("/login", binding.BindIgnErr(auth.LogInForm{}), user.SignIn)
 | 
			
		||||
		r.Any("/sign_up", binding.BindIgnErr(auth.RegisterForm{}), user.SignUp)
 | 
			
		||||
		r.Any("/forget_password", user.ForgotPasswd)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user