mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-18 22:57:38 +01:00
Merge pull request #10329 from wy65701436/expir-robot
add expiration data time when to create a robot account
This commit is contained in:
commit
a5f8111fd0
@ -6239,6 +6239,9 @@ definitions:
|
|||||||
description:
|
description:
|
||||||
type: string
|
type: string
|
||||||
description: The description of robot account
|
description: The description of robot account
|
||||||
|
expires_at:
|
||||||
|
type: integer
|
||||||
|
description: The expiration time on or after which the JWT MUST NOT be accepted for processing.
|
||||||
access:
|
access:
|
||||||
type: array
|
type: array
|
||||||
description: The permission of robot account
|
description: The permission of robot account
|
||||||
|
@ -18,6 +18,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/goharbor/harbor/src/common/dao"
|
"github.com/goharbor/harbor/src/common/dao"
|
||||||
"github.com/goharbor/harbor/src/common/models"
|
"github.com/goharbor/harbor/src/common/models"
|
||||||
@ -40,6 +41,9 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
policies := []*rbac.Policy{}
|
policies := []*rbac.Policy{}
|
||||||
policies = append(policies, rbacPolicy)
|
policies = append(policies, rbacPolicy)
|
||||||
|
|
||||||
|
tokenDuration := time.Duration(30) * time.Minute
|
||||||
|
expiresAt := time.Now().UTC().Add(tokenDuration).Unix()
|
||||||
|
|
||||||
cases := []*codeCheckingCase{
|
cases := []*codeCheckingCase{
|
||||||
// 401
|
// 401
|
||||||
{
|
{
|
||||||
@ -68,6 +72,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Description: "test desc",
|
Description: "test desc",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
Access: policies,
|
Access: policies,
|
||||||
},
|
},
|
||||||
credential: projAdmin4Robot,
|
credential: projAdmin4Robot,
|
||||||
@ -82,6 +87,20 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "testIllgel#",
|
Name: "testIllgel#",
|
||||||
Description: "test desc",
|
Description: "test desc",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
|
},
|
||||||
|
credential: projAdmin4Robot,
|
||||||
|
},
|
||||||
|
code: http.StatusBadRequest,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
request: &testingRequest{
|
||||||
|
method: http.MethodPost,
|
||||||
|
url: robotPath,
|
||||||
|
bodyJSON: &model.RobotCreate{
|
||||||
|
Name: "test not set expiration",
|
||||||
|
Description: "test desc",
|
||||||
|
ExpiresAt: -100,
|
||||||
},
|
},
|
||||||
credential: projAdmin4Robot,
|
credential: projAdmin4Robot,
|
||||||
},
|
},
|
||||||
@ -94,6 +113,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Description: "resource not exist",
|
Description: "resource not exist",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
Access: []*rbac.Policy{
|
Access: []*rbac.Policy{
|
||||||
{Resource: res.Subresource("foo"), Action: rbac.ActionCreate},
|
{Resource: res.Subresource("foo"), Action: rbac.ActionCreate},
|
||||||
},
|
},
|
||||||
@ -109,6 +129,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Description: "action not exist",
|
Description: "action not exist",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
Access: []*rbac.Policy{
|
Access: []*rbac.Policy{
|
||||||
{Resource: res.Subresource(rbac.ResourceRepository), Action: "foo"},
|
{Resource: res.Subresource(rbac.ResourceRepository), Action: "foo"},
|
||||||
},
|
},
|
||||||
@ -124,6 +145,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Description: "policy not exit",
|
Description: "policy not exit",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
Access: []*rbac.Policy{
|
Access: []*rbac.Policy{
|
||||||
{Resource: res.Subresource(rbac.ResourceMember), Action: rbac.ActionPush},
|
{Resource: res.Subresource(rbac.ResourceMember), Action: rbac.ActionPush},
|
||||||
},
|
},
|
||||||
@ -140,6 +162,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test2",
|
Name: "test2",
|
||||||
Description: "test2 desc",
|
Description: "test2 desc",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
},
|
},
|
||||||
credential: projDeveloper,
|
credential: projDeveloper,
|
||||||
},
|
},
|
||||||
@ -154,6 +177,7 @@ func TestRobotAPIPost(t *testing.T) {
|
|||||||
bodyJSON: &model.RobotCreate{
|
bodyJSON: &model.RobotCreate{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Description: "test desc",
|
Description: "test desc",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
Access: policies,
|
Access: policies,
|
||||||
},
|
},
|
||||||
credential: projAdmin4Robot,
|
credential: projAdmin4Robot,
|
||||||
|
@ -58,17 +58,19 @@ func (d *DefaultAPIController) GetRobotAccount(id int64) (*model.Robot, error) {
|
|||||||
func (d *DefaultAPIController) CreateRobotAccount(robotReq *model.RobotCreate) (*model.Robot, error) {
|
func (d *DefaultAPIController) CreateRobotAccount(robotReq *model.RobotCreate) (*model.Robot, error) {
|
||||||
|
|
||||||
var deferDel error
|
var deferDel error
|
||||||
// Token duration in minutes
|
|
||||||
tokenDuration := time.Duration(config.RobotTokenDuration()) * time.Minute
|
|
||||||
expiresAt := time.Now().UTC().Add(tokenDuration).Unix()
|
|
||||||
createdName := common.RobotPrefix + robotReq.Name
|
createdName := common.RobotPrefix + robotReq.Name
|
||||||
|
|
||||||
|
if robotReq.ExpiresAt == 0 {
|
||||||
|
tokenDuration := time.Duration(config.RobotTokenDuration()) * time.Minute
|
||||||
|
robotReq.ExpiresAt = time.Now().UTC().Add(tokenDuration).Unix()
|
||||||
|
}
|
||||||
|
|
||||||
// first to add a robot account, and get its id.
|
// first to add a robot account, and get its id.
|
||||||
robot := &model.Robot{
|
robot := &model.Robot{
|
||||||
Name: createdName,
|
Name: createdName,
|
||||||
Description: robotReq.Description,
|
Description: robotReq.Description,
|
||||||
ProjectID: robotReq.ProjectID,
|
ProjectID: robotReq.ProjectID,
|
||||||
ExpiresAt: expiresAt,
|
ExpiresAt: robotReq.ExpiresAt,
|
||||||
Visible: robotReq.Visible,
|
Visible: robotReq.Visible,
|
||||||
}
|
}
|
||||||
id, err := d.manager.CreateRobotAccount(robot)
|
id, err := d.manager.CreateRobotAccount(robot)
|
||||||
@ -85,7 +87,7 @@ func (d *DefaultAPIController) CreateRobotAccount(robotReq *model.RobotCreate) (
|
|||||||
Access: robotReq.Access,
|
Access: robotReq.Access,
|
||||||
StandardClaims: jwt.StandardClaims{
|
StandardClaims: jwt.StandardClaims{
|
||||||
IssuedAt: time.Now().UTC().Unix(),
|
IssuedAt: time.Now().UTC().Unix(),
|
||||||
ExpiresAt: expiresAt,
|
ExpiresAt: robotReq.ExpiresAt,
|
||||||
Issuer: opt.Issuer,
|
Issuer: opt.Issuer,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ControllerTestSuite struct {
|
type ControllerTestSuite struct {
|
||||||
@ -47,9 +48,13 @@ func (s *ControllerTestSuite) TestRobotAccount() {
|
|||||||
policies := []*rbac.Policy{}
|
policies := []*rbac.Policy{}
|
||||||
policies = append(policies, rbacPolicy)
|
policies = append(policies, rbacPolicy)
|
||||||
|
|
||||||
|
tokenDuration := time.Duration(30) * time.Minute
|
||||||
|
expiresAt := time.Now().UTC().Add(tokenDuration).Unix()
|
||||||
|
|
||||||
robot1 := &model.RobotCreate{
|
robot1 := &model.RobotCreate{
|
||||||
Name: "robot1",
|
Name: "robot1",
|
||||||
Description: "TestCreateRobotAccount",
|
Description: "TestCreateRobotAccount",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
ProjectID: int64(1),
|
ProjectID: int64(1),
|
||||||
Access: policies,
|
Access: policies,
|
||||||
}
|
}
|
||||||
@ -74,6 +79,7 @@ func (s *ControllerTestSuite) TestRobotAccount() {
|
|||||||
robot2 := &model.RobotCreate{
|
robot2 := &model.RobotCreate{
|
||||||
Name: "robot2",
|
Name: "robot2",
|
||||||
Description: "TestCreateRobotAccount",
|
Description: "TestCreateRobotAccount",
|
||||||
|
ExpiresAt: expiresAt,
|
||||||
ProjectID: int64(1),
|
ProjectID: int64(1),
|
||||||
Access: policies,
|
Access: policies,
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ type RobotCreate struct {
|
|||||||
ProjectID int64 `json:"pid"`
|
ProjectID int64 `json:"pid"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Disabled bool `json:"disabled"`
|
Disabled bool `json:"disabled"`
|
||||||
|
ExpiresAt int64 `json:"expires_at"`
|
||||||
Visible bool `json:"-"`
|
Visible bool `json:"-"`
|
||||||
Access []*rbac.Policy `json:"access"`
|
Access []*rbac.Policy `json:"access"`
|
||||||
}
|
}
|
||||||
@ -67,6 +68,9 @@ func (rq *RobotCreate) Valid(v *validation.Validation) {
|
|||||||
if utils.IsContainIllegalChar(rq.Name, []string{",", "~", "#", "$", "%"}) {
|
if utils.IsContainIllegalChar(rq.Name, []string{",", "~", "#", "$", "%"}) {
|
||||||
v.SetError("name", "robot name contains illegal characters")
|
v.SetError("name", "robot name contains illegal characters")
|
||||||
}
|
}
|
||||||
|
if rq.ExpiresAt < 0 {
|
||||||
|
v.SetError("expires_at", "expiration time must be a positive integer if set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RobotRep ...
|
// RobotRep ...
|
||||||
|
@ -173,7 +173,7 @@ class Project(base.Base):
|
|||||||
base._assert_status_code(expect_status_code, status_code)
|
base._assert_status_code(expect_status_code, status_code)
|
||||||
return base._get_id_from_header(header)
|
return base._get_id_from_header(header)
|
||||||
|
|
||||||
def add_project_robot_account(self, project_id, project_name, robot_name = None, robot_desc = None, has_pull_right = True, has_push_right = True, expect_status_code = 201, **kwargs):
|
def add_project_robot_account(self, project_id, project_name, expires_at, robot_name = None, robot_desc = None, has_pull_right = True, has_push_right = True, expect_status_code = 201, **kwargs):
|
||||||
if robot_name is None:
|
if robot_name is None:
|
||||||
robot_name = base._random_name("robot")
|
robot_name = base._random_name("robot")
|
||||||
if robot_desc is None:
|
if robot_desc is None:
|
||||||
@ -190,7 +190,7 @@ class Project(base.Base):
|
|||||||
if has_push_right is True:
|
if has_push_right is True:
|
||||||
robotAccountAccess = swagger_client.RobotAccountAccess(resource = resource_by_project_id, action = action_push)
|
robotAccountAccess = swagger_client.RobotAccountAccess(resource = resource_by_project_id, action = action_push)
|
||||||
access_list.append(robotAccountAccess)
|
access_list.append(robotAccountAccess)
|
||||||
robotAccountCreate = swagger_client.RobotAccountCreate(robot_name, robot_desc, access_list)
|
robotAccountCreate = swagger_client.RobotAccountCreate(robot_name, robot_desc, expires_at, access_list)
|
||||||
client = self._get_client(**kwargs)
|
client = self._get_client(**kwargs)
|
||||||
data = []
|
data = []
|
||||||
data, status_code, header = client.projects_project_id_robots_post_with_http_info(project_id, robotAccountCreate)
|
data, status_code, header = client.projects_project_id_robots_post_with_http_info(project_id, robotAccountCreate)
|
||||||
|
@ -93,7 +93,8 @@ class TestProjects(unittest.TestCase):
|
|||||||
TestProjects.repo_name_in_project_c, tag_c = push_image_to_project(project_ra_name_c, harbor_server, user_ra_name, user_ra_password, image_project_c, tag)
|
TestProjects.repo_name_in_project_c, tag_c = push_image_to_project(project_ra_name_c, harbor_server, user_ra_name, user_ra_password, image_project_c, tag)
|
||||||
|
|
||||||
print "#4. Create a new robot account(RA) with pull and push privilige in project(PA) by user(UA);"
|
print "#4. Create a new robot account(RA) with pull and push privilige in project(PA) by user(UA);"
|
||||||
robot_id, robot_account = self.project.add_project_robot_account(TestProjects.project_ra_id_a, project_ra_name_a, **TestProjects.USER_RA_CLIENT)
|
robot_id, robot_account = self.project.add_project_robot_account(TestProjects.project_ra_id_a, project_ra_name_a,
|
||||||
|
2441000531 ,**TestProjects.USER_RA_CLIENT)
|
||||||
print robot_account.name
|
print robot_account.name
|
||||||
print robot_account.token
|
print robot_account.token
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user