mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-08 16:02:15 +01:00
fix issue in golint, support project creation restriction at backend
This commit is contained in:
parent
33da8b230e
commit
9d7a18a0a3
@ -26,4 +26,4 @@ EXT_ENDPOINT=$ui_url
|
|||||||
TOKEN_ENDPOINT=http://ui
|
TOKEN_ENDPOINT=http://ui
|
||||||
VERIFY_REMOTE_CERT=$verify_remote_cert
|
VERIFY_REMOTE_CERT=$verify_remote_cert
|
||||||
TOKEN_EXPIRATION=$token_expiration
|
TOKEN_EXPIRATION=$token_expiration
|
||||||
CREATE_PROJECT_RESTRICTION=$create_project_restriction
|
PROJECT_CREATION_RESTRICTION=$project_creation_restriction
|
||||||
|
@ -83,6 +83,9 @@ crt_organizationalunit = organizational unit
|
|||||||
crt_commonname = example.com
|
crt_commonname = example.com
|
||||||
crt_email = example@example.com
|
crt_email = example@example.com
|
||||||
|
|
||||||
|
#The flag to control what users have permission to create projects
|
||||||
|
#Be default everyone can create a project, set to "adminonly" such that only admin can create project.
|
||||||
|
project_creation_restriction = adminonly
|
||||||
|
|
||||||
#The path of cert and key files for nginx, they are applied only the protocol is set to https
|
#The path of cert and key files for nginx, they are applied only the protocol is set to https
|
||||||
ssl_cert = /data/server.crt
|
ssl_cert = /data/server.crt
|
||||||
|
@ -32,6 +32,10 @@ def validate(conf):
|
|||||||
cert_key_path = rcp.get("configuration", "ssl_cert_key")
|
cert_key_path = rcp.get("configuration", "ssl_cert_key")
|
||||||
if not os.path.isfile(cert_key_path):
|
if not os.path.isfile(cert_key_path):
|
||||||
raise Exception("Error: The path for certificate key: %s is invalid" % cert_key_path)
|
raise Exception("Error: The path for certificate key: %s is invalid" % cert_key_path)
|
||||||
|
project_creation = rcp.get("configuration", "project_creation_restriction")
|
||||||
|
|
||||||
|
if project_creation != "everyone" and project_creation != "adminonly":
|
||||||
|
raise Exception("Error invalid value for project_creation_restriction: %s" % project_creation)
|
||||||
|
|
||||||
def get_secret_key(path):
|
def get_secret_key(path):
|
||||||
key_file = os.path.join(path, "secretkey")
|
key_file = os.path.join(path, "secretkey")
|
||||||
@ -115,6 +119,7 @@ crt_email = rcp.get("configuration", "crt_email")
|
|||||||
max_job_workers = rcp.get("configuration", "max_job_workers")
|
max_job_workers = rcp.get("configuration", "max_job_workers")
|
||||||
token_expiration = rcp.get("configuration", "token_expiration")
|
token_expiration = rcp.get("configuration", "token_expiration")
|
||||||
verify_remote_cert = rcp.get("configuration", "verify_remote_cert")
|
verify_remote_cert = rcp.get("configuration", "verify_remote_cert")
|
||||||
|
proj_cre_restriction = rcp.get("configuration", "project_creation_restriction")
|
||||||
#secret_key = rcp.get("configuration", "secret_key")
|
#secret_key = rcp.get("configuration", "secret_key")
|
||||||
secret_key = get_secret_key(args.data_volume)
|
secret_key = get_secret_key(args.data_volume)
|
||||||
########
|
########
|
||||||
@ -200,6 +205,7 @@ render(os.path.join(templates_dir, "ui", "env"),
|
|||||||
ui_secret=ui_secret,
|
ui_secret=ui_secret,
|
||||||
secret_key=secret_key,
|
secret_key=secret_key,
|
||||||
verify_remote_cert=verify_remote_cert,
|
verify_remote_cert=verify_remote_cert,
|
||||||
|
project_creation_restriction=proj_cre_restriction,
|
||||||
token_expiration=token_expiration)
|
token_expiration=token_expiration)
|
||||||
|
|
||||||
render(os.path.join(templates_dir, "ui", "app.conf"),
|
render(os.path.join(templates_dir, "ui", "app.conf"),
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Package config provide methods to get the configurations reqruied by code in src/common
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -20,8 +22,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigLoader is the interface to load configurations
|
// ConfLoader is the interface to load configurations
|
||||||
type ConfigLoader interface {
|
type ConfLoader interface {
|
||||||
|
|
||||||
// Load will load configuration from different source into a string map, the values in the map will be parsed in to configurations.
|
// Load will load configuration from different source into a string map, the values in the map will be parsed in to configurations.
|
||||||
Load() (map[string]string, error)
|
Load() (map[string]string, error)
|
||||||
@ -41,18 +43,22 @@ func (ec *EnvConfigLoader) Load() (map[string]string, error) {
|
|||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigParser
|
// ConfParser ...
|
||||||
type ConfigParser interface {
|
type ConfParser interface {
|
||||||
|
|
||||||
//Parse parse the input raw map into a config map
|
//Parse parse the input raw map into a config map
|
||||||
Parse(raw map[string]string, config map[string]interface{}) error
|
Parse(raw map[string]string, config map[string]interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config wraps a map for the processed configuration values,
|
||||||
|
// and loader parser to read configuration from external source and process the values.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Config map[string]interface{}
|
Config map[string]interface{}
|
||||||
Loader ConfigLoader
|
Loader ConfLoader
|
||||||
Parser ConfigParser
|
Parser ConfParser
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load reload the configurations
|
||||||
func (conf *Config) Load() error {
|
func (conf *Config) Load() error {
|
||||||
rawMap, err := conf.Loader.Load()
|
rawMap, err := conf.Loader.Load()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -62,6 +68,7 @@ func (conf *Config) Load() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MySQLSetting wraps the settings of a MySQL DB
|
||||||
type MySQLSetting struct {
|
type MySQLSetting struct {
|
||||||
Database string
|
Database string
|
||||||
User string
|
User string
|
||||||
@ -70,6 +77,7 @@ type MySQLSetting struct {
|
|||||||
Port string
|
Port string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SQLiteSetting wraps the settings of a SQLite DB
|
||||||
type SQLiteSetting struct {
|
type SQLiteSetting struct {
|
||||||
FilePath string
|
FilePath string
|
||||||
}
|
}
|
||||||
@ -165,6 +173,7 @@ func TokenEndpoint() string {
|
|||||||
return commonConfig.Config["token_endpoint"].(string)
|
return commonConfig.Config["token_endpoint"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogLevel returns the log level in string format.
|
||||||
func LogLevel() string {
|
func LogLevel() string {
|
||||||
return commonConfig.Config["log_level"].(string)
|
return commonConfig.Config["log_level"].(string)
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ func getDatabase() (db Database, err error) {
|
|||||||
switch config.Database() {
|
switch config.Database() {
|
||||||
case "", "mysql":
|
case "", "mysql":
|
||||||
db = NewMySQL(config.MySQL().Host, config.MySQL().Port, config.MySQL().User,
|
db = NewMySQL(config.MySQL().Host, config.MySQL().Port, config.MySQL().User,
|
||||||
config.MySQL().Port, config.MySQL().Database)
|
config.MySQL().Password, config.MySQL().Database)
|
||||||
case "sqlite":
|
case "sqlite":
|
||||||
db = NewSQLite(config.SQLite().FilePath)
|
db = NewSQLite(config.SQLite().FilePath)
|
||||||
default:
|
default:
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
@ -72,11 +73,19 @@ func (p *ProjectAPI) Prepare() {
|
|||||||
// Post ...
|
// Post ...
|
||||||
func (p *ProjectAPI) Post() {
|
func (p *ProjectAPI) Post() {
|
||||||
p.userID = p.ValidateUser()
|
p.userID = p.ValidateUser()
|
||||||
|
isSysAdmin, err := dao.IsAdminRole(p.userID)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("Failed to check admin role: %v", err)
|
||||||
|
}
|
||||||
|
if !isSysAdmin && config.OnlyAdminCreateProject() {
|
||||||
|
log.Errorf("Only sys admin can create project")
|
||||||
|
p.RenderError(http.StatusForbidden, "Only system admin can create project")
|
||||||
|
return
|
||||||
|
}
|
||||||
var req projectReq
|
var req projectReq
|
||||||
p.DecodeJSONReq(&req)
|
p.DecodeJSONReq(&req)
|
||||||
public := req.Public
|
public := req.Public
|
||||||
err := validateProjectReq(req)
|
err = validateProjectReq(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Invalid project request, error: %v", err)
|
log.Errorf("Invalid project request, error: %v", err)
|
||||||
p.RenderError(http.StatusBadRequest, fmt.Sprintf("invalid request: %v", err))
|
p.RenderError(http.StatusBadRequest, fmt.Sprintf("invalid request: %v", err))
|
||||||
|
@ -19,23 +19,23 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"github.com/docker/distribution/manifest/schema1"
|
"github.com/docker/distribution/manifest/schema1"
|
||||||
"github.com/docker/distribution/manifest/schema2"
|
"github.com/docker/distribution/manifest/schema2"
|
||||||
|
"github.com/vmware/harbor/src/common/api"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/common/utils/registry"
|
||||||
"github.com/vmware/harbor/src/ui/service/cache"
|
"github.com/vmware/harbor/src/ui/service/cache"
|
||||||
svc_utils "github.com/vmware/harbor/src/ui/service/utils"
|
svc_utils "github.com/vmware/harbor/src/ui/service/utils"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
|
||||||
"github.com/vmware/harbor/src/common/api"
|
|
||||||
"github.com/vmware/harbor/src/common/utils/registry"
|
|
||||||
|
|
||||||
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/utils"
|
"github.com/vmware/harbor/src/common/utils"
|
||||||
"github.com/vmware/harbor/src/common/utils/registry/auth"
|
"github.com/vmware/harbor/src/common/utils/registry/auth"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RepositoryAPI handles request to /api/repositories /api/repositories/tags /api/repositories/manifests, the parm has to be put
|
// RepositoryAPI handles request to /api/repositories /api/repositories/tags /api/repositories/manifests, the parm has to be put
|
||||||
@ -361,7 +361,7 @@ func (ra *RepositoryAPI) GetManifests() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ra *RepositoryAPI) initRepositoryClient(repoName string) (r *registry.Repository, err error) {
|
func (ra *RepositoryAPI) initRepositoryClient(repoName string) (r *registry.Repository, err error) {
|
||||||
endpoint := os.Getenv("REGISTRY_URL")
|
endpoint := config.InternalRegistryURL()
|
||||||
|
|
||||||
username, password, ok := ra.Ctx.Request.BasicAuth()
|
username, password, ok := ra.Ctx.Request.BasicAuth()
|
||||||
if ok {
|
if ok {
|
||||||
|
@ -20,17 +20,17 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/common/api"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils"
|
"github.com/vmware/harbor/src/common/utils"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/common/api"
|
|
||||||
"github.com/vmware/harbor/src/common/utils/registry"
|
"github.com/vmware/harbor/src/common/utils/registry"
|
||||||
"github.com/vmware/harbor/src/common/utils/registry/auth"
|
"github.com/vmware/harbor/src/common/utils/registry/auth"
|
||||||
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TargetAPI handles request to /api/targets/ping /api/targets/{}
|
// TargetAPI handles request to /api/targets/ping /api/targets/{}
|
||||||
@ -41,8 +41,7 @@ type TargetAPI struct {
|
|||||||
|
|
||||||
// Prepare validates the user
|
// Prepare validates the user
|
||||||
func (t *TargetAPI) Prepare() {
|
func (t *TargetAPI) Prepare() {
|
||||||
//TODO:move to config
|
t.secretKey = config.SecretKey()
|
||||||
t.secretKey = os.Getenv("SECRET_KEY")
|
|
||||||
|
|
||||||
userID := t.ValidateUser()
|
userID := t.ValidateUser()
|
||||||
isSysAdmin, err := dao.IsAdminRole(userID)
|
isSysAdmin, err := dao.IsAdminRole(userID)
|
||||||
|
@ -18,7 +18,6 @@ package api
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -27,6 +26,7 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UserAPI handles request to /api/users/{}
|
// UserAPI handles request to /api/users/{}
|
||||||
@ -47,16 +47,9 @@ type passwordReq struct {
|
|||||||
// Prepare validates the URL and parms
|
// Prepare validates the URL and parms
|
||||||
func (ua *UserAPI) Prepare() {
|
func (ua *UserAPI) Prepare() {
|
||||||
|
|
||||||
authMode := strings.ToLower(os.Getenv("AUTH_MODE"))
|
ua.AuthMode = config.AuthMode()
|
||||||
if authMode == "" {
|
|
||||||
authMode = "db_auth"
|
|
||||||
}
|
|
||||||
ua.AuthMode = authMode
|
|
||||||
|
|
||||||
selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION"))
|
ua.SelfRegistration = config.SelfRegistration()
|
||||||
if selfRegistration == "on" {
|
|
||||||
ua.SelfRegistration = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if ua.Ctx.Input.IsPost() {
|
if ua.Ctx.Input.IsPost() {
|
||||||
sessionUserID := ua.GetSession("userId")
|
sessionUserID := ua.GetSession("userId")
|
||||||
@ -241,9 +234,7 @@ func (ua *UserAPI) Delete() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO read from conifg
|
if config.AuthMode() == "ldap_auth" {
|
||||||
authMode := os.Getenv("AUTH_MODE")
|
|
||||||
if authMode == "ldap_auth" {
|
|
||||||
ua.CustomAbort(http.StatusForbidden, "user can not be deleted in LDAP authentication mode")
|
ua.CustomAbort(http.StatusForbidden, "user can not be deleted in LDAP authentication mode")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,18 +22,18 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/ui/service/cache"
|
|
||||||
"github.com/vmware/harbor/src/common/utils"
|
"github.com/vmware/harbor/src/common/utils"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/common/utils/registry"
|
"github.com/vmware/harbor/src/common/utils/registry"
|
||||||
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
registry_error "github.com/vmware/harbor/src/common/utils/registry/error"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
"github.com/vmware/harbor/src/ui/service/cache"
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkProjectPermission(userID int, projectID int64) bool {
|
func checkProjectPermission(userID int, projectID int64) bool {
|
||||||
@ -234,8 +234,7 @@ func addAuthentication(req *http.Request) {
|
|||||||
if req != nil {
|
if req != nil {
|
||||||
req.AddCookie(&http.Cookie{
|
req.AddCookie(&http.Cookie{
|
||||||
Name: models.UISecretCookie,
|
Name: models.UISecretCookie,
|
||||||
// TODO read secret from config
|
Value: config.UISecret(),
|
||||||
Value: os.Getenv("UI_SECRET"),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -351,8 +350,7 @@ func diffRepos(reposInRegistry []string, reposInDB []string) ([]string, []string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove the workaround when the bug of registry is fixed
|
// TODO remove the workaround when the bug of registry is fixed
|
||||||
// TODO read it from config
|
endpoint := config.InternalRegistryURL()
|
||||||
endpoint := os.Getenv("REGISTRY_URL")
|
|
||||||
client, err := cache.NewRepositoryClient(endpoint, true,
|
client, err := cache.NewRepositoryClient(endpoint, true,
|
||||||
"admin", repoInR, "repository", repoInR)
|
"admin", repoInR, "repository", repoInR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -374,8 +372,7 @@ func diffRepos(reposInRegistry []string, reposInDB []string) ([]string, []string
|
|||||||
j++
|
j++
|
||||||
} else {
|
} else {
|
||||||
// TODO remove the workaround when the bug of registry is fixed
|
// TODO remove the workaround when the bug of registry is fixed
|
||||||
// TODO read it from config
|
endpoint := config.InternalRegistryURL()
|
||||||
endpoint := os.Getenv("REGISTRY_URL")
|
|
||||||
client, err := cache.NewRepositoryClient(endpoint, true,
|
client, err := cache.NewRepositoryClient(endpoint, true,
|
||||||
"admin", repoInR, "repository", repoInR)
|
"admin", repoInR, "repository", repoInR)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -425,7 +422,7 @@ func projectExists(repository string) (bool, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initRegistryClient() (r *registry.Registry, err error) {
|
func initRegistryClient() (r *registry.Registry, err error) {
|
||||||
endpoint := os.Getenv("REGISTRY_URL")
|
endpoint := config.InternalRegistryURL()
|
||||||
|
|
||||||
addr := endpoint
|
addr := endpoint
|
||||||
if strings.Contains(endpoint, "/") {
|
if strings.Contains(endpoint, "/") {
|
||||||
@ -462,32 +459,20 @@ func initRegistryClient() (r *registry.Registry, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildReplicationURL() string {
|
func buildReplicationURL() string {
|
||||||
url := getJobServiceURL()
|
url := config.InternalJobServiceURL()
|
||||||
return fmt.Sprintf("%s/api/jobs/replication", url)
|
return fmt.Sprintf("%s/api/jobs/replication", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildJobLogURL(jobID string) string {
|
func buildJobLogURL(jobID string) string {
|
||||||
url := getJobServiceURL()
|
url := config.InternalJobServiceURL()
|
||||||
return fmt.Sprintf("%s/api/jobs/replication/%s/log", url, jobID)
|
return fmt.Sprintf("%s/api/jobs/replication/%s/log", url, jobID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildReplicationActionURL() string {
|
func buildReplicationActionURL() string {
|
||||||
url := getJobServiceURL()
|
url := config.InternalJobServiceURL()
|
||||||
return fmt.Sprintf("%s/api/jobs/replication/actions", url)
|
return fmt.Sprintf("%s/api/jobs/replication/actions", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getJobServiceURL() string {
|
|
||||||
url := os.Getenv("JOB_SERVICE_URL")
|
|
||||||
url = strings.TrimSpace(url)
|
|
||||||
url = strings.TrimRight(url, "/")
|
|
||||||
|
|
||||||
if len(url) == 0 {
|
|
||||||
url = "http://jobservice"
|
|
||||||
}
|
|
||||||
|
|
||||||
return url
|
|
||||||
}
|
|
||||||
|
|
||||||
func getReposByProject(name string, keyword ...string) ([]string, error) {
|
func getReposByProject(name string, keyword ...string) ([]string, error) {
|
||||||
repositories := []string{}
|
repositories := []string{}
|
||||||
|
|
||||||
|
@ -18,14 +18,14 @@ package ldap
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/ui/auth"
|
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/ui/auth"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
|
||||||
"github.com/mqu/openldap"
|
"github.com/mqu/openldap"
|
||||||
)
|
)
|
||||||
@ -46,7 +46,7 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
|||||||
return nil, fmt.Errorf("the principal contains meta char: %q", c)
|
return nil, fmt.Errorf("the principal contains meta char: %q", c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ldapURL := os.Getenv("LDAP_URL")
|
ldapURL := config.LDAP().URL
|
||||||
if ldapURL == "" {
|
if ldapURL == "" {
|
||||||
return nil, errors.New("can not get any available LDAP_URL")
|
return nil, errors.New("can not get any available LDAP_URL")
|
||||||
}
|
}
|
||||||
@ -57,16 +57,16 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3)
|
ldap.SetOption(openldap.LDAP_OPT_PROTOCOL_VERSION, openldap.LDAP_VERSION3)
|
||||||
|
|
||||||
ldapBaseDn := os.Getenv("LDAP_BASE_DN")
|
ldapBaseDn := config.LDAP().BaseDn
|
||||||
if ldapBaseDn == "" {
|
if ldapBaseDn == "" {
|
||||||
return nil, errors.New("can not get any available LDAP_BASE_DN")
|
return nil, errors.New("can not get any available LDAP_BASE_DN")
|
||||||
}
|
}
|
||||||
log.Debug("baseDn:", ldapBaseDn)
|
log.Debug("baseDn:", ldapBaseDn)
|
||||||
|
|
||||||
ldapSearchDn := os.Getenv("LDAP_SEARCH_DN")
|
ldapSearchDn := config.LDAP().SearchDn
|
||||||
if ldapSearchDn != "" {
|
if ldapSearchDn != "" {
|
||||||
log.Debug("Search DN: ", ldapSearchDn)
|
log.Debug("Search DN: ", ldapSearchDn)
|
||||||
ldapSearchPwd := os.Getenv("LDAP_SEARCH_PWD")
|
ldapSearchPwd := config.LDAP().SearchPwd
|
||||||
err = ldap.Bind(ldapSearchDn, ldapSearchPwd)
|
err = ldap.Bind(ldapSearchDn, ldapSearchPwd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debug("Bind search dn error", err)
|
log.Debug("Bind search dn error", err)
|
||||||
@ -74,8 +74,8 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
attrName := os.Getenv("LDAP_UID")
|
attrName := config.LDAP().UID
|
||||||
filter := os.Getenv("LDAP_FILTER")
|
filter := config.LDAP().Filter
|
||||||
if filter != "" {
|
if filter != "" {
|
||||||
filter = "(&" + filter + "(" + attrName + "=" + m.Principal + "))"
|
filter = "(&" + filter + "(" + attrName + "=" + m.Principal + "))"
|
||||||
} else {
|
} else {
|
||||||
@ -83,7 +83,7 @@ func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {
|
|||||||
}
|
}
|
||||||
log.Debug("one or more filter", filter)
|
log.Debug("one or more filter", filter)
|
||||||
|
|
||||||
ldapScope := os.Getenv("LDAP_SCOPE")
|
ldapScope := config.LDAP().Scope
|
||||||
var scope int
|
var scope int
|
||||||
if ldapScope == "1" {
|
if ldapScope == "1" {
|
||||||
scope = openldap.LDAP_SCOPE_BASE
|
scope = openldap.LDAP_SCOPE_BASE
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Package config provides methods to get configurations required by code in src/ui
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -22,6 +24,7 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// LDAPSetting wraps the setting of an LDAP server
|
||||||
type LDAPSetting struct {
|
type LDAPSetting struct {
|
||||||
URL string
|
URL string
|
||||||
BaseDn string
|
BaseDn string
|
||||||
@ -50,7 +53,7 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
|
|||||||
config["ldap"] = setting
|
config["ldap"] = setting
|
||||||
}
|
}
|
||||||
config["auth_mode"] = mode
|
config["auth_mode"] = mode
|
||||||
var tokenExpiration int = 30 //minutes
|
var tokenExpiration = 30 //minutes
|
||||||
if len(raw["TOKEN_EXPIRATION"]) > 0 {
|
if len(raw["TOKEN_EXPIRATION"]) > 0 {
|
||||||
i, err := strconv.Atoi(raw["TOKEN_EXPIRATION"])
|
i, err := strconv.Atoi(raw["TOKEN_EXPIRATION"])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -67,7 +70,7 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
|
|||||||
config["ui_secret"] = raw["UI_SECRET"]
|
config["ui_secret"] = raw["UI_SECRET"]
|
||||||
config["secret_key"] = raw["SECRET_KEY"]
|
config["secret_key"] = raw["SECRET_KEY"]
|
||||||
config["self_registration"] = raw["SELF_REGISTRATION"] != "off"
|
config["self_registration"] = raw["SELF_REGISTRATION"] != "off"
|
||||||
config["admin_create_project"] = strings.ToLower(raw["PROJECT_CREATE_RESTRICTION"]) == "adminonly"
|
config["admin_create_project"] = strings.ToLower(raw["PROJECT_CREATION_RESTRICTION"]) == "adminonly"
|
||||||
registryURL := raw["REGISTRY_URL"]
|
registryURL := raw["REGISTRY_URL"]
|
||||||
registryURL = strings.TrimRight(registryURL, "/")
|
registryURL = strings.TrimRight(registryURL, "/")
|
||||||
config["internal_registry_url"] = registryURL
|
config["internal_registry_url"] = registryURL
|
||||||
@ -80,7 +83,7 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
|
|||||||
var uiConfig *commonConfig.Config
|
var uiConfig *commonConfig.Config
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
uiKeys := []string{"AUTH_MODE", "LDAP_URL", "LDAP_BASE_DN", "LDAP_SEARCH_DN", "LDAP_SEARCH_PWD", "LDAP_UID", "LDAP_FILTER", "LDAP_SCOPE", "TOKEN_EXPIRATION", "HARBOR_ADMIN_PASSWORD", "EXT_REG_URL", "UI_SECRET", "SECRET_KEY", "SELF_REGISTRATION", "PROJECT_CREATE_RESTRICTION", "REGISTRY_URL", "JOB_SERVICE_URL"}
|
uiKeys := []string{"AUTH_MODE", "LDAP_URL", "LDAP_BASE_DN", "LDAP_SEARCH_DN", "LDAP_SEARCH_PWD", "LDAP_UID", "LDAP_FILTER", "LDAP_SCOPE", "TOKEN_EXPIRATION", "HARBOR_ADMIN_PASSWORD", "EXT_REG_URL", "UI_SECRET", "SECRET_KEY", "SELF_REGISTRATION", "PROJECT_CREATION_RESTRICTION", "REGISTRY_URL", "JOB_SERVICE_URL"}
|
||||||
uiConfig = &commonConfig.Config{
|
uiConfig = &commonConfig.Config{
|
||||||
Config: make(map[string]interface{}),
|
Config: make(map[string]interface{}),
|
||||||
Loader: &commonConfig.EnvConfigLoader{Keys: uiKeys},
|
Loader: &commonConfig.EnvConfigLoader{Keys: uiKeys},
|
||||||
@ -91,45 +94,62 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reload ...
|
||||||
func Reload() error {
|
func Reload() error {
|
||||||
return uiConfig.Load()
|
return uiConfig.Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthMode ...
|
||||||
func AuthMode() string {
|
func AuthMode() string {
|
||||||
return uiConfig.Config["auth_mode"].(string)
|
return uiConfig.Config["auth_mode"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LDAP returns the setting of ldap server
|
||||||
func LDAP() LDAPSetting {
|
func LDAP() LDAPSetting {
|
||||||
return uiConfig.Config["ldap"].(LDAPSetting)
|
return uiConfig.Config["ldap"].(LDAPSetting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TokenExpiration returns the token expiration time (in minute)
|
||||||
func TokenExpiration() int {
|
func TokenExpiration() int {
|
||||||
return uiConfig.Config["token_exp"].(int)
|
return uiConfig.Config["token_exp"].(int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ExtRegistryURL returns the registry URL to exposed to external client
|
||||||
func ExtRegistryURL() string {
|
func ExtRegistryURL() string {
|
||||||
return uiConfig.Config["ext_reg_url"].(string)
|
return uiConfig.Config["ext_reg_url"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UISecret returns the value of UI secret cookie, used for communication between UI and JobService
|
||||||
func UISecret() string {
|
func UISecret() string {
|
||||||
return uiConfig.Config["ui_secret"].(string)
|
return uiConfig.Config["ui_secret"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SecretKey returns the secret key to encrypt the password of target
|
||||||
func SecretKey() string {
|
func SecretKey() string {
|
||||||
return uiConfig.Config["secret_key"].(string)
|
return uiConfig.Config["secret_key"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SelfRegistration returns the enablement of self registration
|
||||||
func SelfRegistration() bool {
|
func SelfRegistration() bool {
|
||||||
return uiConfig.Config["self_registration"].(bool)
|
return uiConfig.Config["self_registration"].(bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalRegistryURL returns registry URL for internal communication between Harbor containers
|
||||||
func InternalRegistryURL() string {
|
func InternalRegistryURL() string {
|
||||||
return uiConfig.Config["internal_registry_url"].(string)
|
return uiConfig.Config["internal_registry_url"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InternalJobServiceURL returns jobservice URL for internal communication between Harbor containers
|
||||||
func InternalJobServiceURL() string {
|
func InternalJobServiceURL() string {
|
||||||
return uiConfig.Config["internal_jobservice_url"].(string)
|
return uiConfig.Config["internal_jobservice_url"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InitialAdminPassword returns the initial password for administrator
|
||||||
|
func InitialAdminPassword() string {
|
||||||
|
return uiConfig.Config["admin_password"].(string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// OnlyAdminCreateProject returns the flag to restrict that only sys admin can create project
|
||||||
func OnlyAdminCreateProject() bool {
|
func OnlyAdminCreateProject() bool {
|
||||||
return uiConfig.Config["admin_create_project"].(bool)
|
return uiConfig.Config["admin_create_project"].(bool)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ var (
|
|||||||
uiSecret = "ffadsdfsdf"
|
uiSecret = "ffadsdfsdf"
|
||||||
secretKey = "keykey"
|
secretKey = "keykey"
|
||||||
selfRegistration = "off"
|
selfRegistration = "off"
|
||||||
projectCreationRestriction = "everyone"
|
projectCreationRestriction = "adminonly"
|
||||||
internalRegistryURL = "http://registry:5000"
|
internalRegistryURL = "http://registry:5000"
|
||||||
jobServiceURL = "http://jobservice"
|
jobServiceURL = "http://jobservice"
|
||||||
)
|
)
|
||||||
@ -58,7 +58,7 @@ func TestMain(m *testing.M) {
|
|||||||
os.Setenv("UI_SECRET", uiSecret)
|
os.Setenv("UI_SECRET", uiSecret)
|
||||||
os.Setenv("SECRET_KEY", secretKey)
|
os.Setenv("SECRET_KEY", secretKey)
|
||||||
os.Setenv("SELF_REGISTRATION", selfRegistration)
|
os.Setenv("SELF_REGISTRATION", selfRegistration)
|
||||||
os.Setenv("CREATE_PROJECT_RESTRICTION", projectCreationRestriction)
|
os.Setenv("PROJECT_CREATION_RESTRICTION", projectCreationRestriction)
|
||||||
os.Setenv("REGISTRY_URL", internalRegistryURL)
|
os.Setenv("REGISTRY_URL", internalRegistryURL)
|
||||||
os.Setenv("JOB_SERVICE_URL", jobServiceURL)
|
os.Setenv("JOB_SERVICE_URL", jobServiceURL)
|
||||||
|
|
||||||
@ -132,7 +132,13 @@ func TestSecrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestProjectCreationRestrict(t *testing.T) {
|
func TestProjectCreationRestrict(t *testing.T) {
|
||||||
if OnlyAdminCreateProject() {
|
if !OnlyAdminCreateProject() {
|
||||||
t.Errorf("Expected OnlyAdminCreateProject to be false")
|
t.Errorf("Expected OnlyAdminCreateProject to be true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInitAdminPassword(t *testing.T) {
|
||||||
|
if InitialAdminPassword() != adminPassword {
|
||||||
|
t.Errorf("Expected adminPassword: %s, in fact: %s", adminPassword, InitialAdminPassword)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/ui/auth"
|
"github.com/vmware/harbor/src/ui/auth"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// BaseController wraps common methods such as i18n support, forward, which can be leveraged by other UI render controllers.
|
// BaseController wraps common methods such as i18n support, forward, which can be leveraged by other UI render controllers.
|
||||||
@ -99,7 +100,7 @@ func (b *BaseController) Prepare() {
|
|||||||
b.Data["CurLang"] = curLang.Name
|
b.Data["CurLang"] = curLang.Name
|
||||||
b.Data["RestLangs"] = restLangs
|
b.Data["RestLangs"] = restLangs
|
||||||
|
|
||||||
authMode := strings.ToLower(os.Getenv("AUTH_MODE"))
|
authMode := config.AuthMode()
|
||||||
if authMode == "" {
|
if authMode == "" {
|
||||||
authMode = "db_auth"
|
authMode = "db_auth"
|
||||||
}
|
}
|
||||||
@ -116,11 +117,9 @@ func (b *BaseController) Prepare() {
|
|||||||
b.UseCompressedJS = false
|
b.UseCompressedJS = false
|
||||||
}
|
}
|
||||||
|
|
||||||
selfRegistration := strings.ToLower(os.Getenv("SELF_REGISTRATION"))
|
b.SelfRegistration = config.SelfRegistration()
|
||||||
if selfRegistration == "on" {
|
|
||||||
b.SelfRegistration = true
|
b.Data["SelfRegistration"] = config.SelfRegistration()
|
||||||
}
|
|
||||||
b.Data["SelfRegistration"] = b.SelfRegistration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward to setup layout and template for content for a page.
|
// Forward to setup layout and template for content for a page.
|
||||||
|
@ -3,7 +3,6 @@ package controllers
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import "os"
|
import (
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
)
|
||||||
|
|
||||||
// RepositoryController handles request to /repository
|
// RepositoryController handles request to /repository
|
||||||
type RepositoryController struct {
|
type RepositoryController struct {
|
||||||
@ -9,6 +11,6 @@ type RepositoryController struct {
|
|||||||
|
|
||||||
// Get renders repository page
|
// Get renders repository page
|
||||||
func (rc *RepositoryController) Get() {
|
func (rc *RepositoryController) Get() {
|
||||||
rc.Data["HarborRegUrl"] = os.Getenv("HARBOR_REG_URL")
|
rc.Data["HarborRegUrl"] = config.ExtRegistryURL()
|
||||||
rc.Forward("page_title_repository", "repository.htm")
|
rc.Forward("page_title_repository", "repository.htm")
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,12 @@ import (
|
|||||||
"github.com/astaxie/beego"
|
"github.com/astaxie/beego"
|
||||||
_ "github.com/astaxie/beego/session/redis"
|
_ "github.com/astaxie/beego/session/redis"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
|
"github.com/vmware/harbor/src/common/models"
|
||||||
"github.com/vmware/harbor/src/ui/api"
|
"github.com/vmware/harbor/src/ui/api"
|
||||||
_ "github.com/vmware/harbor/src/ui/auth/db"
|
_ "github.com/vmware/harbor/src/ui/auth/db"
|
||||||
_ "github.com/vmware/harbor/src/ui/auth/ldap"
|
_ "github.com/vmware/harbor/src/ui/auth/ldap"
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
"github.com/vmware/harbor/src/common/models"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -76,7 +77,7 @@ func main() {
|
|||||||
|
|
||||||
dao.InitDatabase()
|
dao.InitDatabase()
|
||||||
|
|
||||||
if err := updateInitPassword(adminUserID, os.Getenv("HARBOR_ADMIN_PASSWORD")); err != nil {
|
if err := updateInitPassword(adminUserID, config.InitialAdminPassword()); err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
}
|
}
|
||||||
initRouters()
|
initRouters()
|
||||||
|
@ -21,13 +21,12 @@ import (
|
|||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/dao"
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
|
||||||
"github.com/docker/distribution/registry/auth/token"
|
"github.com/docker/distribution/registry/auth/token"
|
||||||
"github.com/docker/libtrust"
|
"github.com/docker/libtrust"
|
||||||
@ -38,27 +37,10 @@ const (
|
|||||||
privateKey = "/etc/ui/private_key.pem"
|
privateKey = "/etc/ui/private_key.pem"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var expiration int //minutes
|
||||||
expiration = 30 //minutes
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// TODO read it from config
|
expiration = config.TokenExpiration()
|
||||||
expi := os.Getenv("TOKEN_EXPIRATION")
|
|
||||||
if len(expi) != 0 {
|
|
||||||
i, err := strconv.Atoi(expi)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("failed to parse token expiration: %v, using default value: %d minutes", err, expiration)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if i <= 0 {
|
|
||||||
log.Warningf("invalid token expiration, using default value: %d minutes", expiration)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
expiration = i
|
|
||||||
}
|
|
||||||
log.Infof("token expiration: %d minutes", expiration)
|
log.Infof("token expiration: %d minutes", expiration)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +91,7 @@ func FilterAccess(username string, a *token.ResourceActions) {
|
|||||||
repoLength := len(repoSplit)
|
repoLength := len(repoSplit)
|
||||||
if repoLength > 1 { //Only check the permission when the requested image has a namespace, i.e. project
|
if repoLength > 1 { //Only check the permission when the requested image has a namespace, i.e. project
|
||||||
var projectName string
|
var projectName string
|
||||||
registryURL := os.Getenv("HARBOR_REG_URL")
|
registryURL := config.ExtRegistryURL()
|
||||||
if repoSplit[0] == registryURL {
|
if repoSplit[0] == registryURL {
|
||||||
projectName = repoSplit[1]
|
projectName = repoSplit[1]
|
||||||
log.Infof("Detected Registry URL in Project Name. Assuming this is a notary request and setting Project Name as %s\n", projectName)
|
log.Infof("Detected Registry URL in Project Name. Assuming this is a notary request and setting Project Name as %s\n", projectName)
|
||||||
|
@ -18,14 +18,14 @@ package utils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/vmware/harbor/src/common/utils/log"
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VerifySecret verifies the UI_SECRET cookie in a http request.
|
// VerifySecret verifies the UI_SECRET cookie in a http request.
|
||||||
func VerifySecret(r *http.Request) bool {
|
func VerifySecret(r *http.Request) bool {
|
||||||
secret := os.Getenv("UI_SECRET")
|
secret := config.UISecret()
|
||||||
c, err := r.Cookie("uisecret")
|
c, err := r.Cookie("uisecret")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningf("Failed to get secret cookie, error: %v", err)
|
log.Warningf("Failed to get secret cookie, error: %v", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user