Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
小 白蛋
Harbor
Commits
d13321f2
Unverified
Commit
d13321f2
authored
7 years ago
by
Daniel Jiang
Committed by
GitHub
7 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Support getting user info via token in UAA Client (#3686)
parent
30e536b1
No related merge requests found
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
src/common/utils/uaa/client.go
+39
-0
src/common/utils/uaa/client.go
src/common/utils/uaa/client_test.go
+25
-0
src/common/utils/uaa/client_test.go
src/common/utils/uaa/fake_client.go
+6
-1
src/common/utils/uaa/fake_client.go
src/common/utils/uaa/test/good-access-token.txt
+1
-0
src/common/utils/uaa/test/good-access-token.txt
src/common/utils/uaa/test/server.go
+28
-0
src/common/utils/uaa/test/server.go
src/common/utils/uaa/test/user-info.json
+11
-0
src/common/utils/uaa/test/user-info.json
src/ui/auth/uaa/uaa_test.go
+2
-2
src/ui/auth/uaa/uaa_test.go
with
112 additions
and
3 deletions
+112
-3
src/common/utils/uaa/client.go
+
39
-
0
View file @
d13321f2
...
...
@@ -18,6 +18,7 @@ import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
"io/ioutil"
"net/http"
"strings"
...
...
@@ -30,6 +31,8 @@ import (
type
Client
interface
{
//PasswordAuth accepts username and password, return a token if it's valid.
PasswordAuth
(
username
,
password
string
)
(
*
oauth2
.
Token
,
error
)
//GetUserInfoByToken send the token to OIDC endpoint to get user info, currently it's also used to validate the token.
GetUserInfo
(
token
string
)
(
*
UserInfo
,
error
)
}
// ClientConfig values to initialize UAA Client
...
...
@@ -42,10 +45,22 @@ type ClientConfig struct {
CARootPath
string
}
// UserInfo represent the JSON object of a userinfo response from UAA.
// As the response varies, this struct will contain only a subset of attributes
// that may be used in Harbor
type
UserInfo
struct
{
UserID
string
`json:"user_id"`
Sub
string
`json:"sub"`
UserName
string
`json:"user_name"`
Name
string
`json:"name"`
Email
string
`json:"email"`
}
// DefaultClient leverages oauth2 pacakge for oauth features
type
defaultClient
struct
{
httpClient
*
http
.
Client
oauth2Cfg
*
oauth2
.
Config
endpoint
string
//TODO: add public key, etc...
}
...
...
@@ -54,6 +69,29 @@ func (dc *defaultClient) PasswordAuth(username, password string) (*oauth2.Token,
return
dc
.
oauth2Cfg
.
PasswordCredentialsToken
(
ctx
,
username
,
password
)
}
func
(
dc
*
defaultClient
)
GetUserInfo
(
token
string
)
(
*
UserInfo
,
error
)
{
userInfoURL
:=
dc
.
endpoint
+
"/uaa/userinfo"
req
,
err
:=
http
.
NewRequest
(
http
.
MethodGet
,
userInfoURL
,
nil
)
if
err
!=
nil
{
return
nil
,
err
}
req
.
Header
.
Set
(
"Authorization"
,
"bearer "
+
token
)
resp
,
err
:=
dc
.
httpClient
.
Do
(
req
)
if
err
!=
nil
{
return
nil
,
err
}
defer
resp
.
Body
.
Close
()
data
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
if
err
!=
nil
{
return
nil
,
err
}
info
:=
&
UserInfo
{}
if
err
:=
json
.
Unmarshal
(
data
,
info
);
err
!=
nil
{
return
nil
,
err
}
return
info
,
nil
}
// NewDefaultClient creates an instance of defaultClient.
func
NewDefaultClient
(
cfg
*
ClientConfig
)
(
Client
,
error
)
{
url
:=
cfg
.
Endpoint
...
...
@@ -95,5 +133,6 @@ func NewDefaultClient(cfg *ClientConfig) (Client, error) {
return
&
defaultClient
{
httpClient
:
hc
,
oauth2Cfg
:
oc
,
endpoint
:
url
,
},
nil
}
This diff is collapsed.
Click to expand it.
src/common/utils/uaa/client_test.go
+
25
-
0
View file @
d13321f2
package
uaa
import
(
"fmt"
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/src/common/utils/uaa/test"
"io/ioutil"
"net/http/httptest"
"os"
"path"
"runtime"
"strings"
"testing"
)
...
...
@@ -43,6 +46,28 @@ func TestPasswordAuth(t *testing.T) {
assert
.
NotNil
(
err
)
}
func
TestUserInfo
(
t
*
testing
.
T
)
{
cfg
:=
&
ClientConfig
{
ClientID
:
"uaa"
,
ClientSecret
:
"secret"
,
Endpoint
:
mockUAAServer
.
URL
,
SkipTLSVerify
:
true
,
}
assert
:=
assert
.
New
(
t
)
client
,
err
:=
NewDefaultClient
(
cfg
)
assert
.
Nil
(
err
)
token
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
currPath
(),
"test"
,
"./good-access-token.txt"
))
if
err
!=
nil
{
panic
(
err
)
}
userInfo
,
err
:=
client
.
GetUserInfo
(
strings
.
TrimSpace
(
string
(
token
)))
assert
.
Nil
(
err
,
fmt
.
Sprintf
(
"%v"
,
err
))
assert
.
Equal
(
"user01"
,
userInfo
.
UserName
)
_
,
err2
:=
client
.
GetUserInfo
(
"bad"
)
assert
.
NotNil
(
err2
)
}
func
currPath
()
string
{
_
,
f
,
_
,
ok
:=
runtime
.
Caller
(
0
)
if
!
ok
{
...
...
This diff is collapsed.
Click to expand it.
src/common/utils/uaa/
test/
fake_client.go
→
src/common/utils/uaa/fake_client.go
+
6
-
1
View file @
d13321f2
...
...
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
package
test
package
uaa
import
(
"fmt"
...
...
@@ -32,3 +32,8 @@ func (fc *FakeClient) PasswordAuth(username, password string) (*oauth2.Token, er
}
return
nil
,
fmt
.
Errorf
(
"Invalide username and password"
)
}
// GetUserInfo ...
func
(
fc
*
FakeClient
)
GetUserInfo
(
token
string
)
(
*
UserInfo
,
error
)
{
return
nil
,
nil
}
This diff is collapsed.
Click to expand it.
src/common/utils/uaa/test/good-access-token.txt
0 → 100644
+
1
-
0
View file @
d13321f2
eyJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiIyNmRjYjg1YzMzZjU0OGM5ODk2YjI4MDEwN2IyOWM0NiIsInN1YiI6IjlhMTM0ODhmLWYzY2YtNDdhNi05OGYwLTRmZWQyMWY0MzUyMCIsInNjb3BlIjpbIm9wZW5pZCJdLCJjbGllbnRfaWQiOiJrdWJlcm5ldGVzIiwiY2lkIjoia3ViZXJuZXRlcyIsImF6cCI6Imt1YmVybmV0ZXMiLCJncmFudF90eXBlIjoicGFzc3dvcmQiLCJ1c2VyX2lkIjoiOWExMzQ4OGYtZjNjZi00N2E2LTk4ZjAtNGZlZDIxZjQzNTIwIiwib3JpZ2luIjoibGRhcCIsInVzZXJfbmFtZSI6InVzZXIwMSIsImVtYWlsIjoidXNlcjAxQHVzZXIuZnJvbS5sZGFwLmNmIiwiYXV0aF90aW1lIjoxNTExNDA1NDEwLCJyZXZfc2lnIjoiOGEwYmY5OWQiLCJpYXQiOjE1MTE0MDU0MTAsImV4cCI6MTUxMTQ0ODYxMCwiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6ODQ0My91YWEvb2F1dGgvdG9rZW4iLCJ6aWQiOiJ1YWEiLCJhdWQiOlsia3ViZXJuZXRlcyIsIm9wZW5pZCJdfQ.I7VBx_cQoYkotRJ8KdmESAf_xjzp-R44BRz9ngHPUnoqr4rSMin-Ful8wNzEnaYaG56_mrIPuLOb6vXGWW1svRU892GOK9WQRSiFp7O81V7f1bH6JXnIGvyBNl3JOkDB9d5wXn137h9vNKq3Z9TF3jD7oXR_OENS8paclW5EAjmjGvEVIhObMmHCLhsJshTWIoP8AwoP1m9iqak_-t0c99HWaf1AgVUtT2i9Jb63ndJGA6BkOSRH_YxXmM_qtXmk_0kRA5oLDR2UGA4TVXCYp1_8iwQYjvGBVxO24I5jJh_zDYs5YLTFeNzMTPEhAl_Te6NiE91gRXq6KiVk9tTfuA
This diff is collapsed.
Click to expand it.
src/common/utils/uaa/test/server.go
+
28
-
0
View file @
d13321f2
...
...
@@ -21,6 +21,7 @@ import (
"net/http/httptest"
"path"
"runtime"
"strings"
)
// MockServerConfig ...
...
...
@@ -72,6 +73,28 @@ func (t *tokenHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
}
}
type
userInfoHandler
struct
{
token
string
}
func
(
u
*
userInfoHandler
)
ServeHTTP
(
rw
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
v
:=
req
.
Header
.
Get
(
"Authorization"
)
prefix
:=
v
[
0
:
7
]
reqToken
:=
v
[
7
:
]
if
strings
.
ToLower
(
prefix
)
!=
"bearer "
||
reqToken
!=
u
.
token
{
http
.
Error
(
rw
,
"invalid token"
,
http
.
StatusUnauthorized
)
return
}
userInfo
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
currPath
(),
"./user-info.json"
))
if
err
!=
nil
{
panic
(
err
)
}
_
,
err2
:=
rw
.
Write
(
userInfo
)
if
err2
!=
nil
{
panic
(
err2
)
}
}
// NewMockServer ...
func
NewMockServer
(
cfg
*
MockServerConfig
)
*
httptest
.
Server
{
mux
:=
http
.
NewServeMux
()
...
...
@@ -81,5 +104,10 @@ func NewMockServer(cfg *MockServerConfig) *httptest.Server {
cfg
.
Username
,
cfg
.
Password
,
})
token
,
err
:=
ioutil
.
ReadFile
(
path
.
Join
(
currPath
(),
"./good-access-token.txt"
))
if
err
!=
nil
{
panic
(
err
)
}
mux
.
Handle
(
"/uaa/userinfo"
,
&
userInfoHandler
{
strings
.
TrimSpace
(
string
(
token
))})
return
httptest
.
NewTLSServer
(
mux
)
}
This diff is collapsed.
Click to expand it.
src/common/utils/uaa/test/user-info.json
0 → 100644
+
11
-
0
View file @
d13321f2
{
"user_id"
:
"9a13488f-f3cf-47a6-98f0-4fed21f43520"
,
"sub"
:
"9a13488f-f3cf-47a6-98f0-4fed21f43520"
,
"user_name"
:
"user01"
,
"given_name"
:
null
,
"family_name"
:
null
,
"email"
:
"user01@user.from.ldap.cf"
,
"phone_number"
:
null
,
"previous_logon_time"
:
1511247236160
,
"name"
:
""
}
This diff is collapsed.
Click to expand it.
src/ui/auth/uaa/uaa_test.go
+
2
-
2
View file @
d13321f2
...
...
@@ -18,7 +18,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/vmware/harbor/src/common/dao"
utilstest
"github.com/vmware/harbor/src/common/utils/test"
uaatest
"github.com/vmware/harbor/src/common/utils/uaa
/test
"
"github.com/vmware/harbor/src/common/utils/uaa"
"github.com/vmware/harbor/src/ui/config"
"os"
...
...
@@ -47,7 +47,7 @@ func TestGetClient(t *testing.T) {
func
TestDoAuth
(
t
*
testing
.
T
)
{
assert
:=
assert
.
New
(
t
)
client
:=
&
uaa
test
.
FakeClient
{
client
:=
&
uaa
.
FakeClient
{
Username
:
"user1"
,
Password
:
"password1"
,
}
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help