@@ -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"
|
||||
@@ -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,
|
||||
@@ -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) {
|
||||
30
pkg/api/auth/token/user.go
Normal file
30
pkg/api/auth/token/user.go
Normal 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
48
pkg/api/auth/types.go
Normal 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
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package token
|
||||
|
||||
type User interface {
|
||||
// Name
|
||||
GetName() string
|
||||
|
||||
// UID
|
||||
GetUID() string
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
Reference in New Issue
Block a user