@@ -6,65 +6,32 @@ package user
66
77import (
88 "encoding/json"
9- "net/http "
9+ "fmt "
1010 "net/url"
11- "strconv"
1211 "strings"
1312
1413 "code.google.com/p/goauth2/oauth"
1514
15+ "github.com/go-martini/martini"
1616 "github.com/gogits/gogs/models"
1717 "github.com/gogits/gogs/modules/base"
1818 "github.com/gogits/gogs/modules/log"
1919 "github.com/gogits/gogs/modules/middleware"
2020)
2121
22- type SocialConnector interface {
23- Identity () string
24- Name () string
25- Email () string
26- TokenString () string
27- }
28-
29- type SocialGithub struct {
30- data struct {
31- Id int `json:"id"`
32- Name string `json:"login"`
33- Email string `json:"email"`
34- }
35- Token * oauth.Token
22+ type BasicUserInfo struct {
23+ Identity string
24+ Name string
25+ Email string
3626}
3727
38- func (s * SocialGithub ) Identity () string {
39- return strconv .Itoa (s .data .Id )
40- }
41-
42- func (s * SocialGithub ) Name () string {
43- return s .data .Name
44- }
45-
46- func (s * SocialGithub ) Email () string {
47- return s .data .Email
48- }
49-
50- func (s * SocialGithub ) TokenString () string {
51- data , _ := json .Marshal (s .Token )
52- return string (data )
53- }
28+ type SocialConnector interface {
29+ Type () int
30+ SetRedirectUrl (string )
31+ UserInfo (* oauth.Token , * url.URL ) (* BasicUserInfo , error )
5432
55- // Github API refer: https://developer.github.com/v3/users/
56- func (s * SocialGithub ) Update () error {
57- scope := "https://api.github.com/user"
58- transport := & oauth.Transport {
59- Token : s .Token ,
60- }
61- log .Debug ("update github info" )
62- r , err := transport .Client ().Get (scope )
63- if err != nil {
64- return err
65- }
66- defer r .Body .Close ()
67- return json .NewDecoder (r .Body ).Decode (& s .data )
33+ AuthCodeURL (string ) string
34+ Exchange (string ) (* oauth.Token , error )
6835}
6936
7037func extractPath (next string ) string {
@@ -75,85 +42,76 @@ func extractPath(next string) string {
7542 return n .Path
7643}
7744
78- // github && google && ...
79- func SocialSignIn ( ctx * middleware. Context ) {
80- //if base.OauthService != nil && base.OauthService.GitHub.Enabled {
81- //}
45+ var (
46+ SocialBaseUrl = "/user/login"
47+ SocialMap = make ( map [ string ] SocialConnector )
48+ )
8249
83- var socid int64
84- var ok bool
85- next := extractPath (ctx .Query ("next" ))
86- log .Debug ("social signed check %s" , next )
87- if socid , ok = ctx .Session .Get ("socialId" ).(int64 ); ok && socid != 0 {
88- // already login
89- ctx .Redirect (next )
90- log .Info ("login soc id: %v" , socid )
50+ // github && google && ...
51+ func SocialSignIn (params martini.Params , ctx * middleware.Context ) {
52+ if base .OauthService == nil || ! base .OauthService .GitHub .Enabled {
53+ ctx .Handle (404 , "social login not enabled" , nil )
9154 return
9255 }
93-
94- config := & oauth.Config {
95- ClientId : base .OauthService .GitHub .ClientId ,
96- ClientSecret : base .OauthService .GitHub .ClientSecret ,
97- RedirectURL : strings .TrimSuffix (base .AppUrl , "/" ) + ctx .Req .URL .RequestURI (),
98- Scope : base .OauthService .GitHub .Scopes ,
99- AuthURL : "https://github.com/login/oauth/authorize" ,
100- TokenURL : "https://github.com/login/oauth/access_token" ,
101- }
102- transport := & oauth.Transport {
103- Config : config ,
104- Transport : http .DefaultTransport ,
56+ next := extractPath (ctx .Query ("next" ))
57+ name := params ["name" ]
58+ connect , ok := SocialMap [name ]
59+ if ! ok {
60+ ctx .Handle (404 , "social login" , nil )
61+ return
10562 }
10663 code := ctx .Query ("code" )
10764 if code == "" {
10865 // redirect to social login page
109- ctx .Redirect (config .AuthCodeURL (next ))
66+ connect .SetRedirectUrl (strings .TrimSuffix (base .AppUrl , "/" ) + ctx .Req .URL .Host + ctx .Req .URL .Path )
67+ ctx .Redirect (connect .AuthCodeURL (next ))
11068 return
11169 }
11270
11371 // handle call back
114- tk , err := transport .Exchange (code )
72+ tk , err := connect .Exchange (code ) // exchange for token
11573 if err != nil {
11674 log .Error ("oauth2 handle callback error: %v" , err )
117- return // FIXME, need error page 501
75+ ctx .Handle (500 , "exchange code error" , nil )
76+ return
11877 }
11978 next = extractPath (ctx .Query ("state" ))
120- log .Debug ("success token: %v" , tk )
79+ log .Trace ("success get token" )
12180
122- gh := & SocialGithub { Token : tk }
123- if err = gh . Update (); err != nil {
124- // FIXME: handle error page 501
125- log .Error ("connect with github error: %s" , err )
81+ ui , err := connect . UserInfo ( tk , ctx . Req . URL )
82+ if err != nil {
83+ ctx . Handle ( 500 , fmt . Sprintf ( "get infomation from %s error: %v" , name , err ), nil )
84+ log .Error ("social connect error: %s" , err )
12685 return
12786 }
128- var soc SocialConnector = gh
129- log .Info ("login: %s" , soc .Name ())
130- oa , err := models .GetOauth2 (soc .Identity ())
87+ log .Info ("social login: %s" , ui )
88+ oa , err := models .GetOauth2 (ui .Identity )
13189 switch err {
13290 case nil :
13391 ctx .Session .Set ("userId" , oa .User .Id )
13492 ctx .Session .Set ("userName" , oa .User .Name )
13593 case models .ErrOauth2RecordNotExists :
13694 oa = & models.Oauth2 {}
95+ raw , _ := json .Marshal (tk ) // json encode
96+ oa .Token = string (raw )
13797 oa .Uid = - 1
138- oa .Type = models .OT_GITHUB
139- oa .Token = soc .TokenString ()
140- oa .Identity = soc .Identity ()
141- log .Debug ("oa: %v" , oa )
98+ oa .Type = connect .Type ()
99+ oa .Identity = ui .Identity
100+ log .Trace ("oa: %v" , oa )
142101 if err = models .AddOauth2 (oa ); err != nil {
143102 log .Error ("add oauth2 %v" , err ) // 501
144103 return
145104 }
146105 case models .ErrOauth2NotAssociatedWithUser :
147- ctx .Session .Set ("socialId" , oa .Id )
148- ctx .Session .Set ("socialName" , soc .Name ())
149- ctx .Session .Set ("socialEmail" , soc .Email ())
150- ctx .Redirect ("/user/sign_up" )
151- return
106+ next = "/user/sign_up"
152107 default :
153- log .Error (err .Error ()) // FIXME: handle error page
108+ log .Error ("other error: %v" , err )
109+ ctx .Handle (500 , err .Error (), nil )
154110 return
155111 }
156112 ctx .Session .Set ("socialId" , oa .Id )
157- log .Debug ("socialId: %v" , oa .Id )
113+ ctx .Session .Set ("socialName" , ui .Name )
114+ ctx .Session .Set ("socialEmail" , ui .Email )
115+ log .Trace ("socialId: %v" , oa .Id )
158116 ctx .Redirect (next )
159117}
0 commit comments