mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-11-04 10:44:12 +01:00 
			
		
		
		
	Merge branch 'dev' of github.com:gogits/gogs into dev
This commit is contained in:
		
						commit
						d60f7b85e5
					
				@ -13,6 +13,7 @@ const (
 | 
				
			|||||||
	OT_GITHUB = iota + 1
 | 
						OT_GITHUB = iota + 1
 | 
				
			||||||
	OT_GOOGLE
 | 
						OT_GOOGLE
 | 
				
			||||||
	OT_TWITTER
 | 
						OT_TWITTER
 | 
				
			||||||
 | 
						OT_QQ
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
@ -26,7 +27,7 @@ type Oauth2 struct {
 | 
				
			|||||||
	User     *User  `xorm:"-"`
 | 
						User     *User  `xorm:"-"`
 | 
				
			||||||
	Type     int    `xorm:"unique(s) unique(oauth)"` // twitter,github,google...
 | 
						Type     int    `xorm:"unique(s) unique(oauth)"` // twitter,github,google...
 | 
				
			||||||
	Identity string `xorm:"unique(s) unique(oauth)"` // id..
 | 
						Identity string `xorm:"unique(s) unique(oauth)"` // id..
 | 
				
			||||||
	Token    string `xorm:"VARCHAR(200) not null"`
 | 
						Token    string `xorm:"TEXT not null"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BindUserOauth2(userId, oauthId int64) error {
 | 
					func BindUserOauth2(userId, oauthId int64) error {
 | 
				
			||||||
@ -48,7 +49,7 @@ func GetOauth2(identity string) (oa *Oauth2, err error) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	} else if !isExist {
 | 
						} else if !isExist {
 | 
				
			||||||
		return nil, ErrOauth2RecordNotExists
 | 
							return nil, ErrOauth2RecordNotExists
 | 
				
			||||||
	} else if oa.Uid == 0 {
 | 
						} else if oa.Uid == -1 {
 | 
				
			||||||
		return oa, ErrOauth2NotAssociatedWithUser
 | 
							return oa, ErrOauth2NotAssociatedWithUser
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	oa.User, err = GetUserById(oa.Uid)
 | 
						oa.User, err = GetUserById(oa.Uid)
 | 
				
			||||||
 | 
				
			|||||||
@ -6,65 +6,32 @@ package user
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"net/http"
 | 
						"fmt"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"strconv"
 | 
					 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.google.com/p/goauth2/oauth"
 | 
						"code.google.com/p/goauth2/oauth"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/go-martini/martini"
 | 
				
			||||||
	"github.com/gogits/gogs/models"
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/base"
 | 
						"github.com/gogits/gogs/modules/base"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/log"
 | 
						"github.com/gogits/gogs/modules/log"
 | 
				
			||||||
	"github.com/gogits/gogs/modules/middleware"
 | 
						"github.com/gogits/gogs/modules/middleware"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type BasicUserInfo struct {
 | 
				
			||||||
 | 
						Identity string
 | 
				
			||||||
 | 
						Name     string
 | 
				
			||||||
 | 
						Email    string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SocialConnector interface {
 | 
					type SocialConnector interface {
 | 
				
			||||||
	Identity() string
 | 
						Type() int
 | 
				
			||||||
	Name() string
 | 
						SetRedirectUrl(string)
 | 
				
			||||||
	Email() string
 | 
						UserInfo(*oauth.Token, *url.URL) (*BasicUserInfo, error)
 | 
				
			||||||
	TokenString() string
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SocialGithub struct {
 | 
						AuthCodeURL(string) string
 | 
				
			||||||
	data struct {
 | 
						Exchange(string) (*oauth.Token, error)
 | 
				
			||||||
		Id    int    `json:"id"`
 | 
					 | 
				
			||||||
		Name  string `json:"login"`
 | 
					 | 
				
			||||||
		Email string `json:"email"`
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	Token *oauth.Token
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SocialGithub) Identity() string {
 | 
					 | 
				
			||||||
	return strconv.Itoa(s.data.Id)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SocialGithub) Name() string {
 | 
					 | 
				
			||||||
	return s.data.Name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SocialGithub) Email() string {
 | 
					 | 
				
			||||||
	return s.data.Email
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (s *SocialGithub) TokenString() string {
 | 
					 | 
				
			||||||
	data, _ := json.Marshal(s.Token)
 | 
					 | 
				
			||||||
	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.Token,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	log.Debug("update github info")
 | 
					 | 
				
			||||||
	r, err := transport.Client().Get(scope)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	defer r.Body.Close()
 | 
					 | 
				
			||||||
	return json.NewDecoder(r.Body).Decode(&s.data)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func extractPath(next string) string {
 | 
					func extractPath(next string) string {
 | 
				
			||||||
@ -75,85 +42,76 @@ func extractPath(next string) string {
 | 
				
			|||||||
	return n.Path
 | 
						return n.Path
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// github && google && ...
 | 
					var (
 | 
				
			||||||
func SocialSignIn(ctx *middleware.Context) {
 | 
						SocialBaseUrl = "/user/login"
 | 
				
			||||||
	//if base.OauthService != nil && base.OauthService.GitHub.Enabled {
 | 
						SocialMap     = make(map[string]SocialConnector)
 | 
				
			||||||
	//}
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var socid int64
 | 
					// github && google && ...
 | 
				
			||||||
	var ok bool
 | 
					func SocialSignIn(params martini.Params, ctx *middleware.Context) {
 | 
				
			||||||
	next := extractPath(ctx.Query("next"))
 | 
						if base.OauthService == nil || !base.OauthService.GitHub.Enabled {
 | 
				
			||||||
	log.Debug("social signed check %s", next)
 | 
							ctx.Handle(404, "social login not enabled", nil)
 | 
				
			||||||
	if socid, ok = ctx.Session.Get("socialId").(int64); ok && socid != 0 {
 | 
					 | 
				
			||||||
		// already login
 | 
					 | 
				
			||||||
		ctx.Redirect(next)
 | 
					 | 
				
			||||||
		log.Info("login soc id: %v", socid)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						next := extractPath(ctx.Query("next"))
 | 
				
			||||||
	config := &oauth.Config{
 | 
						name := params["name"]
 | 
				
			||||||
		ClientId:     base.OauthService.GitHub.ClientId,
 | 
						connect, ok := SocialMap[name]
 | 
				
			||||||
		ClientSecret: base.OauthService.GitHub.ClientSecret,
 | 
						if !ok {
 | 
				
			||||||
		RedirectURL:  strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.RequestURI(),
 | 
							ctx.Handle(404, "social login", nil)
 | 
				
			||||||
		Scope:        base.OauthService.GitHub.Scopes,
 | 
							return
 | 
				
			||||||
		AuthURL:      "https://github.com/login/oauth/authorize",
 | 
					 | 
				
			||||||
		TokenURL:     "https://github.com/login/oauth/access_token",
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	transport := &oauth.Transport{
 | 
					 | 
				
			||||||
		Config:    config,
 | 
					 | 
				
			||||||
		Transport: http.DefaultTransport,
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	code := ctx.Query("code")
 | 
						code := ctx.Query("code")
 | 
				
			||||||
	if code == "" {
 | 
						if code == "" {
 | 
				
			||||||
		// redirect to social login page
 | 
							// redirect to social login page
 | 
				
			||||||
		ctx.Redirect(config.AuthCodeURL(next))
 | 
							connect.SetRedirectUrl(strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.Host + ctx.Req.URL.Path)
 | 
				
			||||||
 | 
							ctx.Redirect(connect.AuthCodeURL(next))
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// handle call back
 | 
						// handle call back
 | 
				
			||||||
	tk, err := transport.Exchange(code)
 | 
						tk, err := connect.Exchange(code) // exchange for token
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Error("oauth2 handle callback error: %v", err)
 | 
							log.Error("oauth2 handle callback error: %v", err)
 | 
				
			||||||
		return // FIXME, need error page 501
 | 
							ctx.Handle(500, "exchange code error", nil)
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	next = extractPath(ctx.Query("state"))
 | 
					 | 
				
			||||||
	log.Debug("success token: %v", tk)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	gh := &SocialGithub{Token: tk}
 | 
					 | 
				
			||||||
	if err = gh.Update(); err != nil {
 | 
					 | 
				
			||||||
		// FIXME: handle error page 501
 | 
					 | 
				
			||||||
		log.Error("connect with github error: %s", err)
 | 
					 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var soc SocialConnector = gh
 | 
						next = extractPath(ctx.Query("state"))
 | 
				
			||||||
	log.Info("login: %s", soc.Name())
 | 
						log.Trace("success get token")
 | 
				
			||||||
	oa, err := models.GetOauth2(soc.Identity())
 | 
					
 | 
				
			||||||
 | 
						ui, err := connect.UserInfo(tk, ctx.Req.URL)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							ctx.Handle(500, fmt.Sprintf("get infomation from %s error: %v", name, err), nil)
 | 
				
			||||||
 | 
							log.Error("social connect error: %s", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						log.Info("social login: %s", ui)
 | 
				
			||||||
 | 
						oa, err := models.GetOauth2(ui.Identity)
 | 
				
			||||||
	switch err {
 | 
						switch err {
 | 
				
			||||||
	case nil:
 | 
						case nil:
 | 
				
			||||||
		ctx.Session.Set("userId", oa.User.Id)
 | 
							ctx.Session.Set("userId", oa.User.Id)
 | 
				
			||||||
		ctx.Session.Set("userName", oa.User.Name)
 | 
							ctx.Session.Set("userName", oa.User.Name)
 | 
				
			||||||
	case models.ErrOauth2RecordNotExists:
 | 
						case models.ErrOauth2RecordNotExists:
 | 
				
			||||||
		oa = &models.Oauth2{}
 | 
							oa = &models.Oauth2{}
 | 
				
			||||||
 | 
							raw, _ := json.Marshal(tk) // json encode
 | 
				
			||||||
 | 
							oa.Token = string(raw)
 | 
				
			||||||
		oa.Uid = -1
 | 
							oa.Uid = -1
 | 
				
			||||||
		oa.Type = models.OT_GITHUB
 | 
							oa.Type = connect.Type()
 | 
				
			||||||
		oa.Token = soc.TokenString()
 | 
							oa.Identity = ui.Identity
 | 
				
			||||||
		oa.Identity = soc.Identity()
 | 
							log.Trace("oa: %v", oa)
 | 
				
			||||||
		log.Debug("oa: %v", oa)
 | 
					 | 
				
			||||||
		if err = models.AddOauth2(oa); err != nil {
 | 
							if err = models.AddOauth2(oa); err != nil {
 | 
				
			||||||
			log.Error("add oauth2 %v", err) // 501
 | 
								log.Error("add oauth2 %v", err) // 501
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	case models.ErrOauth2NotAssociatedWithUser:
 | 
						case models.ErrOauth2NotAssociatedWithUser:
 | 
				
			||||||
		ctx.Session.Set("socialId", oa.Id)
 | 
							next = "/user/sign_up"
 | 
				
			||||||
		ctx.Session.Set("socialName", soc.Name())
 | 
					 | 
				
			||||||
		ctx.Session.Set("socialEmail", soc.Email())
 | 
					 | 
				
			||||||
		ctx.Redirect("/user/sign_up")
 | 
					 | 
				
			||||||
		return
 | 
					 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		log.Error(err.Error()) // FIXME: handle error page
 | 
							log.Error("other error: %v", err)
 | 
				
			||||||
 | 
							ctx.Handle(500, err.Error(), nil)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ctx.Session.Set("socialId", oa.Id)
 | 
						ctx.Session.Set("socialId", oa.Id)
 | 
				
			||||||
	log.Debug("socialId: %v", oa.Id)
 | 
						ctx.Session.Set("socialName", ui.Name)
 | 
				
			||||||
 | 
						ctx.Session.Set("socialEmail", ui.Email)
 | 
				
			||||||
 | 
						log.Trace("socialId: %v", oa.Id)
 | 
				
			||||||
	ctx.Redirect(next)
 | 
						ctx.Redirect(next)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										73
									
								
								routers/user/social_github.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								routers/user/social_github.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					// Copyright 2014 The Gogs Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.google.com/p/goauth2/oauth"
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/modules/base"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SocialGithub struct {
 | 
				
			||||||
 | 
						Token *oauth.Token
 | 
				
			||||||
 | 
						*oauth.Transport
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGithub) Type() int {
 | 
				
			||||||
 | 
						return models.OT_GITHUB
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						github := &SocialGithub{}
 | 
				
			||||||
 | 
						name := "github"
 | 
				
			||||||
 | 
						config := &oauth.Config{
 | 
				
			||||||
 | 
							ClientId:     "09383403ff2dc16daaa1",                                       //base.OauthService.GitHub.ClientId, // FIXME: panic when set
 | 
				
			||||||
 | 
							ClientSecret: "0e4aa0c3630df396cdcea01a9d45cacf79925fea",                   //base.OauthService.GitHub.ClientSecret,
 | 
				
			||||||
 | 
							RedirectURL:  strings.TrimSuffix(base.AppUrl, "/") + "/user/login/" + name, //ctx.Req.URL.RequestURI(),
 | 
				
			||||||
 | 
							Scope:        "https://api.github.com/user",
 | 
				
			||||||
 | 
							AuthURL:      "https://github.com/login/oauth/authorize",
 | 
				
			||||||
 | 
							TokenURL:     "https://github.com/login/oauth/access_token",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						github.Transport = &oauth.Transport{
 | 
				
			||||||
 | 
							Config:    config,
 | 
				
			||||||
 | 
							Transport: http.DefaultTransport,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SocialMap[name] = github
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGithub) SetRedirectUrl(url string) {
 | 
				
			||||||
 | 
						s.Transport.Config.RedirectURL = url
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGithub) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
 | 
				
			||||||
 | 
						transport := &oauth.Transport{
 | 
				
			||||||
 | 
							Token: token,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var data struct {
 | 
				
			||||||
 | 
							Id    int    `json:"id"`
 | 
				
			||||||
 | 
							Name  string `json:"login"`
 | 
				
			||||||
 | 
							Email string `json:"email"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						r, err := transport.Client().Get(s.Transport.Scope)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &BasicUserInfo{
 | 
				
			||||||
 | 
							Identity: strconv.Itoa(data.Id),
 | 
				
			||||||
 | 
							Name:     data.Name,
 | 
				
			||||||
 | 
							Email:    data.Email,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								routers/user/social_google.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								routers/user/social_google.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					// Copyright 2014 The Gogs Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.google.com/p/goauth2/oauth"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SocialGoogle struct {
 | 
				
			||||||
 | 
						Token *oauth.Token
 | 
				
			||||||
 | 
						*oauth.Transport
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGoogle) Type() int {
 | 
				
			||||||
 | 
						return models.OT_GOOGLE
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						google := &SocialGoogle{}
 | 
				
			||||||
 | 
						name := "google"
 | 
				
			||||||
 | 
						// get client id and secret from
 | 
				
			||||||
 | 
						// https://console.developers.google.com/project
 | 
				
			||||||
 | 
						config := &oauth.Config{
 | 
				
			||||||
 | 
							ClientId:     "849753812404-mpd7ilvlb8c7213qn6bre6p6djjskti9.apps.googleusercontent.com", //base.OauthService.GitHub.ClientId, // FIXME: panic when set
 | 
				
			||||||
 | 
							ClientSecret: "VukKc4MwaJUSmiyv3D7ANVCa",                                                 //base.OauthService.GitHub.ClientSecret,
 | 
				
			||||||
 | 
							Scope:        "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile",
 | 
				
			||||||
 | 
							AuthURL:      "https://accounts.google.com/o/oauth2/auth",
 | 
				
			||||||
 | 
							TokenURL:     "https://accounts.google.com/o/oauth2/token",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						google.Transport = &oauth.Transport{
 | 
				
			||||||
 | 
							Config:    config,
 | 
				
			||||||
 | 
							Transport: http.DefaultTransport,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SocialMap[name] = google
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGoogle) SetRedirectUrl(url string) {
 | 
				
			||||||
 | 
						s.Transport.Config.RedirectURL = url
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialGoogle) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
 | 
				
			||||||
 | 
						transport := &oauth.Transport{Token: token}
 | 
				
			||||||
 | 
						var data struct {
 | 
				
			||||||
 | 
							Id    string `json:"id"`
 | 
				
			||||||
 | 
							Name  string `json:"name"`
 | 
				
			||||||
 | 
							Email string `json:"email"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						reqUrl := "https://www.googleapis.com/oauth2/v1/userinfo"
 | 
				
			||||||
 | 
						r, err := transport.Client().Get(reqUrl)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &BasicUserInfo{
 | 
				
			||||||
 | 
							Identity: data.Id,
 | 
				
			||||||
 | 
							Name:     data.Name,
 | 
				
			||||||
 | 
							Email:    data.Email,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										83
									
								
								routers/user/social_qq.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								routers/user/social_qq.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,83 @@
 | 
				
			|||||||
 | 
					// Copyright 2014 The Gogs Authors. All rights reserved.
 | 
				
			||||||
 | 
					// Use of this source code is governed by a MIT-style
 | 
				
			||||||
 | 
					// license that can be found in the LICENSE file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// api reference: http://wiki.open.t.qq.com/index.php/OAuth2.0%E9%89%B4%E6%9D%83/Authorization_code%E6%8E%88%E6%9D%83%E6%A1%88%E4%BE%8B
 | 
				
			||||||
 | 
					package user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
 | 
						"github.com/gogits/gogs/models"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.google.com/p/goauth2/oauth"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type SocialQQ struct {
 | 
				
			||||||
 | 
						Token *oauth.Token
 | 
				
			||||||
 | 
						*oauth.Transport
 | 
				
			||||||
 | 
						reqUrl string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialQQ) Type() int {
 | 
				
			||||||
 | 
						return models.OT_QQ
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						qq := &SocialQQ{}
 | 
				
			||||||
 | 
						name := "qq"
 | 
				
			||||||
 | 
						config := &oauth.Config{
 | 
				
			||||||
 | 
							ClientId:     "801497180",                        //base.OauthService.GitHub.ClientId, // FIXME: panic when set
 | 
				
			||||||
 | 
							ClientSecret: "16cd53b8ad2e16a36fc2c8f87d9388f2", //base.OauthService.GitHub.ClientSecret,
 | 
				
			||||||
 | 
							Scope:        "all",
 | 
				
			||||||
 | 
							AuthURL:      "https://open.t.qq.com/cgi-bin/oauth2/authorize",
 | 
				
			||||||
 | 
							TokenURL:     "https://open.t.qq.com/cgi-bin/oauth2/access_token",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						qq.reqUrl = "https://open.t.qq.com/api/user/info"
 | 
				
			||||||
 | 
						qq.Transport = &oauth.Transport{
 | 
				
			||||||
 | 
							Config:    config,
 | 
				
			||||||
 | 
							Transport: http.DefaultTransport,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						SocialMap[name] = qq
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialQQ) SetRedirectUrl(url string) {
 | 
				
			||||||
 | 
						s.Transport.Config.RedirectURL = url
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *SocialQQ) UserInfo(token *oauth.Token, URL *url.URL) (*BasicUserInfo, error) {
 | 
				
			||||||
 | 
						var data struct {
 | 
				
			||||||
 | 
							Data struct {
 | 
				
			||||||
 | 
								Id    string `json:"openid"`
 | 
				
			||||||
 | 
								Name  string `json:"name"`
 | 
				
			||||||
 | 
								Email string `json:"email"`
 | 
				
			||||||
 | 
							} `json:"data"`
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						// https://open.t.qq.com/api/user/info?
 | 
				
			||||||
 | 
						//oauth_consumer_key=APP_KEY&
 | 
				
			||||||
 | 
						//access_token=ACCESSTOKEN&openid=openid
 | 
				
			||||||
 | 
						//clientip=CLIENTIP&oauth_version=2.a
 | 
				
			||||||
 | 
						//scope=all
 | 
				
			||||||
 | 
						var urls = url.Values{
 | 
				
			||||||
 | 
							"oauth_consumer_key": {s.Transport.Config.ClientId},
 | 
				
			||||||
 | 
							"access_token":       {token.AccessToken},
 | 
				
			||||||
 | 
							"openid":             URL.Query()["openid"],
 | 
				
			||||||
 | 
							"oauth_version":      {"2.a"},
 | 
				
			||||||
 | 
							"scope":              {"all"},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						r, err := http.Get(s.reqUrl + "?" + urls.Encode())
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
						if err = json.NewDecoder(r.Body).Decode(&data); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &BasicUserInfo{
 | 
				
			||||||
 | 
							Identity: data.Data.Id,
 | 
				
			||||||
 | 
							Name:     data.Data.Name,
 | 
				
			||||||
 | 
							Email:    data.Data.Email,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										2
									
								
								web.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								web.go
									
									
									
									
									
								
							@ -88,7 +88,7 @@ func runWeb(*cli.Context) {
 | 
				
			|||||||
	m.Group("/user", func(r martini.Router) {
 | 
						m.Group("/user", func(r martini.Router) {
 | 
				
			||||||
		r.Get("/login", user.SignIn)
 | 
							r.Get("/login", user.SignIn)
 | 
				
			||||||
		r.Post("/login", bindIgnErr(auth.LogInForm{}), user.SignInPost)
 | 
							r.Post("/login", bindIgnErr(auth.LogInForm{}), user.SignInPost)
 | 
				
			||||||
		r.Get("/login/github", user.SocialSignIn)
 | 
							r.Get("/login/:name", user.SocialSignIn)
 | 
				
			||||||
		r.Get("/sign_up", user.SignUp)
 | 
							r.Get("/sign_up", user.SignUp)
 | 
				
			||||||
		r.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
 | 
							r.Post("/sign_up", bindIgnErr(auth.RegisterForm{}), user.SignUpPost)
 | 
				
			||||||
		r.Get("/reset_password", user.ResetPasswd)
 | 
							r.Get("/reset_password", user.ResetPasswd)
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user