-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbackend.go
144 lines (132 loc) · 4.3 KB
/
backend.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package jwt
import (
"context"
"fmt"
JWT "github.com/dgrijalva/jwt-go"
"github.com/hashicorp/vault/sdk/framework"
"github.com/hashicorp/vault/sdk/logical"
)
func Factory(ctx context.Context, conf *logical.BackendConfig) (logical.Backend, error) {
b := NewBackend()
if err := b.Setup(ctx, conf); err != nil {
return nil, err
}
return b, nil
}
type Backend struct {
*framework.Backend
}
func NewBackend() Backend {
b := Backend{}
b.Backend = &framework.Backend{
Help: "The JWT backend generates & validates JWT tokens.",
Paths: []*framework.Path{
&framework.Path{
Pattern: fmt.Sprintf("roles/%s/config", framework.GenericNameRegex("name")),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeLowerCaseString,
Description: "Name of the role",
Required: true,
},
"alg": {
Type: framework.TypeString,
Description: "Signing algorithm to use",
AllowedValues: []interface{}{
JWT.SigningMethodRS256.Alg(),
JWT.SigningMethodRS384.Alg(),
JWT.SigningMethodRS512.Alg(),
JWT.SigningMethodHS256.Alg(),
JWT.SigningMethodHS384.Alg(),
JWT.SigningMethodHS512.Alg(),
},
},
"key": {
Type: framework.TypeString,
Description: "Key to use to sign/verify JWTs. If not specified, an RSA key will be generated.",
},
"exp": {
Type: framework.TypeDurationSecond,
Description: "How long the JWT lives after its creation time",
Required: true,
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.CreateOperation: &framework.PathOperation{
Callback: b.operationCreateRole,
},
logical.UpdateOperation: &framework.PathOperation{
Callback: b.operationUpdateRole,
},
logical.ReadOperation: &framework.PathOperation{
Callback: b.operationReadRole,
},
logical.DeleteOperation: &framework.PathOperation{
Callback: b.operationDeleteRole,
},
},
ExistenceCheck: func(ctx context.Context, req *logical.Request, data *framework.FieldData) (bool, error) {
name := data.Get("name").(string)
role, err := getRole(ctx, req.Storage, name)
if err != nil {
return false, err
}
if role == nil {
return false, nil
}
return true, nil
},
HelpSynopsis: "Configures a JWT role.",
HelpDescription: "Before being able to generate JWTs, the backend needs some information about how " +
"to generate it such as the secret key to use and the fields to include in the claims.",
},
&framework.Path{
Pattern: fmt.Sprintf("roles/%s/generate", framework.GenericNameRegex("name")),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeLowerCaseString,
Description: "Name of the role",
Required: true,
},
// TODO: `nbf`?
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.operationGenerateToken,
},
},
HelpSynopsis: "Configures a JWT role.",
HelpDescription: "Before being able to generate JWTs, the backend needs some information about how " +
"to generate it such as the secret key to use and the fields to include in the claims.",
},
&framework.Path{
Pattern: fmt.Sprintf("roles/%s/validate", framework.GenericNameRegex("name")),
Fields: map[string]*framework.FieldSchema{
"name": {
Type: framework.TypeLowerCaseString,
Description: "Name of the role",
Required: true,
},
"token": {
Type: framework.TypeString,
Description: "Token to be validated",
Required: true,
},
},
Operations: map[logical.Operation]framework.OperationHandler{
logical.CreateOperation: &framework.PathOperation{
Callback: b.operationValidateToken,
},
logical.UpdateOperation: &framework.PathOperation{
Callback: b.operationValidateToken,
},
},
HelpSynopsis: "Configures a JWT role.",
HelpDescription: "Before being able to generate JWTs, the backend needs some information about how " +
"to generate it such as the secret key to use and the fields to include in the claims.",
},
},
BackendType: logical.TypeLogical,
}
return b
}