Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Tan Jiang 2016-04-05 20:46:46 +08:00
commit 88303cf2a2
12 changed files with 142 additions and 36 deletions

View File

@ -30,4 +30,6 @@ ldap_basedn = uid=%s,ou=people,dc=mydomain,dc=com
#The password for the root user of mysql db, change this before any production use.
db_password = root123
#Switch for self-registration feature
self_registration = on
#####

View File

@ -25,6 +25,7 @@ auth_mode = cp.get("configuration", "auth_mode")
ldap_url = cp.get("configuration", "ldap_url")
ldap_basedn = cp.get("configuration", "ldap_basedn")
db_password = cp.get("configuration", "db_password")
self_registration = cp.get("configuration", "self_registration")
########
base_dir = os.path.dirname(__file__)
@ -65,7 +66,8 @@ render(os.path.join(templates_dir, "ui", "env"),
auth_mode=auth_mode,
admin_pwd=harbor_admin_password,
ldap_url=ldap_url,
ldap_basedn=ldap_basedn)
ldap_basedn=ldap_basedn,
self_registration=self_registration)
render(os.path.join(templates_dir, "ui", "app.conf"),
ui_conf,

View File

@ -10,4 +10,5 @@ HARBOR_URL=$ui_url
AUTH_MODE=$auth_mode
LDAP_URL=$ldap_url
LDAP_BASE_DN=$ldap_basedn
SELF_REGISTRATION=$self_registration
LOG_LEVEL=debug

View File

@ -16,12 +16,14 @@
package controllers
import (
"net/http"
"os"
"strings"
"github.com/vmware/harbor/utils/log"
"github.com/astaxie/beego"
"github.com/beego/i18n"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/utils/log"
)
// CommonController handles request from UI that doesn't expect a page, such as /login /logout ...
@ -38,6 +40,9 @@ func (c *CommonController) Render() error {
type BaseController struct {
beego.Controller
i18n.Locale
SelfRegistration bool
IsAdmin bool
AuthMode string
}
type langType struct {
@ -93,15 +98,35 @@ func (b *BaseController) Prepare() {
b.Data["CurLang"] = curLang.Name
b.Data["RestLangs"] = restLangs
sessionUserID := b.GetSession("userId")
if sessionUserID != nil {
b.Data["Username"] = b.GetSession("username")
}
authMode := os.Getenv("AUTH_MODE")
authMode := strings.ToLower(os.Getenv("AUTH_MODE"))
if authMode == "" {
authMode = "db_auth"
}
b.Data["AuthMode"] = authMode
b.AuthMode = authMode
b.Data["AuthMode"] = b.AuthMode
selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION"))
if selfRegistration == "on" {
b.SelfRegistration = true
}
sessionUserID := b.GetSession("userId")
if sessionUserID != nil {
b.Data["Username"] = b.GetSession("username")
b.Data["UserId"] = sessionUserID.(int)
var err error
b.IsAdmin, err = dao.IsAdminRole(sessionUserID.(int))
if err != nil {
log.Errorf("Error occurred in IsAdminRole:%v", err)
b.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
}
b.Data["IsAdmin"] = b.IsAdmin
b.Data["SelfRegistration"] = b.SelfRegistration
}
// ForwardTo setup layout and template for content for a page.

View File

@ -17,11 +17,11 @@ package controllers
import (
"net/http"
"os"
"strings"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils/log"
)
@ -32,35 +32,70 @@ type RegisterController struct {
// Get renders the Sign In page, it only works if the auth mode is set to db_auth
func (rc *RegisterController) Get() {
authMode := os.Getenv("AUTH_MODE")
if authMode == "" || authMode == "db_auth" {
if !rc.SelfRegistration {
log.Warning("Registration is disabled when self-registration is off.")
rc.Redirect("/signIn", http.StatusFound)
}
if rc.AuthMode == "db_auth" {
rc.ForwardTo("page_title_registration", "register")
} else {
rc.Redirect("/signIn", http.StatusNotFound)
rc.Redirect("/signIn", http.StatusFound)
}
}
// AddUserController handles request for adding user with an admin role user
type AddUserController struct {
BaseController
}
// Get renders the Sign In page, it only works if the auth mode is set to db_auth
func (ac *AddUserController) Get() {
if !ac.IsAdmin {
log.Warning("Add user can only be used by admin role user.")
ac.Redirect("/signIn", http.StatusFound)
}
if ac.AuthMode == "db_auth" {
ac.ForwardTo("page_title_add_user", "register")
} else {
ac.Redirect("/signIn", http.StatusFound)
}
}
// SignUp insert data into DB based on data in form.
func (rc *CommonController) SignUp() {
username := strings.TrimSpace(rc.GetString("username"))
email := strings.TrimSpace(rc.GetString("email"))
realname := strings.TrimSpace(rc.GetString("realname"))
password := strings.TrimSpace(rc.GetString("password"))
comment := strings.TrimSpace(rc.GetString("comment"))
func (cc *CommonController) SignUp() {
if !(cc.AuthMode == "db_auth") {
cc.CustomAbort(http.StatusForbidden, "")
}
if !(cc.SelfRegistration || cc.IsAdmin) {
log.Warning("Registration can only be used by admin role user when self-registration is off.")
cc.CustomAbort(http.StatusForbidden, "")
}
username := strings.TrimSpace(cc.GetString("username"))
email := strings.TrimSpace(cc.GetString("email"))
realname := strings.TrimSpace(cc.GetString("realname"))
password := strings.TrimSpace(cc.GetString("password"))
comment := strings.TrimSpace(cc.GetString("comment"))
user := models.User{Username: username, Email: email, Realname: realname, Password: password, Comment: comment}
_, err := dao.Register(user)
if err != nil {
log.Errorf("Error occurred in Register: %v", err)
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
}
// UserExists checks if user exists when user input value in sign in form.
func (rc *CommonController) UserExists() {
target := rc.GetString("target")
value := rc.GetString("value")
func (cc *CommonController) UserExists() {
target := cc.GetString("target")
value := cc.GetString("value")
user := models.User{}
switch target {
@ -73,8 +108,8 @@ func (rc *CommonController) UserExists() {
exist, err := dao.UserExists(user, target)
if err != nil {
log.Errorf("Error occurred in UserExists: %v", err)
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
rc.Data["json"] = exist
rc.ServeJSON()
cc.Data["json"] = exist
cc.ServeJSON()
}

View File

@ -41,6 +41,7 @@ func init() {
beego.Router("/", &controllers.IndexController{})
beego.Router("/signIn", &controllers.SignInController{})
beego.Router("/register", &controllers.RegisterController{})
beego.Router("/addUser", &controllers.AddUserController{})
beego.Router("/forgotPassword", &controllers.ForgotPasswordController{})
beego.Router("/resetPassword", &controllers.ResetPasswordController{})
beego.Router("/changePassword", &controllers.ChangePasswordController{})

View File

@ -3,6 +3,7 @@ page_title_sign_in = Sign In - Harbor
page_title_project = Project - Harbor
page_title_item_details = Details - Harbor
page_title_registration = Sign Up - Harbor
page_title_add_user = Add User - Harbor
page_title_forgot_password = Forgot Password - Harbor
title_forgot_password = Forgot Password
page_title_reset_password = Reset Password - Harbor
@ -12,6 +13,7 @@ title_change_password = Change Password
page_title_search = Search - Harbor
sign_in = Sign In
sign_up = Sign Up
add_user = Add User
log_out = Log Out
search_placeholder = projects or repositories
change_password = Change Password

View File

@ -177,6 +177,10 @@ var global_messages = {
"en-US": "Sign Up",
"zh-CN": "注册"
},
"title_add_user": {
"en-US": "Add User",
"zh-CN": "新增用户"
},
"registered_successfully": {
"en-US": "Signed up successfully.",
"zh-CN": "注册成功。"
@ -185,6 +189,14 @@ var global_messages = {
"en-US": "Failed to sign up.",
"zh-CN": "注册失败。"
},
"added_user_successfully": {
"en-US": "Added user successfully.",
"zh-CN": "新增用户成功。"
},
"added_user_failed": {
"en-US": "Added user failed.",
"zh-CN": "新增用户失败。"
},
"projects" : {
"en-US": "Projects",
"zh-CN": "项目"

View File

@ -3,6 +3,7 @@ page_title_sign_in = 登录 - Harbor
page_title_project = 项目 - Harbor
page_title_item_details = 详细信息 - Harbor
page_title_registration = 注册 - Harbor
page_title_add_user = 新增用户 - Harbor
page_title_forgot_password = 忘记密码 - Harbor
title_forgot_password = 忘记密码
page_title_reset_password = 重置密码 - Harbor
@ -12,6 +13,7 @@ title_change_password = 修改密码
page_title_search = 搜索 - Harbor
sign_in = 登录
sign_up = 注册
add_user = 新增用户
log_out = 注销
search_placeholder = 项目或镜像名称
change_password = 修改密码

View File

@ -30,12 +30,14 @@ jQuery(function(){
$("#btnPageSignUp").on("click", function(){
validateOptions.Validate(function() {
var username = $.trim($("#Username").val());
var email = $.trim($("#Email").val());
var password = $.trim($("#Password").val());
var confirmedPassword = $.trim($("#ConfirmedPassword").val());
var realname = $.trim($("#Realname").val());
var comment = $.trim($("#Comment").val());
var username = $.trim($("#Username").val());
var email = $.trim($("#Email").val());
var password = $.trim($("#Password").val());
var confirmedPassword = $.trim($("#ConfirmedPassword").val());
var realname = $.trim($("#Realname").val());
var comment = $.trim($("#Comment").val());
var isAdmin = $("#isAdmin").val();
$.ajax({
url : '/signUp',
data:{username: username, password: password, realname: realname, comment: comment, email: email},
@ -47,10 +49,14 @@ jQuery(function(){
if(xhr && xhr.status == 200){
$("#dlgModal")
.dialogModal({
"title": i18n.getMessage("title_sign_up"),
"content": i18n.getMessage("registered_successfully"),
"callback": function(){
document.location = "/signIn";
"title": isAdmin == "true" ? i18n.getMessage("title_add_user") : i18n.getMessage("title_sign_up"),
"content": isAdmin == "true" ? i18n.getMessage("added_user_successfully") : i18n.getMessage("registered_successfully"),
"callback": function(){
if(isAdmin == "true") {
document.location = "/registry/project";
}else{
document.location = "/signIn";
}
}
});
}

View File

@ -16,7 +16,11 @@
<div class="col-sm-4"></div>
<div class="col-sm-4">
<div class="page-header">
{{ if eq .IsAdmin true }}
<h1>{{i18n .Lang "add_user" }}</h1>
{{ else }}
<h1>{{i18n .Lang "registration"}}</h1>
{{ end }}
</div>
<form class="form">
<div class="alert alert-danger" role="alert" id="divErrMsg"></div>
@ -62,7 +66,13 @@
</div>
<div class="form-group has-feedback">
<div class="text-center">
<button type="button" class="btn btn-default" id="btnPageSignUp">{{i18n .Lang "sign_up"}}</button>
<button type="button" class="btn btn-default" id="btnPageSignUp">
{{ if eq .IsAdmin true }}
{{i18n .Lang "add_user" }}
{{ else }}
{{i18n .Lang "sign_up"}}
{{ end }}
</button>
</div>
</div>
</form>

View File

@ -13,6 +13,7 @@
limitations under the License.
-->
<input type="hidden" id="currentLanguage" value="{{.Lang}}">
<input type="hidden" id="isAdmin" value="{{.IsAdmin}}">
<nav class="navbar navbar-default" role="navigation" style="margin-bottom: 0;">
<div class="navbar-header">
<button aria-controls="navbar" aria-expanded="false" data-target="#navbar" data-toggle="collapse" class="navbar-toggle collapsed" type="button">
@ -55,6 +56,11 @@
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;{{i18n .Lang "change_password"}}</a></li>
<li role="separator" class="divider"></li>
{{ end }}
{{ if eq .AuthMode "db_auth" }}
{{ if eq .IsAdmin true }}
<li><a id="aAddUser" href="/addUser" target="_blank"><span class="glyphicon glyphicon-plus"></span>&nbsp;&nbsp;{{i18n .Lang "add_user"}}</a></li>
{{ end }}
{{ end}}
<li><a id="aLogout" href="#"><span class="glyphicon glyphicon-log-in"></span>&nbsp;&nbsp;{{i18n .Lang "log_out"}}</a></li>
</ul>
</li>
@ -63,7 +69,9 @@
{{ else if eq .AuthMode "db_auth" }}
<div class="input-group">
&nbsp;<button type="button" class="btn btn-default" id="btnSignIn">{{i18n .Lang "sign_in"}}</button>
{{ if eq .SelfRegistration true }}
&nbsp;<button type="button" class="btn btn-success" id="btnSignUp">{{i18n .Lang "sign_up"}}</button>
{{ end }}
</div>
{{ else }}
<div class="input-group">