]> source.dussan.org Git - gitea.git/commitdiff
add oauth2 qq support
authorskyblue <ssx205@gmail.com>
Sat, 12 Apr 2014 17:15:19 +0000 (01:15 +0800)
committerskyblue <ssx205@gmail.com>
Sat, 12 Apr 2014 17:15:19 +0000 (01:15 +0800)
models/oauth2.go
routers/user/social.go
routers/user/social_github.go
routers/user/social_google.go
routers/user/social_qq.go [new file with mode: 0644]

index e28b00870f8edfde0bec03dfd7333bcc9e62df31..f8780fe68209f2fe70a945a5219b4ab97000a0d6 100644 (file)
@@ -13,6 +13,7 @@ const (
        OT_GITHUB = iota + 1
        OT_GOOGLE
        OT_TWITTER
+       OT_QQ
 )
 
 var (
index cd5958aa08cd78ae20e7cabd76e7155b73ba9e72..ea47d71b14124d0dbce696a506b44a34cf630019 100644 (file)
@@ -28,7 +28,7 @@ type BasicUserInfo struct {
 type SocialConnector interface {
        Type() int
        SetRedirectUrl(string)
-       UserInfo(*oauth.Token) (*BasicUserInfo, error)
+       UserInfo(*oauth.Token, *url.URL) (*BasicUserInfo, error)
 
        AuthCodeURL(string) string
        Exchange(string) (*oauth.Token, error)
@@ -63,13 +63,13 @@ func SocialSignIn(params martini.Params, ctx *middleware.Context) {
        code := ctx.Query("code")
        if code == "" {
                // redirect to social login page
-               connect.SetRedirectUrl(strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.RequestURI())
+               connect.SetRedirectUrl(strings.TrimSuffix(base.AppUrl, "/") + ctx.Req.URL.Host + ctx.Req.URL.Path)
                ctx.Redirect(connect.AuthCodeURL(next))
                return
        }
 
        // handle call back
-       tk, err := connect.Exchange(code) // transport.Exchange(code)
+       tk, err := connect.Exchange(code) // exchange for token
        if err != nil {
                log.Error("oauth2 handle callback error: %v", err)
                ctx.Handle(500, "exchange code error", nil)
@@ -78,7 +78,7 @@ func SocialSignIn(params martini.Params, ctx *middleware.Context) {
        next = extractPath(ctx.Query("state"))
        log.Trace("success get token")
 
-       ui, err := connect.UserInfo(tk)
+       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)
index 316dc37ad411d228cfea9551c0442928c847d47d..e532efd0a31634780c181e1633901da8cc1bbb9e 100644 (file)
@@ -1,8 +1,13 @@
+// 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"
 
@@ -42,7 +47,7 @@ func (s *SocialGithub) SetRedirectUrl(url string) {
        s.Transport.Config.RedirectURL = url
 }
 
-func (s *SocialGithub) UserInfo(token *oauth.Token) (*BasicUserInfo, error) {
+func (s *SocialGithub) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
        transport := &oauth.Transport{
                Token: token,
        }
index ecd090cd1ef65168f191ebde95cdca5ba1287496..b585386f21b092d58c85a780cdfbba2e2f6eb1ae 100644 (file)
@@ -1,8 +1,13 @@
+// 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"
@@ -40,7 +45,7 @@ func (s *SocialGoogle) SetRedirectUrl(url string) {
        s.Transport.Config.RedirectURL = url
 }
 
-func (s *SocialGoogle) UserInfo(token *oauth.Token) (*BasicUserInfo, error) {
+func (s *SocialGoogle) UserInfo(token *oauth.Token, _ *url.URL) (*BasicUserInfo, error) {
        transport := &oauth.Transport{Token: token}
        var data struct {
                Id    string `json:"id"`
diff --git a/routers/user/social_qq.go b/routers/user/social_qq.go
new file mode 100644 (file)
index 0000000..d08892e
--- /dev/null
@@ -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
+}