2014-04-02 06:39:04 +04:00
// 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.
2014-04-07 20:56:40 +04:00
2014-04-02 06:39:04 +04:00
package user
import (
"encoding/json"
2014-04-14 02:12:07 +04:00
"errors"
2014-04-12 19:19:17 +04:00
"fmt"
2014-11-29 05:20:13 +03:00
// "strings"
2014-11-29 05:38:35 +03:00
"time"
2014-04-02 06:39:04 +04:00
2014-11-29 05:20:13 +03:00
"github.com/macaron-contrib/oauth2"
2014-11-29 05:38:35 +03:00
"github.com/gogits/gogs/models"
2014-04-02 06:39:04 +04:00
"github.com/gogits/gogs/modules/log"
2014-04-07 14:01:25 +04:00
"github.com/gogits/gogs/modules/middleware"
2014-05-26 04:11:25 +04:00
"github.com/gogits/gogs/modules/setting"
2014-04-14 02:12:07 +04:00
"github.com/gogits/gogs/modules/social"
2014-04-02 06:39:04 +04:00
)
2014-07-26 08:24:27 +04:00
func SocialSignIn ( ctx * middleware . Context ) {
2014-05-26 04:11:25 +04:00
if setting . OauthService == nil {
2014-11-29 05:20:13 +03:00
ctx . Handle ( 404 , "OAuth2 service not enabled" , nil )
2014-04-09 20:07:57 +04:00
return
}
2014-04-14 02:12:07 +04:00
2014-11-29 05:38:35 +03:00
next := setting . AppSubUrl + "/user/login"
2014-11-29 05:20:13 +03:00
info := ctx . Session . Get ( oauth2 . KEY_TOKEN )
if info == nil {
2014-11-29 05:38:35 +03:00
ctx . Redirect ( next )
2014-04-12 19:19:17 +04:00
return
2014-04-09 20:07:57 +04:00
}
2014-04-14 02:12:07 +04:00
2014-11-29 05:20:13 +03:00
name := ctx . Params ( ":name" )
connect , ok := social . SocialMap [ name ]
if ! ok {
ctx . Handle ( 404 , "social login not enabled" , errors . New ( name ) )
2014-04-07 20:56:40 +04:00
return
}
2014-04-09 20:07:57 +04:00
2014-11-29 05:20:13 +03:00
tk := new ( oauth2 . Token )
if err := json . Unmarshal ( info . ( [ ] byte ) , tk ) ; err != nil {
ctx . Handle ( 500 , "Unmarshal token" , err )
2014-04-12 19:19:17 +04:00
return
2014-04-09 20:07:57 +04:00
}
2014-04-12 21:15:19 +04:00
ui , err := connect . UserInfo ( tk , ctx . Req . URL )
2014-04-12 19:19:17 +04:00
if err != nil {
2014-11-29 05:20:13 +03:00
ctx . Handle ( 500 , fmt . Sprintf ( "UserInfo(%s)" , name ) , err )
2014-04-07 14:01:25 +04:00
return
}
2014-11-29 05:54:49 +03:00
if len ( ui . Identity ) == 0 {
ctx . Handle ( 404 , "no identity is presented" , errors . New ( name ) )
return
}
2014-04-14 02:12:07 +04:00
log . Info ( "social.SocialSignIn(social login): %s" , ui )
2014-11-29 05:38:35 +03:00
oa , err := models . GetOauth2 ( ui . Identity )
switch err {
case nil :
ctx . Session . Set ( "uid" , oa . User . Id )
ctx . Session . Set ( "uname" , oa . User . Name )
case models . ErrOauth2RecordNotExist :
raw , _ := json . Marshal ( tk )
oa = & models . Oauth2 {
Uid : - 1 ,
Type : connect . Type ( ) ,
Identity : ui . Identity ,
Token : string ( raw ) ,
}
log . Trace ( "social.SocialSignIn(oa): %v" , oa )
if err = models . AddOauth2 ( oa ) ; err != nil {
log . Error ( 4 , "social.SocialSignIn(add oauth2): %v" , err ) // 501
return
}
case models . ErrOauth2NotAssociated :
next = setting . AppSubUrl + "/user/sign_up"
default :
ctx . Handle ( 500 , "social.SocialSignIn(GetOauth2)" , err )
return
}
2014-04-14 02:12:07 +04:00
2014-11-29 05:38:35 +03:00
oa . Updated = time . Now ( )
if err = models . UpdateOauth2 ( oa ) ; err != nil {
log . Error ( 4 , "UpdateOauth2: %v" , err )
}
2014-08-10 04:25:02 +04:00
2014-11-29 05:38:35 +03:00
ctx . Session . Set ( "socialId" , oa . Id )
ctx . Session . Set ( "socialName" , ui . Name )
ctx . Session . Set ( "socialEmail" , ui . Email )
log . Trace ( "social.SocialSignIn(social ID): %v" , oa . Id )
ctx . Redirect ( next )
2014-04-02 06:39:04 +04:00
}