Skip to content

Commit

Permalink
Merge 4603b79 into 2b1bfaf
Browse files Browse the repository at this point in the history
  • Loading branch information
u2takey committed May 5, 2017
2 parents 2b1bfaf + 4603b79 commit a84fdcc
Show file tree
Hide file tree
Showing 43 changed files with 4,809 additions and 1 deletion.
102 changes: 102 additions & 0 deletions src/ui/auth/keystone/keystone.go
@@ -0,0 +1,102 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package keystone

import (
"errors"
"fmt"
"strings"

"github.com/vmware/harbor/src/common/utils/log"

"github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/ui/auth"
"github.com/vmware/harbor/src/ui/config"

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
)

// Auth implements Authenticator interface to authenticate against keystone
type Auth struct{}

const metaChars = "&|!=~*<>()"

// Authenticate checks user's credential against keystone based on keystone URL
// if the check is successful a dummy record will be inserted into DB, such that this user can
// be associated to other entities in the system.
func (l *Auth) Authenticate(m models.AuthModel) (*models.User, error) {

p := m.Principal
for _, c := range metaChars {
if strings.ContainsRune(p, c) {
return nil, fmt.Errorf("the principal contains meta char: %q", c)
}
}
// get keystoneURL
keystoneURL := config.KeyStone().URL
if keystoneURL == "" {
return nil, errors.New("can not get any available KeyStone_URL")
}
log.Debug("keystoneURL:", keystoneURL)

// Authenticate with keystone
opts := gophercloud.AuthOptions{
IdentityEndpoint: keystoneURL,
Username: m.Principal,
Password: m.Password,
DomainName: config.KeyStone().DomainName,
}

_, err := openstack.AuthenticatedClient(opts)
if err != nil {
return nil, err
}

u := models.User{}
u.Username = m.Principal

exist, err := dao.UserExists(u, "username")
if err != nil {
return nil, err
}

if exist {
currentUser, err := dao.GetUser(u)
if err != nil {
return nil, err
}
u.UserID = currentUser.UserID
} else {
u.Realname = m.Principal
u.Password = "12345678AbC"
u.Comment = "registered from KeyStone."
if u.Email == "" {
u.Email = u.Username + "@placeholder.com"
}
userID, err := dao.Register(u)
if err != nil {
return nil, err
}
u.UserID = int(userID)
}
return &u, nil
}

func init() {
auth.Register("keystone_auth", &Auth{})
}
8 changes: 8 additions & 0 deletions src/ui/auth/keystone/keystone_test.go
@@ -0,0 +1,8 @@
package keystone

import (
"testing"
)

func TestMain(t *testing.T) {
}
26 changes: 25 additions & 1 deletion src/ui/config/config.go
Expand Up @@ -35,6 +35,12 @@ type LDAPSetting struct {
Scope string
}

// KeySetting wraps the setting of an LDAP server
type KeyStoneSetting struct {
URL string
DomainName string
}

type uiParser struct{}

// Parse parses the auth settings url settings and other configuration consumed by code under src/ui
Expand All @@ -52,6 +58,18 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
}
config["ldap"] = setting
}

if mode == "keystone_auth" {
setting := KeyStoneSetting{
URL: raw["KEYSTONE_URL"],
DomainName: raw["DOMAIN_NAME"],
}
if setting.DomainName == "" {
setting.DomainName = "default"
}
config["keystone"] = setting
}

config["auth_mode"] = mode
var tokenExpiration = 30 //minutes
if len(raw["TOKEN_EXPIRATION"]) > 0 {
Expand All @@ -64,6 +82,7 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
tokenExpiration = i
}
}

config["token_exp"] = tokenExpiration
config["admin_password"] = raw["HARBOR_ADMIN_PASSWORD"]
config["ext_reg_url"] = raw["EXT_REG_URL"]
Expand All @@ -83,7 +102,7 @@ func (up *uiParser) Parse(raw map[string]string, config map[string]interface{})
var uiConfig *commonConfig.Config

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_CREATION_RESTRICTION", "REGISTRY_URL", "JOB_SERVICE_URL"}
uiKeys := []string{"AUTH_MODE", "KEYSTONE_URL", "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{
Config: make(map[string]interface{}),
Loader: &commonConfig.EnvConfigLoader{Keys: uiKeys},
Expand All @@ -109,6 +128,11 @@ func LDAP() LDAPSetting {
return uiConfig.Config["ldap"].(LDAPSetting)
}

// KeyStone returns the setting of KeyStone server
func KeyStone() KeyStoneSetting {
return uiConfig.Config["keystone"].(KeyStoneSetting)
}

// TokenExpiration returns the token expiration time (in minute)
func TokenExpiration() int {
return uiConfig.Config["token_exp"].(int)
Expand Down
1 change: 1 addition & 0 deletions src/ui/main.go
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/ui/api"
_ "github.com/vmware/harbor/src/ui/auth/db"
_ "github.com/vmware/harbor/src/ui/auth/keystone"
_ "github.com/vmware/harbor/src/ui/auth/ldap"
"github.com/vmware/harbor/src/ui/config"
)
Expand Down
Empty file.
148 changes: 148 additions & 0 deletions src/vendor/github.com/gophercloud/gophercloud/FAQ.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit a84fdcc

Please sign in to comment.