mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-22 16:48:30 +01:00
update self-registration features and merge from master.
This commit is contained in:
commit
21430b0ebb
5
AUTHORS
5
AUTHORS
@ -1,10 +1,15 @@
|
||||
# This file lists all individuals having contributed content to the repository.
|
||||
|
||||
Amanda Zhang <amzhang@vmware.com>
|
||||
Ben Niu Ji <benniuji@gmail.com>
|
||||
Bobby Zhang <junzhang@vmware.com>
|
||||
Daniel Jiang <jiangd@vmware.com>
|
||||
Haining Henry Zhang <henryzhang@vmware.com>
|
||||
Hao Xia <haox@vmware.com>
|
||||
Jack Liu <ljack@vmware.com>
|
||||
Kun Wang <kunw@vmware.com>
|
||||
Shan Zhu <zhus@vmware.com>
|
||||
Victoria Zheng <vzheng@vmware.com>
|
||||
Wenkai Yin <yinw@vmware.com>
|
||||
Yan Wang <wangyan@vmware.com>
|
||||
|
||||
|
@ -22,5 +22,5 @@ ldap_basedn = uid=%s,ou=people,dc=mydomain,dc=com
|
||||
#The password for root user of db
|
||||
db_password = root123
|
||||
#Switch for self-registration feature
|
||||
self_registration = off
|
||||
self_registration = on
|
||||
#####
|
||||
|
@ -63,7 +63,7 @@ We welcome contributions from the community. If you wish to contribute code, we
|
||||
Harbor is available under the [Apache 2 license](LICENSE).
|
||||
|
||||
### Partners
|
||||
<a href="https://www.shurenyun.com/" border="0" target="_blank"><img alt="DataMan" src="docs/img/dataman.png"></a>
|
||||
<a href="https://www.shurenyun.com/" border="0" target="_blank"><img alt="DataMan" src="docs/img/dataman.png"></a> <a href="http://www.slamtec.com" target="_blank" border="0"><img alt="SlamTec" src="docs/img/slamteclogo.png"></a>
|
||||
|
||||
### Users
|
||||
<a href="https://www.madailicai.com/" border="0" target="_blank"><img alt="MaDaiLiCai" src="docs/img/UserMaDai.jpg"></a> <a href="http://www.slamtec.com" target="_blank" border="0"><img alt="SlamTec" src="docs/img/slamteclogo.png"></a>
|
||||
<a href="https://www.madailicai.com/" border="0" target="_blank"><img alt="MaDaiLiCai" src="docs/img/UserMaDai.jpg"></a>
|
||||
|
@ -16,12 +16,14 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"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 ...
|
||||
@ -47,11 +49,11 @@ type langType struct {
|
||||
|
||||
const (
|
||||
defaultLang = "en-US"
|
||||
adminUserID = 1
|
||||
)
|
||||
|
||||
var supportLanguages map[string]langType
|
||||
var selfRegistration bool
|
||||
var enableAddUserByAdmin bool
|
||||
var isAdminLoginedUser bool
|
||||
|
||||
// Prepare extracts the language information from request and populate data for rendering templates.
|
||||
func (b *BaseController) Prepare() {
|
||||
@ -107,17 +109,23 @@ func (b *BaseController) Prepare() {
|
||||
}
|
||||
b.Data["AuthMode"] = authMode
|
||||
|
||||
strSelfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION"))
|
||||
selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION"))
|
||||
|
||||
if strSelfRegistration == "on" {
|
||||
selfRegistration = true
|
||||
if selfRegistration == "off" {
|
||||
enableAddUserByAdmin = true
|
||||
}
|
||||
|
||||
if sessionUserID != nil && sessionUserID.(int) != adminUserID {
|
||||
selfRegistration = false
|
||||
if sessionUserID != nil {
|
||||
var err error
|
||||
isAdminLoginedUser, err = dao.IsAdminRole(sessionUserID)
|
||||
if err != nil {
|
||||
log.Errorf("Error occurred in IsAdminRole:%v", err)
|
||||
b.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
}
|
||||
|
||||
b.Data["EnableAddUserByAdmin"] = selfRegistration
|
||||
b.Data["IsAdminLoginedUser"] = isAdminLoginedUser
|
||||
b.Data["EnableAddUserByAdmin"] = enableAddUserByAdmin
|
||||
|
||||
}
|
||||
|
||||
@ -141,10 +149,10 @@ func init() {
|
||||
//conf/app.conf -> os.Getenv("config_path")
|
||||
configPath := os.Getenv("CONFIG_PATH")
|
||||
if len(configPath) != 0 {
|
||||
log.Printf("Config path: %s", configPath)
|
||||
log.Infof("Config path: %s", configPath)
|
||||
beego.AppConfigPath = configPath
|
||||
if err := beego.ParseConfig(); err != nil {
|
||||
beego.Warning("Failed to parse config file: ", configPath, "error: ", err)
|
||||
log.Warningf("Failed to parse config file: %s, error: %v", configPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +175,7 @@ func init() {
|
||||
|
||||
for _, lang := range langs {
|
||||
if err := i18n.SetMessage(lang, "static/i18n/"+"locale_"+lang+".ini"); err != nil {
|
||||
beego.Error("Fail to set message file:" + err.Error())
|
||||
log.Errorf("Fail to set message file: %s", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,8 +21,7 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/vmware/harbor/dao"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/vmware/harbor/utils/log"
|
||||
)
|
||||
|
||||
// ItemDetailController handles requet to /registry/detail, which shows the detail of a project.
|
||||
@ -37,7 +36,7 @@ func (idc *ItemDetailController) Get() {
|
||||
projectID, _ := idc.GetInt64("project_id")
|
||||
|
||||
if projectID <= 0 {
|
||||
beego.Error("Invalid project id:", projectID)
|
||||
log.Errorf("Invalid project id: %d", projectID)
|
||||
idc.Redirect("/signIn", http.StatusFound)
|
||||
return
|
||||
}
|
||||
@ -45,7 +44,7 @@ func (idc *ItemDetailController) Get() {
|
||||
project, err := dao.GetProjectByID(projectID)
|
||||
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in GetProjectById:", err)
|
||||
log.Errorf("Error occurred in GetProjectById: %v", err)
|
||||
idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
|
||||
@ -70,13 +69,13 @@ func (idc *ItemDetailController) Get() {
|
||||
|
||||
roleList, err := dao.GetUserProjectRoles(userID, projectID)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in GetUserProjectRoles:", err)
|
||||
log.Errorf("Error occurred in GetUserProjectRoles: %v", err)
|
||||
idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
|
||||
isAdmin, err := dao.IsAdminRole(userID)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in IsAdminRole:", err)
|
||||
log.Errorf("Error occurred in IsAdminRole: %v", err)
|
||||
idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,7 @@ import (
|
||||
|
||||
"github.com/vmware/harbor/auth"
|
||||
"github.com/vmware/harbor/models"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/vmware/harbor/utils/log"
|
||||
)
|
||||
|
||||
// IndexController handles request to /
|
||||
@ -52,7 +51,7 @@ func (c *CommonController) Login() {
|
||||
|
||||
user, err := auth.Login(models.AuthModel{principal, password})
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in UserLogin:", err)
|
||||
log.Errorf("Error occurred in UserLogin: %v", err)
|
||||
c.CustomAbort(http.StatusUnauthorized, "")
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/vmware/harbor/dao"
|
||||
"github.com/vmware/harbor/models"
|
||||
"github.com/vmware/harbor/utils"
|
||||
"github.com/vmware/harbor/utils/log"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
@ -51,25 +52,25 @@ func (cc *CommonController) UpdatePassword() {
|
||||
sessionUserID := cc.GetSession("userId")
|
||||
|
||||
if sessionUserID == nil {
|
||||
beego.Warning("User does not login.")
|
||||
log.Warning("User does not login.")
|
||||
cc.CustomAbort(http.StatusUnauthorized, "please_login_first")
|
||||
}
|
||||
|
||||
oldPassword := cc.GetString("old_password")
|
||||
if oldPassword == "" {
|
||||
beego.Error("Old password is blank")
|
||||
log.Error("Old password is blank")
|
||||
cc.CustomAbort(http.StatusBadRequest, "Old password is blank")
|
||||
}
|
||||
|
||||
queryUser := models.User{UserID: sessionUserID.(int), Password: oldPassword}
|
||||
user, err := dao.CheckUserPassword(queryUser)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in CheckUserPassword:", err)
|
||||
log.Errorf("Error occurred in CheckUserPassword: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
|
||||
if user == nil {
|
||||
beego.Warning("Password input is not correct")
|
||||
log.Warning("Password input is not correct")
|
||||
cc.CustomAbort(http.StatusForbidden, "old_password_is_not_correct")
|
||||
}
|
||||
|
||||
@ -78,7 +79,7 @@ func (cc *CommonController) UpdatePassword() {
|
||||
updateUser := models.User{UserID: sessionUserID.(int), Password: password, Salt: user.Salt}
|
||||
err = dao.ChangeUserPassword(updateUser, oldPassword)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in ChangeUserPassword:", err)
|
||||
log.Errorf("Error occurred in ChangeUserPassword: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
} else {
|
||||
@ -116,7 +117,7 @@ func (cc *CommonController) SendEmail() {
|
||||
queryUser := models.User{Email: email}
|
||||
exist, err := dao.UserExists(queryUser, "email")
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in UserExists:", err)
|
||||
log.Errorf("Error occurred in UserExists: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
if !exist {
|
||||
@ -125,7 +126,7 @@ func (cc *CommonController) SendEmail() {
|
||||
|
||||
messageTemplate, err := template.ParseFiles("views/reset-password-mail.tpl")
|
||||
if err != nil {
|
||||
beego.Error("Parse email template file failed:", err)
|
||||
log.Errorf("Parse email template file failed: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, err.Error())
|
||||
}
|
||||
|
||||
@ -137,7 +138,7 @@ func (cc *CommonController) SendEmail() {
|
||||
}
|
||||
uuid, err := dao.GenerateRandomString()
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in GenerateRandomString:", err)
|
||||
log.Errorf("Error occurred in GenerateRandomString: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
err = messageTemplate.Execute(message, messageDetail{
|
||||
@ -147,13 +148,13 @@ func (cc *CommonController) SendEmail() {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
beego.Error("message template error:", err)
|
||||
log.Errorf("Message template error: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "internal_error")
|
||||
}
|
||||
|
||||
config, err := beego.AppConfig.GetSection("mail")
|
||||
if err != nil {
|
||||
beego.Error("Can not load app.conf:", err)
|
||||
log.Errorf("Can not load app.conf: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "internal_error")
|
||||
}
|
||||
|
||||
@ -166,7 +167,7 @@ func (cc *CommonController) SendEmail() {
|
||||
err = mail.SendMail()
|
||||
|
||||
if err != nil {
|
||||
beego.Error("send email failed:", err)
|
||||
log.Errorf("Send email failed: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "send_email_failed")
|
||||
}
|
||||
|
||||
@ -187,7 +188,7 @@ func (rpc *ResetPasswordController) Get() {
|
||||
|
||||
resetUUID := rpc.GetString("reset_uuid")
|
||||
if resetUUID == "" {
|
||||
beego.Error("Reset uuid is blank.")
|
||||
log.Error("Reset uuid is blank.")
|
||||
rpc.Redirect("/", http.StatusFound)
|
||||
return
|
||||
}
|
||||
@ -195,7 +196,7 @@ func (rpc *ResetPasswordController) Get() {
|
||||
queryUser := models.User{ResetUUID: resetUUID}
|
||||
user, err := dao.GetUser(queryUser)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in GetUser:", err)
|
||||
log.Errorf("Error occurred in GetUser: %v", err)
|
||||
rpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
|
||||
@ -218,11 +219,11 @@ func (cc *CommonController) ResetPassword() {
|
||||
queryUser := models.User{ResetUUID: resetUUID}
|
||||
user, err := dao.GetUser(queryUser)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in GetUser:", err)
|
||||
log.Errorf("Error occurred in GetUser: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
if user == nil {
|
||||
beego.Error("User does not exist")
|
||||
log.Error("User does not exist")
|
||||
cc.CustomAbort(http.StatusBadRequest, "User does not exist")
|
||||
}
|
||||
|
||||
@ -232,7 +233,7 @@ func (cc *CommonController) ResetPassword() {
|
||||
user.Password = password
|
||||
err = dao.ResetUserPassword(*user)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in ResetUserPassword:", err)
|
||||
log.Errorf("Error occurred in ResetUserPassword: %v", err)
|
||||
cc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
} else {
|
||||
|
@ -24,8 +24,6 @@ import (
|
||||
"github.com/vmware/harbor/models"
|
||||
|
||||
"github.com/vmware/harbor/utils/log"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
)
|
||||
|
||||
// RegisterController handles request to /register
|
||||
@ -38,12 +36,13 @@ func (rc *RegisterController) Get() {
|
||||
|
||||
pageTitleKey := "page_title_registration"
|
||||
|
||||
if selfRegistration {
|
||||
sessionUserID := rc.GetSession("userId")
|
||||
if sessionUserID == nil || sessionUserID.(int) != adminUserID {
|
||||
if enableAddUserByAdmin {
|
||||
|
||||
if !isAdminLoginedUser {
|
||||
log.Error("Self registration can only be used by admin user.\n")
|
||||
rc.Redirect("/signIn", http.StatusFound)
|
||||
}
|
||||
|
||||
pageTitleKey = "page_title_add_user"
|
||||
}
|
||||
|
||||
@ -58,12 +57,9 @@ func (rc *RegisterController) Get() {
|
||||
// SignUp insert data into DB based on data in form.
|
||||
func (rc *CommonController) SignUp() {
|
||||
|
||||
if selfRegistration {
|
||||
sessionUserID := rc.GetSession("userId")
|
||||
if sessionUserID == nil || sessionUserID.(int) != adminUserID {
|
||||
log.Error("Self registration can only be used by admin user.\n")
|
||||
rc.Redirect("/signIn", http.StatusForbidden)
|
||||
}
|
||||
if enableAddUserByAdmin && !isAdminLoginedUser {
|
||||
log.Error("Self registration can only be used by admin user.\n")
|
||||
rc.CustomAbort(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
username := strings.TrimSpace(rc.GetString("username"))
|
||||
@ -76,7 +72,7 @@ func (rc *CommonController) SignUp() {
|
||||
|
||||
_, err := dao.Register(user)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in Register:", err)
|
||||
log.Errorf("Error occurred in Register: %v", err)
|
||||
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
}
|
||||
@ -96,7 +92,7 @@ func (rc *CommonController) UserExists() {
|
||||
|
||||
exist, err := dao.UserExists(user, target)
|
||||
if err != nil {
|
||||
beego.Error("Error occurred in UserExists:", err)
|
||||
log.Errorf("Error occurred in UserExists: %v", err)
|
||||
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
|
||||
}
|
||||
rc.Data["json"] = exist
|
||||
|
@ -4,7 +4,7 @@ Because Harbor does not ship with any certificates, it uses HTTP by default to s
|
||||
|
||||
##Get a certificate
|
||||
|
||||
Assuming that your registry’s **hostname** is **reg.yourdomain.com**, and that its DNS record points to the host where you are running Harbor, you first should get a certificate from a CA. The certificate usually contains a .crt file and a .key file, for example, **yourdomain.com.crt** and **yourdomain.com.key**.
|
||||
Assuming that your registry's **hostname** is **reg.yourdomain.com**, and that its DNS record points to the host where you are running Harbor. You first should get a certificate from a CA. The certificate usually contains a .crt file and a .key file, for example, **yourdomain.com.crt** and **yourdomain.com.key**.
|
||||
|
||||
In a test or development environment, you may choose to use a self-signed certificate instead of the one from a CA. The below commands generate your own certificate:
|
||||
|
||||
@ -20,9 +20,9 @@ In a test or development environment, you may choose to use a self-signed certif
|
||||
-newkey rsa:4096 -nodes -sha256 -keyout yourdomain.com.key \
|
||||
-out yourdomain.com.csr
|
||||
```
|
||||
3) Generate the certificate of your registry host
|
||||
3) Generate the certificate of your registry host:
|
||||
|
||||
You need to configure openssl first. On Ubuntu, the config file locates at /etc/ssl/openssl.cnf. Refer to openssl document for more information. The default CA directory of openssl is called demoCA. Let’s creates necessary directories and files:
|
||||
You need to configure openssl first. On Ubuntu, the config file locates at /etc/ssl/openssl.cnf. Refer to openssl document for more information. The default CA directory of openssl is called demoCA. Let's create necessary directories and files:
|
||||
```
|
||||
mkdir demoCA
|
||||
cd demoCA
|
||||
@ -32,7 +32,7 @@ You need to configure openssl first. On Ubuntu, the config file locates at /etc/
|
||||
```
|
||||
Then run this command to generate the certificate of your registry host:
|
||||
```
|
||||
openssl ca -in yourdomain.com.csr -out yourdomain.com.crt -cert ca.crt -keyfile ca.key –outdir .
|
||||
openssl ca -in yourdomain.com.csr -out yourdomain.com.crt -cert ca.crt -keyfile ca.key -outdir .
|
||||
```
|
||||
|
||||
##Configuration of Nginx
|
||||
@ -40,7 +40,7 @@ After obtaining the **yourdomain.com.crt** and **yourdomain.com.key** files, cha
|
||||
```
|
||||
cd Deploy/config/nginx
|
||||
```
|
||||
Create a new directory “cert/” if it does not exist. Then copy **yourdomain.com.crt** and **yourdomain.com.key** to cert/.
|
||||
Create a new directory cert/, if it does not exist. Then copy **yourdomain.com.crt** and **yourdomain.com.key** to cert/.
|
||||
|
||||
Rename the existing configuration file of Nginx:
|
||||
```
|
||||
@ -50,28 +50,26 @@ Copy the template **nginx.https.conf** as the new configuration file:
|
||||
```
|
||||
cp nginx.https.conf nginx.conf
|
||||
```
|
||||
Edit the file nginx.conf and replace two occurrences of **server name** harbordomain.com to your own host name: reg.yourdomain.com .
|
||||
Edit the file nginx.conf and replace two occurrences of **harbordomain.com** to your own host name, such as reg.yourdomain.com .
|
||||
```
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name harbordomain.com;
|
||||
|
||||
…
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name harbordomain.com;
|
||||
rewrite ^/(.*) https://$server_name$1 permanent;
|
||||
|
||||
...
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name harbordomain.com;
|
||||
rewrite ^/(.*) https://$server_name$1 permanent;
|
||||
```
|
||||
Then look for the SSL section to make sure the files of your certificates match the names in the config file. Do not change the path of the files.
|
||||
```
|
||||
…
|
||||
|
||||
...
|
||||
|
||||
# SSL
|
||||
ssl_certificate /etc/nginx/cert/yourdomain.com.crt;
|
||||
ssl_certificate_key /etc/nginx/cert/yourdomain.com.key;
|
||||
|
||||
```
|
||||
Save your changes in nginx.conf.
|
||||
|
||||
@ -95,29 +93,30 @@ If Harbor is already running, stop and remove the existing instance. Your image
|
||||
```
|
||||
Finally, restart Harbor:
|
||||
```
|
||||
docker-compose up –d
|
||||
docker-compose up -d
|
||||
```
|
||||
After setting up HTTPS for Harbor, you can verify it by the follow steps:
|
||||
|
||||
1. Open a browser and enter the address: https://reg.yourdomain.com . It should display the user interface of Harbor.
|
||||
|
||||
2. On a machine with Docker daemon, make sure the option “--insecure-registry” does not present, run any docker command to verify the setup, e.g.
|
||||
2. On a machine with Docker daemon, make sure the option "-insecure-registry" does not present, run any docker command to verify the setup, e.g.
|
||||
```
|
||||
docker login reg.yourdomain.com
|
||||
```
|
||||
##Troubleshooting
|
||||
1.` `You may get an intermediate certificate from a certificate issuer. In this case, you should merge the intermediate certificate with your own certificate to create a certificate bundle. You can achieve this by the below command:
|
||||
```
|
||||
cat intermediate-certificate.pem >> yourdomain.com.crt
|
||||
```
|
||||
2.` `On some systems where docker daemon runs, you may need to trust the certificate at OS level.
|
||||
On Ubuntu, this can be done by below commands:
|
||||
```
|
||||
cp youdomain.com.crt /usr/local/share/ca-certificates/reg.yourdomain.com.crt
|
||||
update-ca-certificates
|
||||
```
|
||||
On Red Hat (CentOS etc), the commands are:
|
||||
```
|
||||
cp yourdomain.com.crt /etc/pki/ca-trust/source/anchors/reg.yourdomain.com.crt
|
||||
update-ca-trust
|
||||
|
||||
1. You may get an intermediate certificate from a certificate issuer. In this case, you should merge the intermediate certificate with your own certificate to create a certificate bundle. You can achieve this by the below command:
|
||||
```
|
||||
cat intermediate-certificate.pem >> yourdomain.com.crt
|
||||
```
|
||||
2. On some systems where docker daemon runs, you may need to trust the certificate at OS level.
|
||||
On Ubuntu, this can be done by below commands:
|
||||
```sh
|
||||
cp youdomain.com.crt /usr/local/share/ca-certificates/reg.yourdomain.com.crt
|
||||
update-ca-certificates
|
||||
```
|
||||
|
||||
On Red Hat (CentOS etc), the commands are:
|
||||
```sh
|
||||
cp yourdomain.com.crt /etc/pki/ca-trust/source/anchors/reg.yourdomain.com.crt
|
||||
update-ca-trust
|
||||
```
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.0 KiB |
@ -21,7 +21,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"regexp"
|
||||
|
||||
"github.com/vmware/harbor/utils/log"
|
||||
)
|
||||
@ -62,22 +62,13 @@ func RegistryAPIGet(url, username string) ([]byte, error) {
|
||||
} else if response.StatusCode == http.StatusUnauthorized {
|
||||
authenticate := response.Header.Get("WWW-Authenticate")
|
||||
log.Debugf("authenticate header: %s", authenticate)
|
||||
str := strings.Split(authenticate, " ")[1]
|
||||
var service string
|
||||
var scope string
|
||||
strs := strings.Split(str, ",")
|
||||
for _, s := range strs {
|
||||
if strings.Contains(s, "service") {
|
||||
service = s
|
||||
} else if strings.Contains(s, "scope") {
|
||||
scope = s
|
||||
}
|
||||
}
|
||||
if arr := strings.Split(service, "\""); len(arr) > 1 {
|
||||
service = arr[1]
|
||||
}
|
||||
if arr := strings.Split(scope, "\""); len(arr) > 1 {
|
||||
scope = arr[1]
|
||||
re := regexp.MustCompile(`service=\"(.*?)\".*scope=\"(.*?)\"`)
|
||||
res := re.FindStringSubmatch(authenticate)
|
||||
if len(res) > 2 {
|
||||
service = res[1]
|
||||
scope = res[2]
|
||||
}
|
||||
token, err := GenTokenForUI(username, service, scope)
|
||||
if err != nil {
|
||||
|
@ -36,7 +36,7 @@ jQuery(function(){
|
||||
var confirmedPassword = $.trim($("#ConfirmedPassword").val());
|
||||
var realname = $.trim($("#Realname").val());
|
||||
var comment = $.trim($("#Comment").val());
|
||||
var enableAddUserByAdmin = $("#enableAddUserByAdmin").val();
|
||||
var isAdminLoginedUser = $("#isAdminLoginedUser").val();
|
||||
|
||||
$.ajax({
|
||||
url : '/signUp',
|
||||
@ -49,10 +49,10 @@ jQuery(function(){
|
||||
if(xhr && xhr.status == 200){
|
||||
$("#dlgModal")
|
||||
.dialogModal({
|
||||
"title": enableAddUserByAdmin == "true" ? i18n.getMessage("title_add_user") : i18n.getMessage("title_sign_up"),
|
||||
"content": enableAddUserByAdmin == "true" ? i18n.getMessage("added_user_successfully") : i18n.getMessage("registered_successfully"),
|
||||
"title": isAdminLoginedUser == "true" ? i18n.getMessage("title_add_user") : i18n.getMessage("title_sign_up"),
|
||||
"content": isAdminLoginedUser == "true" ? i18n.getMessage("added_user_successfully") : i18n.getMessage("registered_successfully"),
|
||||
"callback": function(){
|
||||
if(enableAddUserByAdmin == "true") {
|
||||
if(isAdminLoginedUser == "true") {
|
||||
document.location = "/registry/project";
|
||||
}else{
|
||||
document.location = "/signIn";
|
||||
|
@ -16,7 +16,7 @@
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-4">
|
||||
<div class="page-header">
|
||||
{{ if eq .EnableAddUserByAdmin true }}
|
||||
{{ if eq .IsAdminLoginedUser true }}
|
||||
<h1>{{i18n .Lang "add_user" }}</h1>
|
||||
{{ else }}
|
||||
<h1>{{i18n .Lang "registration"}}</h1>
|
||||
@ -67,7 +67,7 @@
|
||||
<div class="form-group has-feedback">
|
||||
<div class="text-center">
|
||||
<button type="button" class="btn btn-default" id="btnPageSignUp">
|
||||
{{ if eq .EnableAddUserByAdmin true }}
|
||||
{{ if eq .IsAdminLoginedUser true }}
|
||||
{{i18n .Lang "add_user" }}
|
||||
{{ else }}
|
||||
{{i18n .Lang "sign_up"}}
|
||||
|
@ -13,7 +13,7 @@
|
||||
limitations under the License.
|
||||
-->
|
||||
<input type="hidden" id="currentLanguage" value="{{.Lang}}">
|
||||
<input type="hidden" id="enableAddUserByAdmin" value="{{.EnableAddUserByAdmin}}">
|
||||
<input type="hidden" id="isAdminLoginedUser" value="{{.IsAdminLoginedUser}}">
|
||||
<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">
|
||||
@ -56,7 +56,7 @@
|
||||
<li><a id="aChangePassword" href="/changePassword" target="_blank"><span class="glyphicon glyphicon-pencil"></span> {{i18n .Lang "change_password"}}</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
{{ end }}
|
||||
{{ if eq .EnableAddUserByAdmin true }}
|
||||
{{ if eq .IsAdminLoginedUser true }}
|
||||
<li><a id="aSelfSignUp" href="/register" target="_blank"><span class="glyphicon glyphicon-plus"></span> {{i18n .Lang "add_user"}}</a></li>
|
||||
{{ end}}
|
||||
<li><a id="aLogout" href="#"><span class="glyphicon glyphicon-log-in"></span> {{i18n .Lang "log_out"}}</a></li>
|
||||
|
Loading…
Reference in New Issue
Block a user