Skip to content

Commit

Permalink
✨feat: Enhance support for /access (#125)
Browse files Browse the repository at this point in the history
* ✨feat: Add DeleteContent method for storage

* ✨feat: Add ConvertToTemplate method

* ✨feat: Enhance support for /access

* fix: Update variable naming and remove duplicates
  • Loading branch information
alperencelik authored Mar 5, 2024
1 parent 799beb9 commit a6a1921
Show file tree
Hide file tree
Showing 4 changed files with 283 additions and 0 deletions.
39 changes: 39 additions & 0 deletions access.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ func (c *Client) Users(ctx context.Context) (users Users, err error) {
return
}

func (c *Client) NewUser(ctx context.Context, user *NewUser) (err error) {
return c.Post(ctx, "/access/users", user, nil)
}

func (u *User) Update(ctx context.Context) error {
return u.client.Put(ctx, fmt.Sprintf("/access/users/%s", u.UserID), u, nil)
}
Expand All @@ -169,11 +173,46 @@ func (u *User) Delete(ctx context.Context) error {
return u.client.Delete(ctx, fmt.Sprintf("/access/users/%s", u.UserID), nil)
}

func (u *User) GetAPITokens(ctx context.Context) (tokens Tokens, err error) {
return tokens, u.client.Get(ctx, fmt.Sprintf("/access/users/%s/token", u.UserID), &tokens)
}

func (u *User) APIToken(ctx context.Context, tokenid string) (token Token, err error) {
return token, u.client.Get(ctx, fmt.Sprintf("/access/users/%s/token/%s", u.UserID, tokenid), &token)
}

func (u *User) NewAPIToken(ctx context.Context, token Token) (newtoken NewAPIToken, err error) {
return newtoken, u.client.Post(ctx, fmt.Sprintf("/access/users/%s/token/%s", u.UserID, token.TokenID), token, &newtoken)
}

func (u *User) UpdateAPIToken(ctx context.Context, tokenid string) (token Token, err error) {
return token, u.client.Put(ctx, fmt.Sprintf("/access/users/%s/token/%s", u.UserID, tokenid), token, nil)
}

func (u *User) DeleteAPIToken(ctx context.Context, tokenid string) error {
return u.client.Delete(ctx, fmt.Sprintf("/access/users/%s/token/%s", u.UserID, tokenid), nil)
}

func (u *User) GetTFA(ctx context.Context) (tfa TFA, err error) {
return tfa, u.client.Get(ctx, fmt.Sprintf("/access/users/%s/tfa", u.UserID), &tfa)
}

func (u *User) UnlockTFA(ctx context.Context) error {
return u.client.Delete(ctx, fmt.Sprintf("/access/users/%s/tfa", u.UserID), nil)
}

func (c *Client) Role(ctx context.Context, roleid string) (role Permission, err error) {
err = c.Get(ctx, fmt.Sprintf("/access/roles/%s", roleid), &role)
return
}

func (c *Client) NewRole(ctx context.Context, roleID string, privs string) (err error) {
return c.Post(ctx, "/access/roles", map[string]string{
"roleid": roleID,
"privs": privs,
}, nil)
}

func (c *Client) Roles(ctx context.Context) (roles Roles, err error) {
err = c.Get(ctx, "/access/roles", &roles)
if nil == err {
Expand Down
136 changes: 136 additions & 0 deletions access_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,139 @@ func TestDomain_Sync(t *testing.T) {
domain.Realm = "test"
assert.Nil(t, domain.Sync(ctx, DomainSyncOptions{}))
}

func TestNewUser(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()
user := NewUser{
UserID: "test",
}
assert.Nil(t, client.NewUser(ctx, &user))

}

func TestAPITokens(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

user := &User{
client: client,
UserID: "test",
}

apitokens, err := user.GetAPITokens(ctx)
assert.Nil(t, err)
assert.Len(t, apitokens, 2)
}

func TestAPIToken(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

User := &User{
client: client,
UserID: "root@pam",
}
token, err := User.APIToken(ctx, "test")
assert.Nil(t, err)
assert.NotNil(t, token)

}

func TestUpdateAPIToken(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

User := &User{
client: client,
UserID: "userid",
}
token, err := User.UpdateAPIToken(ctx, "tokenid")
assert.Nil(t, err)
assert.NotNil(t, token)
}

// func TestNewAPIToken(t *testing.T) {
// mocks.On(mockConfig)
// defer mocks.Off()
// client := mockClient()
// ctx := context.Background()

// // Users
// user := &User{
// client: client,
// UserID: "userid",
// }

// token := &Token{
// TokenID: "test",
// Comment: "test",
// Expire: 0,
// }

// newToken, err := user.NewAPIToken(ctx, *token)
// assert.Nil(t, err)
// // Check if newToken.Value is not empty
// assert.NotEmpty(t, newToken.Value)
// // Check if fullTokenid = userid!tokenid
// assert.Equal(t, "userid!test", newToken.FullTokenID)
// }

func TestDeleteAPIToken(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

User := &User{
client: client,
UserID: "root@pam",
}
assert.Nil(t, User.DeleteAPIToken(ctx, "test"))
}

func TestNewRole(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

assert.Nil(t, client.NewRole(ctx, "test", "test"))
}

func TestGetTFA(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

user := &User{
client: client,
UserID: "userid",
}

tfa, err := user.GetTFA(ctx)
assert.Nil(t, err)
assert.Equal(t, "userid", tfa.User)
}

func TestUnlockTFA(t *testing.T) {
mocks.On(mockConfig)
defer mocks.Off()
client := mockClient()
ctx := context.Background()

user := &User{
client: client,
UserID: "userid",
}
assert.Nil(t, user.UnlockTFA(ctx))
}
83 changes: 83 additions & 0 deletions tests/mocks/pve7x/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -869,4 +869,87 @@ func access() {
Post("^/access/groups/groupid").
Reply(200).
JSON(``)

gock.New(config.C.URI).
Post("^/access/users").
Reply(200).
JSON(``)

gock.New(config.C.URI).
Post("^/access/roles").
Reply(200).
JSON(``)

gock.New(config.C.URI).
Get("^/access/users/test/token").
Reply(200).
JSON(`{
"data": [
{
"expire": 100,
"privsep": 0,
"tokenid": "test",
"comment": "comment"
},
{
"expire": 0,
"privsep": 1,
"tokenid": "test2",
"comment": "comment"
}
]
}`)

gock.New(config.C.URI).
Get("^/access/users/root@pam/token/test").
Reply(200).
JSON(`{
"data": {
"expire": 0,
"privsep": 0,
"comment": "comment"
}
}`)

gock.New(config.C.URI).
Post("^/access/users/userid/token/test").
Reply(200).
JSON(`{
"data": {"full-tokenid":"userid!test","value":"tokenvalue"}
}`)

gock.New(config.C.URI).
Delete("^/access/users/root@pam/token/test").
Reply(200).
JSON(``)

gock.New(config.C.URI).
Get("^/access/users/userid/tfa").
Reply(200).
JSON(`{
"data": {
"realm": "pve",
"types": [
"oath"
],
"user": "userid"
}
}`)

gock.New(config.C.URI).
Delete("^/access/users/userid/tfa").
Reply(200).
JSON(``)

gock.New(config.C.URI).
Put("^/access/users/userid/token/tokenid").
Reply(200).
JSON(`
"data": {
"expire": 0,
"privsep": 0,
"comment": "comment"
}
}`)

}
25 changes: 25 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -1181,3 +1181,28 @@ type CustomCertificate struct {
Key string `json:"key,omitempty"` // PEM encoded private key
Restart bool `json:"restart,omitempty"` // restart pveproxy
}

type NewUser struct {
UserID string `json:"userid"`
Comment string `json:"comment,omitempty"`
Email string `json:"email,omitempty"`
Enable bool `json:"enable,omitempty"`
Expire int `json:"expire,omitempty"`
Firstname string `json:"firstname,omitempty"`
Groups []string `json:"groups,omitempty"`
Keys []string `json:"keys,omitempty"`
Lastname string `json:"lastname,omitempty"`
Password string `json:"password,omitempty"`
}

type TFA struct {
Realm string `json:"realm,omitempty"`
Types []string `json:"types,omitempty"`
User string `json:"user,omitempty"`
}

type NewAPIToken struct {
FullTokenID string `json:"full-tokenid,omitempty"`
Info interface{} `json:"info,omitempty"`
Value string `json:"value,omitempty"`
}

0 comments on commit a6a1921

Please sign in to comment.