-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathhmac_key.dart
More file actions
131 lines (117 loc) · 4.68 KB
/
hmac_key.dart
File metadata and controls
131 lines (117 loc) · 4.68 KB
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
part of '../google_cloud_storage.dart';
/// A handle to a single HMAC key, analogous to the Node.js HmacKey class.
///
/// This class does not expose the secret; that is only returned at creation
/// time by `projects.hmacKeys.create`.
class HmacKey extends ServiceObject<HmacKeyMetadata>
with
GettableMixin<HmacKeyMetadata, HmacKey>,
DeletableMixin<HmacKeyMetadata> {
/// A reference to the [Storage] associated with this [HmacKey] instance.
final Storage storage;
final String _accessId;
HmacKey._(this.storage, this._accessId, {HmacKeyOptions? options})
: super(
service: storage,
id: _accessId,
metadata: HmacKeyMetadata()
..accessId = _accessId
..projectId = options?.projectId ?? storage.options.projectId,
);
/// Delete this HMAC key.
///
/// The server requires the key to be `INACTIVE` before deletion.
@override
Future<void> delete({PreconditionOptions? options}) async {
// HMAC key delete doesn't use preconditions, but we accept the parameter
// for base class compatibility. userProject is not supported via options.
final api = ApiExecutor(storage);
await api.executeWithProjectId<void>((client, projectId) async {
await client.projects.hmacKeys.delete(projectId, _accessId);
}, projectIdOverride: metadata.projectId);
}
/// Retrieve and populate this HMAC key's metadata, and return this [HmacKey]
/// instance.
///
/// This method does not give the HMAC key secret, as it is only returned
/// on creation.
///
/// The authenticated user must have `storage.hmacKeys.get` permission
/// for the project in which the key exists.
Future<HmacKey> getInstance({String? userProject}) async {
await getMetadata(userProject: userProject);
return this;
}
/// Retrieve and cache the latest metadata for this HMAC key.
///
/// This method does not give the HMAC key secret, as it is only returned
/// on creation.
///
/// The authenticated user must have `storage.hmacKeys.get` permission
/// for the project in which the key exists.
///
/// Note: This method has a different signature than the mixin's `getMetadata()`
/// (which takes no parameters), so both methods are available.
@override
Future<HmacKeyMetadata> getMetadata({String? userProject}) async {
final api = ApiExecutor(storage);
final metadata = await api.executeWithProjectId<HmacKeyMetadata>(
(client, projectId) async => await client.projects.hmacKeys.get(
projectId,
_accessId,
userProject: userProject,
),
projectIdOverride: this.metadata.projectId,
);
setInstanceMetadata(metadata);
return metadata;
}
/// Get the HMAC key metadata and return this instance.
///
/// This follows the standard ServiceObject pattern: calls [getMetadata()]
/// to fetch and update metadata, then returns this instance.
///
/// Note: HMAC keys don't support userProject, so this parameter is ignored.
@override
Future<HmacKey> get({String? userProject}) async {
await getMetadata();
return this;
}
/// Helper for HMAC key mutations: only retry if idempotency strategy is retryAlways.
///
/// ETag preconditions are not fully supported for HMAC keys, so we disable
/// retries unless the strategy explicitly allows always retrying.
static bool _shouldRetryHmacKeyMutation(
PreconditionOptions? callPreconditions,
PreconditionOptions? instancePreconditions,
RetryOptions retryOptions,
) {
return retryOptions.idempotencyStrategy == IdempotencyStrategy.retryAlways;
}
/// Update the metadata for this HMAC key (e.g. state, etag).
///
/// Node disables retries here unless IdempotencyStrategy is RetryAlways,
/// because ETag preconditions are not fully supported. We mirror that by
/// using [shouldRetryHmacKeyMutation] with [RetryExecutor].
///
/// This overrides [ServiceObject.setMetadata] to provide custom retry behavior.
/// The [metadata] parameter should have [state] and/or [etag] set for updates.
/// To use [SetHmacKeyMetadata], create an [HmacKeyMetadata] with the desired
/// state and etag values.
Future<HmacKeyMetadata> setMetadata(HmacKeyMetadata updateMetadata) async {
final api = ApiExecutor(
storage,
shouldRetryMutation: _shouldRetryHmacKeyMutation,
);
final request = HmacKeyMetadata()
..state = updateMetadata.state
..etag = updateMetadata.etag;
final metadata = await api.executeWithProjectId<HmacKeyMetadata>(
(client, projectId) async =>
await client.projects.hmacKeys.update(request, projectId, _accessId),
projectIdOverride: this.metadata.projectId,
);
setInstanceMetadata(metadata);
return metadata;
}
}