Browse Source

add cloudbrain login

master
yuyuanshifu 4 years ago
parent
commit
c1a7a1cda9
8 changed files with 109 additions and 8 deletions
  1. +11
    -5
      models/login_source.go
  2. +6
    -2
      modules/auth/cloudbrain/cloudbrain.go
  3. +2
    -0
      options/locale/locale_zh-CN.ini
  4. +1
    -0
      routers/routes/routes.go
  5. +20
    -0
      routers/user/auth.go
  6. +10
    -0
      templates/user/auth/signin_cloud_brain.tmpl
  7. +55
    -0
      templates/user/auth/signin_cloudbrain.tmpl
  8. +4
    -1
      templates/user/auth/signin_navbar.tmpl

+ 11
- 5
models/login_source.go View File

@@ -40,7 +40,7 @@ const (
LoginDLDAP // 5 LoginDLDAP // 5
LoginOAuth2 // 6 LoginOAuth2 // 6
LoginSSPI // 7 LoginSSPI // 7
LoginCloubBrain // 8
LoginCloudBrain // 8
) )


// LoginNames contains the name of LoginType values. // LoginNames contains the name of LoginType values.
@@ -51,7 +51,7 @@ var LoginNames = map[LoginType]string{
LoginPAM: "PAM", LoginPAM: "PAM",
LoginOAuth2: "OAuth2", LoginOAuth2: "OAuth2",
LoginSSPI: "SPNEGO with SSPI", LoginSSPI: "SPNEGO with SSPI",
LoginCloubBrain: "Cloud Brain",
LoginCloudBrain: "Cloud Brain",
} }


// SecurityProtocolNames contains the name of SecurityProtocol values. // SecurityProtocolNames contains the name of SecurityProtocol values.
@@ -202,6 +202,8 @@ func (source *LoginSource) BeforeSet(colName string, val xorm.Cell) {
source.Cfg = new(OAuth2Config) source.Cfg = new(OAuth2Config)
case LoginSSPI: case LoginSSPI:
source.Cfg = new(SSPIConfig) source.Cfg = new(SSPIConfig)
case LoginCloudBrain:
source.Cfg = new(CloudBrainConfig)
default: default:
panic("unrecognized login source type: " + com.ToStr(*val)) panic("unrecognized login source type: " + com.ToStr(*val))
} }
@@ -717,7 +719,7 @@ func ExternalUserLogin(user *User, login, password string, source *LoginSource)
user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig)) user, err = LoginViaSMTP(user, login, password, source.ID, source.Cfg.(*SMTPConfig))
case LoginPAM: case LoginPAM:
user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig)) user, err = LoginViaPAM(user, login, password, source.ID, source.Cfg.(*PAMConfig))
case LoginCloubBrain:
case LoginCloudBrain:
user, err = LoginViaCloudBrain(user, login, password, source) user, err = LoginViaCloudBrain(user, login, password, source)
default: default:
return nil, ErrUnsupportedLoginType return nil, ErrUnsupportedLoginType
@@ -831,12 +833,16 @@ func LoginViaCloudBrain(user *User, login, password string, source *LoginSource)
} }


if user != nil { if user != nil {
//todo: update token
user.Token = token user.Token = token
return user, UpdateUserCols(user, "token") return user, UpdateUserCols(user, "token")
} }


cloudBrainUser, err := cloudbrain.GetUserInfo(token, login)
cloudBrainUser, err := cloudbrain.GetUserInfo(login, token)

if err != nil {
log.Error("GetUserInfo(%s) failed: %v", login, err)
return nil, err
}


if len(cloudBrainUser.Email) == 0 { if len(cloudBrainUser.Email) == 0 {
cloudBrainUser.Email = fmt.Sprintf("%s@cloudbrain", login) cloudBrainUser.Email = fmt.Sprintf("%s@cloudbrain", login)


+ 6
- 2
modules/auth/cloudbrain/cloudbrain.go View File

@@ -31,7 +31,7 @@ type RespAuth struct {


type RespToken struct { type RespToken struct {
Code string `json:"code"` Code string `json:"code"`
Message string `json:"message"`
Message string `json:"msg"`
Payload PayloadToken `json:"payload"` Payload PayloadToken `json:"payload"`
} }


@@ -43,7 +43,7 @@ type PayloadToken struct {


type RespUserInfo struct { type RespUserInfo struct {
Code string `json:"code"` Code string `json:"code"`
Message string `json:"message"`
Message string `json:"msg"`
Payload PayloadUserInfo `json:"payload"` Payload PayloadUserInfo `json:"payload"`
} }


@@ -71,6 +71,8 @@ func UserValidate(username string, password string) (string, error) {
return "", err return "", err
} }


defer resp.Body.Close()

body,err := ioutil.ReadAll(resp.Body) body,err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
log.Error("read resp body failed:" + err.Error()) log.Error("read resp body failed:" + err.Error())
@@ -109,6 +111,8 @@ func GetUserInfo(username string, token string) (*CloudBrainUser, error) {
return nil, err return nil, err
} }


defer resp.Body.Close()

body,err := ioutil.ReadAll(resp.Body) body,err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
log.Error("read resp body failed:", err.Error()) log.Error("read resp body failed:", err.Error())


+ 2
- 0
options/locale/locale_zh-CN.ini View File

@@ -192,6 +192,7 @@ no_reply_address_helper=具有隐藏电子邮件地址的用户的域名。例


[home] [home]
uname_holder=登录名或电子邮箱地址 uname_holder=登录名或电子邮箱地址
uname_holder_cloud_brain=云脑登录名
password_holder=密码 password_holder=密码
switch_dashboard_context=切换控制面板用户 switch_dashboard_context=切换控制面板用户
my_repos=项目列表 my_repos=项目列表
@@ -267,6 +268,7 @@ twofa_passcode_incorrect=你的验证码不正确。如果你丢失了你的设
twofa_scratch_token_incorrect=你的验证口令不正确。 twofa_scratch_token_incorrect=你的验证口令不正确。
login_userpass=登录 login_userpass=登录
login_openid=OpenID login_openid=OpenID
login_cloudbrain=云脑用户登录
oauth_signup_tab=注册帐号 oauth_signup_tab=注册帐号
oauth_signup_title=添加电子邮件和密码 (用于帐号恢复) oauth_signup_title=添加电子邮件和密码 (用于帐号恢复)
oauth_signup_submit=完成账号 oauth_signup_submit=完成账号


+ 1
- 0
routers/routes/routes.go View File

@@ -305,6 +305,7 @@ func RegisterRoutes(m *macaron.Macaron) {
// ***** START: User ***** // ***** START: User *****
m.Group("/user", func() { m.Group("/user", func() {
m.Get("/login", user.SignIn) m.Get("/login", user.SignIn)
m.Get("/login/cloud_brain", user.SignInCloudBrain)
m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost) m.Post("/login", bindIgnErr(auth.SignInForm{}), user.SignInPost)
m.Group("", func() { m.Group("", func() {
m.Combo("/login/openid"). m.Combo("/login/openid").


+ 20
- 0
routers/user/auth.go View File

@@ -36,6 +36,8 @@ const (
tplMustChangePassword = "user/auth/change_passwd" tplMustChangePassword = "user/auth/change_passwd"
// tplSignIn template for sign in page // tplSignIn template for sign in page
tplSignIn base.TplName = "user/auth/signin" tplSignIn base.TplName = "user/auth/signin"
// tplSignIn template for sign in page
tplSignInCloudBrain base.TplName = "user/auth/signin_cloud_brain"
// tplSignUp template path for sign up page // tplSignUp template path for sign up page
tplSignUp base.TplName = "user/auth/signup" tplSignUp base.TplName = "user/auth/signup"
// TplActivate template path for activate user // TplActivate template path for activate user
@@ -143,10 +145,28 @@ func SignIn(ctx *context.Context) {
ctx.Data["PageIsSignIn"] = true ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled() ctx.Data["EnableSSPI"] = models.IsSSPIEnabled()
ctx.Data["EnableCloudBrain"] = true


ctx.HTML(200, tplSignIn) ctx.HTML(200, tplSignIn)
} }


// SignInCloudBrain render sign in page
func SignInCloudBrain(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")

// Check auto-login.
if checkAutoLogin(ctx) {
return
}

ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsCloudBrainLogin"] = true
ctx.Data["EnableCloudBrain"] = true

ctx.HTML(200, tplSignInCloudBrain)
}

// SignInPost response for sign in request // SignInPost response for sign in request
func SignInPost(ctx *context.Context, form auth.SignInForm) { func SignInPost(ctx *context.Context, form auth.SignInForm) {
ctx.Data["Title"] = ctx.Tr("sign_in") ctx.Data["Title"] = ctx.Tr("sign_in")


+ 10
- 0
templates/user/auth/signin_cloud_brain.tmpl View File

@@ -0,0 +1,10 @@
{{template "base/head" .}}
<div class="user signin">
{{template "user/auth/signin_navbar" .}}
<div class="ui container">
<div class="ui raised very padded text container segment">
{{template "user/auth/signin_cloudbrain" .}}
</div>
</div>
</div>
{{template "base/footer" .}}

+ 55
- 0
templates/user/auth/signin_cloudbrain.tmpl View File

@@ -0,0 +1,55 @@
<style>
.full.height{background-color: #F9F9F9;}
.ui.left:not(.action){ float:none;}
.ui.left{ float:none;}
.ui.secondary.pointing.menu{ border-bottom:none;}
</style>
{{template "base/alert" .}}

<div class="ui centered grid">
<div class="sixteen wide mobile ten wide tablet ten wide computer column">
<div class="ui bottom aligned two column grid">
<div class="column">
<h2 class="ui header">
{{.i18n.Tr "auth.login_userpass"}}
</h2>
</div>
</div>

<div class="ui grid">
<div class="column">
<form class="ui form" action="{{.SignInLink}}" method="post">
{{.CsrfTokenHtml}}
<div class="field">
<div class="ui left icon input {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
<i class="user icon"></i>
<input id="user_name" name="user_name" value="{{.user_name}}" placeholder="{{.i18n.Tr "home.uname_holder_cloud_brain"}}" autofocus required>
</div>
</div>
<div class="field">
<div class="ui left icon input {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
<i class="lock icon"></i>
<input id="password" name="password" type="password" value="{{.password}}" placeholder="{{.i18n.Tr "password"}}" autocomplete="off" required>
</div>
</div>
<div class="two fields inline">
<div class="field">
<div class="ui checkbox">
<label>{{.i18n.Tr "auth.remember_me"}}</label>
<input name="remember" type="checkbox">
</div>
</div>
</div>

<div class="ui hidden divider"></div>

<div class="center aligned field">
<button class="fluid large ui blue button">
{{.i18n.Tr "sign_in"}}
</button>
</div>
</form>
</div>
</div>
</div>
</div>

+ 4
- 1
templates/user/auth/signin_navbar.tmpl View File

@@ -1,8 +1,11 @@
{{if or .EnableOpenIDSignIn .EnableSSPI}}
{{if or .EnableOpenIDSignIn .EnableSSPI .EnableCloudBrain}}
<div class="ui secondary pointing tabular top attached borderless menu new-menu navbar"> <div class="ui secondary pointing tabular top attached borderless menu new-menu navbar">
<a class="{{if .PageIsLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login"> <a class="{{if .PageIsLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login">
{{.i18n.Tr "auth.login_userpass"}} {{.i18n.Tr "auth.login_userpass"}}
</a> </a>
<a class="{{if .PageIsCloudBrainLogin}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/cloud_brain">
{{.i18n.Tr "auth.login_cloudbrain"}}
</a>
{{if .EnableOpenIDSignIn}} {{if .EnableOpenIDSignIn}}
<a class="{{if .PageIsLoginOpenID}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/openid"> <a class="{{if .PageIsLoginOpenID}}active{{end}} item" rel="nofollow" href="{{AppSubUrl}}/user/login/openid">
<i class="fa fa-openid"></i> <i class="fa fa-openid"></i>


Loading…
Cancel
Save