@@ -4,25 +4,138 @@ import (
4
4
"context"
5
5
"crypto/sha1"
6
6
"fmt"
7
+ "strconv"
7
8
"strings"
8
9
"time"
9
10
11
+ "github.com/hashicorp/go-multierror"
12
+ "github.com/hashicorp/vault/sdk/framework"
10
13
"github.com/hashicorp/vault/sdk/logical"
11
14
)
12
15
13
16
type EntryConfig struct {
14
17
TokenId int `json:"token_id" yaml:"token_id" mapstructure:"token_id"`
15
18
BaseURL string `json:"base_url" structs:"base_url" mapstructure:"base_url"`
16
- Token string `json:"token" structs:"token" mapstructure:"token"`
19
+ Token string `json:"token" structs:"token" mapstructure:"token" validate:"min=10,max=40" `
17
20
AutoRotateToken bool `json:"auto_rotate_token" structs:"auto_rotate_token" mapstructure:"auto_rotate_token"`
18
21
AutoRotateBefore time.Duration `json:"auto_rotate_before" structs:"auto_rotate_before" mapstructure:"auto_rotate_before"`
19
22
TokenCreatedAt time.Time `json:"token_created_at" structs:"token_created_at" mapstructure:"token_created_at"`
20
23
TokenExpiresAt time.Time `json:"token_expires_at" structs:"token_expires_at" mapstructure:"token_expires_at"`
21
24
Scopes []string `json:"scopes" structs:"scopes" mapstructure:"scopes"`
22
- Type Type `json:"type" structs:"type" mapstructure:"type"`
25
+ Type Type `json:"type" structs:"type" mapstructure:"type" validate:"gitlab-type" `
23
26
}
24
27
25
- func (e EntryConfig ) Response () * logical.Response {
28
+ func (e * EntryConfig ) Merge (data * framework.FieldData ) (warnings []string , changes map [string ]string , err error ) {
29
+ var er error
30
+ if data == nil {
31
+ return warnings , changes , multierror .Append (fmt .Errorf ("data: %w" , ErrNilValue ))
32
+ }
33
+
34
+ if err = data .Validate (); err != nil {
35
+ return warnings , changes , multierror .Append (err )
36
+ }
37
+
38
+ changes = make (map [string ]string )
39
+
40
+ if val , ok := data .GetOk ("auto_rotate_token" ); ok {
41
+ e .AutoRotateToken = val .(bool )
42
+ changes ["auto_rotate_token" ] = strconv .FormatBool (e .AutoRotateToken )
43
+ }
44
+
45
+ if typ , ok := data .GetOk ("type" ); ok {
46
+ var pType Type
47
+ if pType , er = TypeParse (typ .(string )); er != nil {
48
+ err = multierror .Append (err , er )
49
+ } else {
50
+ e .Type = pType
51
+ changes ["type" ] = pType .String ()
52
+ }
53
+ }
54
+
55
+ if _ , ok := data .GetOk ("auto_rotate_before" ); ok {
56
+ w , er := e .updateAutoRotateBefore (data )
57
+ if er != nil {
58
+ err = multierror .Append (err , er .Errors ... )
59
+ } else {
60
+ changes ["auto_rotate_before" ] = e .AutoRotateBefore .String ()
61
+ }
62
+ warnings = append (warnings , w ... )
63
+ }
64
+
65
+ if val , ok := data .GetOk ("base_url" ); ok && len (val .(string )) > 0 {
66
+ e .BaseURL = val .(string )
67
+ changes ["base_url" ] = e .BaseURL
68
+ }
69
+
70
+ if val , ok := data .GetOk ("token" ); ok && len (val .(string )) > 0 {
71
+ e .Token = val .(string )
72
+ changes ["token" ] = strings .Repeat ("*" , len (e .Token ))
73
+ }
74
+
75
+ return warnings , changes , err
76
+ }
77
+
78
+ func (e * EntryConfig ) updateAutoRotateBefore (data * framework.FieldData ) (warnings []string , err * multierror.Error ) {
79
+ if val , ok := data .GetOk ("auto_rotate_before" ); ok {
80
+ atr , _ := convertToInt (val )
81
+ if atr > int (DefaultAutoRotateBeforeMaxTTL .Seconds ()) {
82
+ err = multierror .Append (err , fmt .Errorf ("auto_rotate_token can not be bigger than %s: %w" , DefaultAutoRotateBeforeMaxTTL , ErrInvalidValue ))
83
+ } else if atr <= int (DefaultAutoRotateBeforeMinTTL .Seconds ())- 1 {
84
+ err = multierror .Append (err , fmt .Errorf ("auto_rotate_token can not be less than %s: %w" , DefaultAutoRotateBeforeMinTTL , ErrInvalidValue ))
85
+ } else {
86
+ e .AutoRotateBefore = time .Duration (atr ) * time .Second
87
+ }
88
+ } else {
89
+ e .AutoRotateBefore = DefaultAutoRotateBeforeMinTTL
90
+ warnings = append (warnings , fmt .Sprintf ("auto_rotate_token not specified setting to %s" , DefaultAutoRotateBeforeMinTTL ))
91
+ }
92
+ return warnings , err
93
+ }
94
+
95
+ func (e * EntryConfig ) UpdateFromFieldData (data * framework.FieldData ) (warnings []string , err error ) {
96
+ if data == nil {
97
+ return warnings , multierror .Append (fmt .Errorf ("data: %w" , ErrNilValue ))
98
+ }
99
+
100
+ if err = data .Validate (); err != nil {
101
+ return warnings , multierror .Append (err )
102
+ }
103
+
104
+ var er error
105
+ e .AutoRotateToken = data .Get ("auto_rotate_token" ).(bool )
106
+
107
+ if token , ok := data .GetOk ("token" ); ok && len (token .(string )) > 0 {
108
+ e .Token = token .(string )
109
+ } else {
110
+ err = multierror .Append (err , fmt .Errorf ("token: %w" , ErrFieldRequired ))
111
+ }
112
+
113
+ if typ , ok := data .GetOk ("type" ); ok {
114
+ if e .Type , er = TypeParse (typ .(string )); er != nil {
115
+ err = multierror .Append (err , er )
116
+ }
117
+ } else {
118
+ err = multierror .Append (err , fmt .Errorf ("gitlab type: %w" , ErrFieldRequired ))
119
+ }
120
+
121
+ if baseUrl , ok := data .GetOk ("base_url" ); ok && len (baseUrl .(string )) > 0 {
122
+ e .BaseURL = baseUrl .(string )
123
+ } else {
124
+ err = multierror .Append (err , fmt .Errorf ("base_url: %w" , ErrFieldRequired ))
125
+ }
126
+
127
+ {
128
+ w , er := e .updateAutoRotateBefore (data )
129
+ if er != nil {
130
+ err = multierror .Append (err , er .Errors ... )
131
+ }
132
+ warnings = append (warnings , w ... )
133
+ }
134
+
135
+ return warnings , err
136
+ }
137
+
138
+ func (e * EntryConfig ) Response () * logical.Response {
26
139
return & logical.Response {
27
140
Secret : & logical.Secret {
28
141
LeaseOptions : logical.LeaseOptions {},
@@ -35,7 +148,7 @@ func (e EntryConfig) Response() *logical.Response {
35
148
}
36
149
}
37
150
38
- func (e EntryConfig ) LogicalResponseData () map [string ]any {
151
+ func (e * EntryConfig ) LogicalResponseData () map [string ]any {
39
152
var tokenExpiresAt , tokenCreatedAt = "" , ""
40
153
if ! e .TokenExpiresAt .IsZero () {
41
154
tokenExpiresAt = e .TokenExpiresAt .Format (time .RFC3339 )
@@ -57,33 +170,25 @@ func (e EntryConfig) LogicalResponseData() map[string]any {
57
170
}
58
171
}
59
172
60
- func getConfig (ctx context.Context , s logical.Storage ) (* EntryConfig , error ) {
173
+ func getConfig (ctx context.Context , s logical.Storage ) (cfg * EntryConfig , err error ) {
61
174
if s == nil {
62
175
return nil , fmt .Errorf ("%w: local.Storage" , ErrNilValue )
63
176
}
64
- entry , err := s .Get (ctx , PathConfigStorage )
65
- if err != nil {
66
- return nil , err
177
+ var entry * logical.StorageEntry
178
+ if entry , err = s .Get (ctx , PathConfigStorage ); err == nil {
179
+ if entry == nil {
180
+ return nil , nil
181
+ }
182
+ cfg = new (EntryConfig )
183
+ _ = entry .DecodeJSON (cfg )
67
184
}
68
-
69
- if entry == nil {
70
- return nil , nil
71
- }
72
-
73
- cfg := new (EntryConfig )
74
- if err := entry .DecodeJSON (cfg ); err != nil {
75
- return nil , err
76
- }
77
- return cfg , nil
185
+ return cfg , err
78
186
}
79
187
80
- func saveConfig (ctx context.Context , config EntryConfig , s logical.Storage ) error {
81
- var err error
188
+ func saveConfig (ctx context.Context , config EntryConfig , s logical.Storage ) (err error ) {
82
189
var storageEntry * logical.StorageEntry
83
- storageEntry , err = logical .StorageEntryJSON (PathConfigStorage , config )
84
- if err != nil {
85
- return nil
190
+ if storageEntry , err = logical .StorageEntryJSON (PathConfigStorage , config ); err == nil {
191
+ err = s .Put (ctx , storageEntry )
86
192
}
87
-
88
- return s .Put (ctx , storageEntry )
193
+ return err
89
194
}
0 commit comments