Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2020-03-22 04:29:06 +08:00
parent aadb5e91e8
commit b9bdcd824c
19 changed files with 284 additions and 347 deletions

View File

@@ -1,4 +1,22 @@
package iam
/*
*
* Copyright 2020 The KubeSphere Authors.
*
* 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 auth
import (
"fmt"

View File

@@ -3,7 +3,6 @@ package token
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"kubesphere.io/kubesphere/pkg/api/iam"
"kubesphere.io/kubesphere/pkg/server/errors"
"time"
)
@@ -13,8 +12,9 @@ const DefaultIssuerName = "kubesphere"
var errInvalidToken = errors.New("invalid token")
type claims struct {
Username string `json:"username"`
UID string `json:"uid"`
Username string `json:"username"`
UID string `json:"uid"`
Groups []string `json:"groups"`
// Currently, we are not using any field in jwt.StandardClaims
jwt.StandardClaims
}
@@ -37,13 +37,14 @@ func (s *jwtTokenIssuer) Verify(tokenString string) (User, error) {
return nil, err
}
return &iam.User{Username: clm.Username, UID: clm.UID}, nil
return &AuthUser{Name: clm.Username, UID: clm.UID, Groups: clm.Groups}, nil
}
func (s *jwtTokenIssuer) IssueTo(user User) (string, error) {
clm := &claims{
Username: user.GetName(),
UID: user.GetUID(),
Groups: user.GetGroups(),
StandardClaims: jwt.StandardClaims{
IssuedAt: time.Now().Unix(),
Issuer: s.name,

View File

@@ -2,7 +2,6 @@ package token
import (
"github.com/google/go-cmp/cmp"
"kubesphere.io/kubesphere/pkg/api/iam"
"testing"
)
@@ -25,9 +24,9 @@ func TestJwtTokenIssuer(t *testing.T) {
}
for _, testCase := range testCases {
user := &iam.User{
Username: testCase.name,
UID: testCase.uid,
user := &AuthUser{
Name: testCase.name,
UID: testCase.uid,
}
t.Run(testCase.description, func(t *testing.T) {

View File

@@ -0,0 +1,30 @@
package token
type User interface {
// Name
GetName() string
// UID
GetUID() string
// Groups
GetGroups() []string
}
type AuthUser struct {
Name string
UID string
Groups []string
}
func (a AuthUser) GetName() string {
return a.Name
}
func (a AuthUser) GetUID() string {
return a.UID
}
func (a AuthUser) GetGroups() []string {
return a.Groups
}

48
pkg/api/auth/types.go Normal file
View File

@@ -0,0 +1,48 @@
/*
*
* Copyright 2020 The KubeSphere Authors.
*
* 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 auth
import "fmt"
const (
KindTokenReview = "TokenReview"
)
type Spec struct {
Token string `json:"token" description:"access token"`
}
type Status struct {
Authenticated bool `json:"authenticated" description:"is authenticated"`
User map[string]interface{} `json:"user,omitempty" description:"user info"`
}
type TokenReview struct {
APIVersion string `json:"apiVersion" description:"Kubernetes API version"`
Kind string `json:"kind" description:"kind of the API object"`
Spec *Spec `json:"spec,omitempty"`
Status *Status `json:"status,omitempty" description:"token review status"`
}
func (request *TokenReview) Validate() error {
if request.Spec == nil || request.Spec.Token == "" {
return fmt.Errorf("token must not be null")
}
return nil
}

View File

@@ -1,9 +0,0 @@
package token
type User interface {
// Name
GetName() string
// UID
GetUID() string
}

View File

@@ -16,25 +16,16 @@ type User struct {
Password string `json:"password,omitempty"`
}
func NewUser() *User {
return &User{
Username: "",
UID: "",
Email: "",
Lang: "",
Description: "",
CreateTime: time.Time{},
Groups: nil,
Password: "",
}
}
func (u *User) GetName() string {
return u.Username
}
func (u *User) GetUID() string {
return ""
return u.UID
}
func (u *User) GetGroups() []string {
return u.Groups
}
func (u *User) Validate() error {

View File

@@ -1,110 +0,0 @@
/*
*
* Copyright 2020 The KubeSphere Authors.
*
* 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 v1alpha2
import (
"fmt"
"kubesphere.io/kubesphere/pkg/api/iam"
"net/mail"
)
const minPasswordLength = 6
type Spec struct {
Token string `json:"token" description:"access token"`
}
type Status struct {
Authenticated bool `json:"authenticated" description:"is authenticated"`
User map[string]interface{} `json:"user,omitempty" description:"user info"`
}
type TokenReview struct {
APIVersion string `json:"apiVersion" description:"Kubernetes API version"`
Kind string `json:"kind" description:"kind of the API object"`
Spec *Spec `json:"spec,omitempty"`
Status *Status `json:"status,omitempty" description:"token review status"`
}
type LoginRequest struct {
Username string `json:"username" description:"username"`
Password string `json:"password" description:"password"`
}
type UserDetail struct {
*iam.User
ClusterRole string `json:"cluster_role"`
}
type CreateUserRequest struct {
*UserDetail
}
func (request *CreateUserRequest) Validate() error {
if request.Username == "" {
return fmt.Errorf("username must not be empty")
}
// Parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"
if _, err := mail.ParseAddress(request.Email); err != nil {
return fmt.Errorf("invalid email: %s", request.Email)
}
if len(request.Password) < minPasswordLength {
return fmt.Errorf("password must be at least %d characters long", minPasswordLength)
}
return nil
}
type ModifyUserRequest struct {
*UserDetail
CurrentPassword string `json:"current_password,omitempty" description:"this is necessary if you need to change your password"`
}
func (request *TokenReview) Validate() error {
if request.Spec == nil || request.Spec.Token == "" {
return fmt.Errorf("token must not be null")
}
return nil
}
func (request ModifyUserRequest) Validate() error {
// Parses a single RFC 5322 address, e.g. "Barry Gibbs <bg@example.com>"
if _, err := mail.ParseAddress(request.Email); err != nil {
return fmt.Errorf("invalid email: %s", request.Email)
}
if request.Password != "" {
if len(request.Password) < minPasswordLength {
return fmt.Errorf("password must be at least %d characters long", minPasswordLength)
}
if len(request.CurrentPassword) < minPasswordLength {
return fmt.Errorf("password must be at least %d characters long", minPasswordLength)
}
}
return nil
}
type ListUserResponse struct {
Items []*UserDetail `json:"items"`
TotalCount int `json:"total_count"`
}