-
Notifications
You must be signed in to change notification settings - Fork 1
/
path_token.go
93 lines (80 loc) · 2.48 KB
/
path_token.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package artifactory
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
rtTokenService "github.com/jsok/vault-plugin-secrets-artifactory/pkg/token"
)
func pathToken(b *backend) *framework.Path {
return &framework.Path{
Pattern: "token/" + framework.GenericNameRegex("name"),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeString,
Description: "The name of the role.",
},
},
Callbacks: map[logical.Operation]framework.OperationFunc{
logical.ReadOperation: b.pathTokenRead,
},
HelpSynopsis: pathTokenHelpSyn,
}
}
func (b *backend) pathTokenRead(ctx context.Context, req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
roleName := d.Get("name").(string)
if roleName == "" {
return nil, errors.New("role name is required")
}
role, err := readRole(ctx, req.Storage, roleName)
if err != nil {
return nil, err
}
if role == nil {
return logical.ErrorResponse("role does not exist"), nil
}
client, rtDetails, err := b.rtClient(ctx, req.Storage)
if client == nil || rtDetails == nil {
return nil, fmt.Errorf("Failed to create Artifactory client: %v\n", err)
}
username := role.Username
if username == "" {
username = generateRoleUsername(roleName, req.ID)
}
tokenService := rtTokenService.NewAccessTokenService(client)
tokenService.SetArtifactoryDetails(rtDetails)
tokenResp, err := tokenService.CreateToken(&rtTokenService.CreateTokenRequest{
Username: username,
Scope: fmt.Sprintf("member-of-groups:%s", strings.Join(role.MemberOfGroups, ",")),
ExpiresIn: int64(role.TTL.Seconds()),
Refreshable: false,
})
if err != nil {
return nil, fmt.Errorf("Failed to create access token: %v\n", err)
}
resp := b.Secret(accessTokenSecretType).Response(
map[string]interface{}{
"access_token": tokenResp.AccessToken,
"scope": tokenResp.Scope,
"token_type": tokenResp.TokenType,
},
map[string]interface{}{
"role_name": roleName,
"username": username,
},
)
resp.Secret.TTL = time.Duration(tokenResp.ExpiresIn) * time.Second
resp.Secret.MaxTTL = resp.Secret.MaxTTL
return resp, nil
}
// Generate a transient username that's highly unlikely to clash
// with an existing Artifactory username.
func generateRoleUsername(role, id string) string {
return fmt.Sprintf("vault-%s-%s", role, id)
}
const pathTokenHelpSyn = `
Create an Artifactory access token against the specified role.
`