Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
水淹萌龙
kubesphere
提交
abf0d66b
K
kubesphere
项目概览
水淹萌龙
/
kubesphere
与 Fork 源项目一致
Fork自
KubeSphere / kubesphere
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kubesphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
未验证
提交
abf0d66b
编写于
3月 15, 2020
作者:
Z
zryfish
提交者:
GitHub
3月 15, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add more tests (#1949)
* add more test code * add more test code
上级
f8e7d06b
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
444 addition
and
55 deletion
+444
-55
cmd/ks-apiserver/app/options/options.go
cmd/ks-apiserver/app/options/options.go
+36
-14
pkg/apiserver/authentication/token_authenticator.go
pkg/apiserver/authentication/token_authenticator.go
+12
-5
pkg/apiserver/config/config.go
pkg/apiserver/config/config.go
+1
-0
pkg/apiserver/dispatch/dispatch.go
pkg/apiserver/dispatch/dispatch.go
+1
-1
pkg/apiserver/filters/authentication.go
pkg/apiserver/filters/authentication.go
+1
-0
pkg/informers/informers.go
pkg/informers/informers.go
+4
-1
pkg/simple/client/cache/cache.go
pkg/simple/client/cache/cache.go
+2
-0
pkg/simple/client/cache/simple_cache.go
pkg/simple/client/cache/simple_cache.go
+88
-17
pkg/simple/client/cache/simple_cache_test.go
pkg/simple/client/cache/simple_cache_test.go
+123
-0
pkg/simple/client/ldap/interface.go
pkg/simple/client/ldap/interface.go
+21
-0
pkg/simple/client/ldap/ldap.go
pkg/simple/client/ldap/ldap.go
+0
-17
pkg/simple/client/ldap/simple_ldap.go
pkg/simple/client/ldap/simple_ldap.go
+57
-0
pkg/simple/client/ldap/simple_ldap_test.go
pkg/simple/client/ldap/simple_ldap_test.go
+98
-0
未找到文件。
cmd/ks-apiserver/app/options/options.go
浏览文件 @
abf0d66b
...
...
@@ -19,6 +19,7 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
fakeS3
"kubesphere.io/kubesphere/pkg/simple/client/s3/fake"
"kubesphere.io/kubesphere/pkg/simple/client/servicemesh"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"net/http"
...
...
@@ -40,6 +41,9 @@ type ServerRunOptions struct {
LdapOptions
*
ldap
.
Options
CacheOptions
*
cache
.
Options
AuthenticateOptions
*
iam
.
AuthenticationOptions
//
DebugMode
bool
}
func
NewServerRunOptions
()
*
ServerRunOptions
{
...
...
@@ -64,7 +68,9 @@ func NewServerRunOptions() *ServerRunOptions {
}
func
(
s
*
ServerRunOptions
)
Flags
()
(
fss
cliflag
.
NamedFlagSets
)
{
s
.
GenericServerRunOptions
.
AddFlags
(
fss
.
FlagSet
(
"generic"
),
s
.
GenericServerRunOptions
)
fs
:=
fss
.
FlagSet
(
"generic"
)
fs
.
BoolVar
(
&
s
.
DebugMode
,
"debug"
,
false
,
"Don't enable this if you don't know what it means."
)
s
.
GenericServerRunOptions
.
AddFlags
(
fs
,
s
.
GenericServerRunOptions
)
s
.
KubernetesOptions
.
AddFlags
(
fss
.
FlagSet
(
"kubernetes"
),
s
.
KubernetesOptions
)
s
.
AuthenticateOptions
.
AddFlags
(
fss
.
FlagSet
(
"authenticate"
),
s
.
AuthenticateOptions
)
s
.
MySQLOptions
.
AddFlags
(
fss
.
FlagSet
(
"mysql"
),
s
.
MySQLOptions
)
...
...
@@ -78,7 +84,7 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
s
.
MonitoringOptions
.
AddFlags
(
fss
.
FlagSet
(
"monitoring"
),
s
.
MonitoringOptions
)
s
.
LoggingOptions
.
AddFlags
(
fss
.
FlagSet
(
"logging"
),
s
.
LoggingOptions
)
fs
:
=
fss
.
FlagSet
(
"klog"
)
fs
=
fss
.
FlagSet
(
"klog"
)
local
:=
flag
.
NewFlagSet
(
"klog"
,
flag
.
ExitOnError
)
klog
.
InitFlags
(
local
)
local
.
VisitAll
(
func
(
fl
*
flag
.
Flag
)
{
...
...
@@ -89,6 +95,9 @@ func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
return
fss
}
const
fakeInterface
string
=
"FAKE"
// NewAPIServer creates an APIServer instance using given options
func
(
s
*
ServerRunOptions
)
NewAPIServer
(
stopCh
<-
chan
struct
{})
(
*
apiserver
.
APIServer
,
error
)
{
apiServer
:=
&
apiserver
.
APIServer
{}
...
...
@@ -113,11 +122,15 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
}
if
s
.
S3Options
.
Endpoint
!=
""
{
s3Client
,
err
:=
s3
.
NewS3Client
(
s
.
S3Options
)
if
err
!=
nil
{
return
nil
,
err
if
s
.
S3Options
.
Endpoint
==
fakeInterface
&&
s
.
DebugMode
{
apiServer
.
S3Client
=
fakeS3
.
NewFakeS3
()
}
else
{
s3Client
,
err
:=
s3
.
NewS3Client
(
s
.
S3Options
)
if
err
!=
nil
{
return
nil
,
err
}
apiServer
.
S3Client
=
s3Client
}
apiServer
.
S3Client
=
s3Client
}
if
s
.
DevopsOptions
.
Host
!=
""
{
...
...
@@ -129,19 +142,28 @@ func (s *ServerRunOptions) NewAPIServer(stopCh <-chan struct{}) (*apiserver.APIS
}
if
s
.
LdapOptions
.
Host
!=
""
{
ldapClient
,
err
:=
ldap
.
NewLdapClient
(
s
.
LdapOptions
,
stopCh
)
if
err
!=
nil
{
return
nil
,
err
if
s
.
LdapOptions
.
Host
==
fakeInterface
&&
s
.
DebugMode
{
apiServer
.
LdapClient
=
ldap
.
NewSimpleLdap
()
}
else
{
ldapClient
,
err
:=
ldap
.
NewLdapClient
(
s
.
LdapOptions
,
stopCh
)
if
err
!=
nil
{
return
nil
,
err
}
apiServer
.
LdapClient
=
ldapClient
}
apiServer
.
LdapClient
=
ldapClient
}
var
cacheClient
cache
.
Interface
if
s
.
CacheOptions
.
RedisURL
!=
""
{
cacheClient
,
err
:=
cache
.
NewRedisClient
(
s
.
CacheOptions
,
stopCh
)
if
err
!=
nil
{
return
nil
,
err
if
s
.
CacheOptions
.
RedisURL
==
fakeInterface
&&
s
.
DebugMode
{
apiServer
.
CacheClient
=
cache
.
NewSimpleCache
()
}
else
{
cacheClient
,
err
=
cache
.
NewRedisClient
(
s
.
CacheOptions
,
stopCh
)
if
err
!=
nil
{
return
nil
,
err
}
apiServer
.
CacheClient
=
cacheClient
}
apiServer
.
CacheClient
=
cacheClient
}
if
s
.
MySQLOptions
.
Host
!=
""
{
...
...
pkg/apiserver/authentication/token_authenticator.go
浏览文件 @
abf0d66b
...
...
@@ -7,23 +7,30 @@ import (
"kubesphere.io/kubesphere/pkg/simple/client/cache"
)
type
TokenAuthenticator
struct
{
// TokenAuthenticator implements kubernetes token authenticate interface with our custom logic.
// TokenAuthenticator will retrieve user info from cache by given token. If empty or invalid token
// was given, authenticator will still give passed response at the condition user will be user.Anonymous
// and group from user.AllUnauthenticated. This helps requests be passed along the handler chain,
// because some resources are public accessible.
type
tokenAuthenticator
struct
{
cacheClient
cache
.
Interface
}
func
NewTokenAuthenticator
(
cacheClient
cache
.
Interface
)
authenticator
.
Token
{
return
&
T
okenAuthenticator
{
return
&
t
okenAuthenticator
{
cacheClient
:
cacheClient
,
}
}
func
(
t
*
TokenAuthenticator
)
AuthenticateToken
(
ctx
context
.
Context
,
token
string
)
(
*
authenticator
.
Response
,
bool
,
error
)
{
func
(
t
*
tokenAuthenticator
)
AuthenticateToken
(
ctx
context
.
Context
,
token
string
)
(
*
authenticator
.
Response
,
bool
,
error
)
{
//if len(token) == 0 {
return
&
authenticator
.
Response
{
User
:
&
user
.
DefaultInfo
{
Name
:
"admin"
,
Name
:
user
.
Anonymous
,
UID
:
""
,
Groups
:
nil
,
Groups
:
[]
string
{
user
.
AllUnauthenticated
}
,
Extra
:
nil
,
},
},
true
,
nil
//}
}
pkg/apiserver/config/config.go
浏览文件 @
abf0d66b
...
...
@@ -188,6 +188,7 @@ func (conf *Config) toMap() map[string]bool {
return
result
}
// Remove invalid options before serializing to json or yaml
func
(
conf
*
Config
)
stripEmptyOptions
()
{
if
conf
.
MySQLOptions
!=
nil
&&
conf
.
MySQLOptions
.
Host
==
""
{
conf
.
MySQLOptions
=
nil
...
...
pkg/apiserver/dispatch/dispatch.go
浏览文件 @
abf0d66b
...
...
@@ -7,7 +7,7 @@ import (
"k8s.io/apimachinery/pkg/util/proxy"
)
// Dispatcher defines how to forward request to desi
red cluster apiserver
// Dispatcher defines how to forward request to desi
gnated cluster based on cluster name
type
Dispatcher
interface
{
Dispatch
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
}
...
...
pkg/apiserver/filters/authentication.go
浏览文件 @
abf0d66b
...
...
@@ -7,6 +7,7 @@ import (
"net/http"
)
// WithAuthentication installs authentication handler to handler chain.
func
WithAuthentication
(
handler
http
.
Handler
,
auth
authenticator
.
Request
,
failed
http
.
Handler
)
http
.
Handler
{
if
auth
==
nil
{
klog
.
Warningf
(
"Authentication is disabled"
)
...
...
pkg/informers/informers.go
浏览文件 @
abf0d66b
...
...
@@ -29,15 +29,18 @@ import (
"time"
)
// default re-sync period for all informer factories
const
defaultResync
=
600
*
time
.
Second
// InformerFactory is a group all shared informer factories which kubesphere needed
// callers should check if the return value is nil
type
InformerFactory
interface
{
KubernetesSharedInformerFactory
()
k8sinformers
.
SharedInformerFactory
KubeSphereSharedInformerFactory
()
ksinformers
.
SharedInformerFactory
IstioSharedInformerFactory
()
istioinformers
.
SharedInformerFactory
ApplicationSharedInformerFactory
()
applicationinformers
.
SharedInformerFactory
// Start
all the informer factories if
not nil
// Start
shared informer factory one by one if they are
not nil
Start
(
stopCh
<-
chan
struct
{})
}
...
...
pkg/simple/client/cache/cache.go
浏览文件 @
abf0d66b
...
...
@@ -2,6 +2,8 @@ package cache
import
"time"
var
NeverExpire
=
time
.
Duration
(
0
)
type
Interface
interface
{
// Keys retrieves all keys match the given pattern
Keys
(
pattern
string
)
([]
string
,
error
)
...
...
pkg/simple/client/cache/simple_cache.go
浏览文件 @
abf0d66b
package
cache
import
"time"
import
(
"kubesphere.io/kubesphere/pkg/server/errors"
"regexp"
"strings"
"time"
)
var
ErrNoSuchKey
=
errors
.
New
(
"no such key"
)
type
simpleObject
struct
{
value
string
expire
time
.
Time
value
string
neverExpire
bool
expiredAt
time
.
Time
}
type
SimpleCache
struct
{
// SimpleCache implements cache.Interface use memory objects, it should be used only for testing
type
simpleCache
struct
{
store
map
[
string
]
simpleObject
}
func
NewSimpleCache
()
Interface
{
return
&
S
impleCache
{
store
:
make
(
map
[
string
]
simpleObject
)}
return
&
s
impleCache
{
store
:
make
(
map
[
string
]
simpleObject
)}
}
func
(
s
*
SimpleCache
)
Keys
(
pattern
string
)
([]
string
,
error
)
{
panic
(
"implement me"
)
func
(
s
*
simpleCache
)
Keys
(
pattern
string
)
([]
string
,
error
)
{
// There is a little difference between go regexp and redis key pattern
// In redis, * means any character, while in go . means match everything.
pattern
=
strings
.
Replace
(
pattern
,
"*"
,
"."
,
-
1
)
re
,
err
:=
regexp
.
Compile
(
pattern
)
if
err
!=
nil
{
return
nil
,
err
}
var
keys
[]
string
for
k
,
_
:=
range
s
.
store
{
if
re
.
MatchString
(
k
)
{
keys
=
append
(
keys
,
k
)
}
}
return
keys
,
nil
}
func
(
s
*
SimpleCache
)
Set
(
key
string
,
value
string
,
duration
time
.
Duration
)
error
{
panic
(
"implement me"
)
func
(
s
*
simpleCache
)
Set
(
key
string
,
value
string
,
duration
time
.
Duration
)
error
{
sobject
:=
simpleObject
{
value
:
value
,
neverExpire
:
false
,
expiredAt
:
time
.
Now
()
.
Add
(
duration
),
}
if
duration
==
NeverExpire
{
sobject
.
neverExpire
=
true
}
s
.
store
[
key
]
=
sobject
return
nil
}
func
(
s
*
SimpleCache
)
Del
(
keys
...
string
)
error
{
panic
(
"implement me"
)
func
(
s
*
simpleCache
)
Del
(
keys
...
string
)
error
{
for
_
,
key
:=
range
keys
{
if
_
,
ok
:=
s
.
store
[
key
];
ok
{
delete
(
s
.
store
,
key
)
}
else
{
return
ErrNoSuchKey
}
}
return
nil
}
func
(
s
*
SimpleCache
)
Get
(
key
string
)
(
string
,
error
)
{
return
""
,
nil
func
(
s
*
simpleCache
)
Get
(
key
string
)
(
string
,
error
)
{
if
sobject
,
ok
:=
s
.
store
[
key
];
ok
{
if
sobject
.
neverExpire
||
time
.
Now
()
.
Before
(
sobject
.
expiredAt
)
{
return
sobject
.
value
,
nil
}
}
return
""
,
ErrNoSuchKey
}
func
(
s
*
SimpleCache
)
Exists
(
keys
...
string
)
(
bool
,
error
)
{
panic
(
"implement me"
)
func
(
s
*
simpleCache
)
Exists
(
keys
...
string
)
(
bool
,
error
)
{
for
_
,
key
:=
range
keys
{
if
_
,
ok
:=
s
.
store
[
key
];
!
ok
{
return
false
,
ErrNoSuchKey
}
}
return
true
,
nil
}
func
(
s
*
SimpleCache
)
Expire
(
key
string
,
duration
time
.
Duration
)
error
{
panic
(
"implement me"
)
func
(
s
*
simpleCache
)
Expire
(
key
string
,
duration
time
.
Duration
)
error
{
value
,
err
:=
s
.
Get
(
key
)
if
err
!=
nil
{
return
err
}
sobject
:=
simpleObject
{
value
:
value
,
neverExpire
:
false
,
expiredAt
:
time
.
Now
()
.
Add
(
duration
),
}
if
duration
==
NeverExpire
{
sobject
.
neverExpire
=
true
}
s
.
store
[
key
]
=
sobject
return
nil
}
pkg/simple/client/cache/simple_cache_test.go
0 → 100644
浏览文件 @
abf0d66b
package
cache
import
(
"github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/util/sets"
"testing"
"time"
)
var
dataSet
=
map
[
string
]
string
{
"foo1"
:
"val1"
,
"foo2"
:
"val2"
,
"foo3"
:
"val3"
,
"bar1"
:
"val1"
,
"bar2"
:
"val2"
,
}
// load dataset into cache
func
load
(
client
Interface
,
data
map
[
string
]
string
)
error
{
for
k
,
v
:=
range
data
{
err
:=
client
.
Set
(
k
,
v
,
NeverExpire
)
if
err
!=
nil
{
return
err
}
}
return
nil
}
// dump retrieve all data in simple into a map
func
dump
(
client
Interface
)
(
map
[
string
]
string
,
error
)
{
keys
,
err
:=
client
.
Keys
(
"*"
)
if
err
!=
nil
{
return
nil
,
err
}
snapshot
:=
make
(
map
[
string
]
string
)
for
_
,
key
:=
range
keys
{
val
,
err
:=
client
.
Get
(
key
)
if
err
!=
nil
{
continue
}
snapshot
[
key
]
=
val
}
return
snapshot
,
nil
}
func
TestDeleteAndExpireCache
(
t
*
testing
.
T
)
{
var
testCases
=
[]
struct
{
description
string
deleteKeys
sets
.
String
expireKeys
sets
.
String
expireDuration
time
.
Duration
// never use a 0(NeverExpires) duration with expireKeys, recommend time.Millisecond * 500.
expected
map
[
string
]
string
}{
{
description
:
"Should get all keys"
,
expected
:
map
[
string
]
string
{
"foo1"
:
"val1"
,
"foo2"
:
"val2"
,
"foo3"
:
"val3"
,
"bar1"
:
"val1"
,
"bar2"
:
"val2"
,
},
},
{
description
:
"Test delete should get only keys start with foo"
,
expected
:
map
[
string
]
string
{
"foo1"
:
"val1"
,
"foo2"
:
"val2"
,
"foo3"
:
"val3"
,
},
deleteKeys
:
sets
.
NewString
(
"bar1"
,
"bar2"
),
},
{
description
:
"Should get only keys start with bar"
,
expected
:
map
[
string
]
string
{
"bar1"
:
"val1"
,
"bar2"
:
"val2"
,
},
expireDuration
:
time
.
Millisecond
*
500
,
expireKeys
:
sets
.
NewString
(
"foo1"
,
"foo2"
,
"foo3"
),
},
}
for
_
,
testCase
:=
range
testCases
{
cacheClient
:=
NewSimpleCache
()
t
.
Run
(
testCase
.
description
,
func
(
t
*
testing
.
T
)
{
err
:=
load
(
cacheClient
,
dataSet
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unable to load dataset, got error %v"
,
err
)
}
if
len
(
testCase
.
deleteKeys
)
!=
0
{
err
=
cacheClient
.
Del
(
testCase
.
deleteKeys
.
List
()
...
)
if
err
!=
nil
{
t
.
Fatalf
(
"Error delete keys, %v"
,
err
)
}
}
if
len
(
testCase
.
expireKeys
)
!=
0
&&
testCase
.
expireDuration
!=
0
{
for
_
,
key
:=
range
testCase
.
expireKeys
.
List
()
{
err
=
cacheClient
.
Expire
(
key
,
testCase
.
expireDuration
)
if
err
!=
nil
{
t
.
Fatalf
(
"Error expire keys, %v"
,
err
)
}
}
time
.
Sleep
(
testCase
.
expireDuration
)
}
got
,
err
:=
dump
(
cacheClient
)
if
err
!=
nil
{
t
.
Fatalf
(
"Error dump data, %v"
,
err
)
}
if
diff
:=
cmp
.
Diff
(
got
,
testCase
.
expected
);
len
(
diff
)
!=
0
{
t
.
Errorf
(
"%T differ (-got, +expected) %v"
,
testCase
.
expected
,
diff
)
}
})
}
}
pkg/simple/client/ldap/interface.go
0 → 100644
浏览文件 @
abf0d66b
package
ldap
import
"kubesphere.io/kubesphere/pkg/api/iam"
// Interface defines CRUD behaviors of manipulating users
type
Interface
interface
{
// Create create a new user in ldap
Create
(
user
*
iam
.
User
)
error
// Update updates a user information, return error if user not exists
Update
(
user
*
iam
.
User
)
error
// Delete deletes a user from ldap, return nil if user not exists
Delete
(
name
string
)
error
// Get gets a user by its username from ldap, return ErrUserNotExists if user not exists
Get
(
name
string
)
(
*
iam
.
User
,
error
)
// Verify checks if (name, password) is valid, return ErrInvalidCredentials if not
Verify
(
name
string
,
password
string
)
error
}
pkg/simple/client/ldap/ldap.go
浏览文件 @
abf0d66b
...
...
@@ -27,23 +27,6 @@ import (
"time"
)
type
Interface
interface
{
// Create create a new user in ldap
Create
(
user
*
iam
.
User
)
error
// Update updates a user information, return error if user not exists
Update
(
user
*
iam
.
User
)
error
// Delete deletes a user from ldap, return nil if user not exists
Delete
(
name
string
)
error
// Get gets a user by its username from ldap
Get
(
name
string
)
(
*
iam
.
User
,
error
)
//
Verify
(
name
string
,
password
string
)
error
}
const
(
ldapAttributeObjectClass
=
"objectClass"
ldapAttributeCommonName
=
"cn"
...
...
pkg/simple/client/ldap/simple_ldap.go
0 → 100644
浏览文件 @
abf0d66b
package
ldap
import
"kubesphere.io/kubesphere/pkg/api/iam"
// simpleLdap is a implementation of ldap.Interface, you should never use this in production env!
type
simpleLdap
struct
{
store
map
[
string
]
*
iam
.
User
}
func
NewSimpleLdap
()
Interface
{
return
&
simpleLdap
{
store
:
map
[
string
]
*
iam
.
User
{},
}
}
func
(
s
simpleLdap
)
Create
(
user
*
iam
.
User
)
error
{
s
.
store
[
user
.
Username
]
=
user
return
nil
}
func
(
s
simpleLdap
)
Update
(
user
*
iam
.
User
)
error
{
_
,
err
:=
s
.
Get
(
user
.
Username
)
if
err
!=
nil
{
return
err
}
s
.
store
[
user
.
Username
]
=
user
return
nil
}
func
(
s
simpleLdap
)
Delete
(
name
string
)
error
{
_
,
err
:=
s
.
Get
(
name
)
if
err
!=
nil
{
return
err
}
delete
(
s
.
store
,
name
)
return
nil
}
func
(
s
simpleLdap
)
Get
(
name
string
)
(
*
iam
.
User
,
error
)
{
if
user
,
ok
:=
s
.
store
[
name
];
!
ok
{
return
nil
,
ErrUserNotExists
}
else
{
return
user
,
nil
}
}
func
(
s
simpleLdap
)
Verify
(
name
string
,
password
string
)
error
{
if
user
,
err
:=
s
.
Get
(
name
);
err
!=
nil
{
return
err
}
else
{
if
user
.
Password
!=
password
{
return
ErrInvalidCredentials
}
}
return
nil
}
pkg/simple/client/ldap/simple_ldap_test.go
0 → 100644
浏览文件 @
abf0d66b
package
ldap
import
(
"github.com/google/go-cmp/cmp"
"kubesphere.io/kubesphere/pkg/api/iam"
"testing"
"time"
)
func
TestSimpleLdap
(
t
*
testing
.
T
)
{
ldapClient
:=
NewSimpleLdap
()
foo
:=
&
iam
.
User
{
Username
:
"jerry"
,
Email
:
"jerry@kubesphere.io"
,
Lang
:
"en"
,
Description
:
"Jerry is kind and gentle."
,
CreateTime
:
time
.
Now
(),
Groups
:
[]
string
{},
Password
:
"P@88w0rd"
,
}
t
.
Run
(
"should create user"
,
func
(
t
*
testing
.
T
)
{
err
:=
ldapClient
.
Create
(
foo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// check if user really created
user
,
err
:=
ldapClient
.
Get
(
foo
.
Username
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
diff
:=
cmp
.
Diff
(
user
,
foo
);
len
(
diff
)
!=
0
{
t
.
Fatalf
(
"%T differ (-got, +want): %s"
,
user
,
diff
)
}
_
=
ldapClient
.
Delete
(
foo
.
Username
)
})
t
.
Run
(
"should update user"
,
func
(
t
*
testing
.
T
)
{
err
:=
ldapClient
.
Create
(
foo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
foo
.
Description
=
"Jerry needs some drinks."
err
=
ldapClient
.
Update
(
foo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
// check if user really created
user
,
err
:=
ldapClient
.
Get
(
foo
.
Username
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
if
diff
:=
cmp
.
Diff
(
user
,
foo
);
len
(
diff
)
!=
0
{
t
.
Fatalf
(
"%T differ (-got, +want): %s"
,
user
,
diff
)
}
_
=
ldapClient
.
Delete
(
foo
.
Username
)
})
t
.
Run
(
"should delete user"
,
func
(
t
*
testing
.
T
)
{
err
:=
ldapClient
.
Create
(
foo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
ldapClient
.
Delete
(
foo
.
Username
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
_
,
err
=
ldapClient
.
Get
(
foo
.
Username
)
if
err
==
nil
||
err
!=
ErrUserNotExists
{
t
.
Fatalf
(
"expected ErrUserNotExists error, got %v"
,
err
)
}
})
t
.
Run
(
"should verify username and password"
,
func
(
t
*
testing
.
T
)
{
err
:=
ldapClient
.
Create
(
foo
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
err
=
ldapClient
.
Verify
(
foo
.
Username
,
foo
.
Password
)
if
err
!=
nil
{
t
.
Fatalf
(
"should pass but got an error %v"
,
err
)
}
err
=
ldapClient
.
Verify
(
foo
.
Username
,
"gibberish"
)
if
err
==
nil
||
err
!=
ErrInvalidCredentials
{
t
.
Fatalf
(
"expected error ErrInvalidCrenentials but got %v"
,
err
)
}
})
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录