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
//! The [`ProviderAccountStore`] trait -- storage of Provider Accounts and their usage.
use chrono::{DateTime, Utc};
use uuid::Uuid;
use crate::entities::{
NewProviderAccount, NewProviderAccountObservation, Page, ProviderAccount,
ProviderAccountCandidate, ProviderAccountUpdate, ProviderAccountUsagePoint,
ProviderAccountWindow,
};
use crate::store::StoreFuture;
/// Async storage abstraction for Provider Accounts.
///
/// The credential of an account is not stored here: it lives in the system
/// secret [`ProviderAccount::secret_key`], managed through
/// [`SecretStore`](crate::secret_store::SecretStore).
pub trait ProviderAccountStore: Send + Sync {
/// Create an account.
///
/// # Errors
///
/// Returns [`StoreError::DuplicateProviderAccount`](crate::error::StoreError)
/// when the name is taken.
fn create_provider_account(&self, req: NewProviderAccount) -> StoreFuture<'_, ProviderAccount>;
/// Find an account by ID.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn get_provider_account(&self, id: Uuid) -> StoreFuture<'_, Option<ProviderAccount>>;
/// Find an account by name.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn find_provider_account_by_name(&self, name: &str)
-> StoreFuture<'_, Option<ProviderAccount>>;
/// List accounts, optionally of one kind, ordered by `priority` then `name`.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn list_provider_accounts(
&self,
kind: Option<String>,
page: u32,
per_page: u32,
) -> StoreFuture<'_, Page<ProviderAccount>>;
/// Update an account and bump `updated_at`.
///
/// # Errors
///
/// Returns [`StoreError::ProviderAccountNotFound`](crate::error::StoreError)
/// when the account does not exist.
fn update_provider_account(
&self,
id: Uuid,
update: ProviderAccountUpdate,
) -> StoreFuture<'_, ProviderAccount>;
/// Delete an account. Its windows and usage are deleted with it and the
/// steps that ran under it lose their `account_id`.
///
/// Returns `false` when the account did not exist.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn delete_provider_account(&self, id: Uuid) -> StoreFuture<'_, bool>;
/// Latest windows of every account in `ids`, in one query.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn list_provider_account_windows(
&self,
ids: Vec<Uuid>,
) -> StoreFuture<'_, Vec<ProviderAccountWindow>>;
/// Usage history of an account since `since`, oldest first.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn list_provider_account_usage(
&self,
id: Uuid,
since: DateTime<Utc>,
) -> StoreFuture<'_, Vec<ProviderAccountUsagePoint>>;
/// Record observed windows in one transaction and return the current windows.
///
/// Every window is upserted unless a newer observation is already stored,
/// and appended to the history. `auth_failed_at` is set when
/// `auth_failed`, and cleared when windows were recorded without it.
///
/// # Errors
///
/// Returns [`StoreError::ProviderAccountNotFound`](crate::error::StoreError)
/// when the account does not exist.
fn record_provider_account_observation(
&self,
id: Uuid,
observation: NewProviderAccountObservation,
) -> StoreFuture<'_, Vec<ProviderAccountWindow>>;
/// Delete usage history observed before `before`. Returns the number of rows deleted.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn purge_provider_account_usage(&self, before: DateTime<Utc>) -> StoreFuture<'_, u64>;
/// Accounts of `kind` a step may run under: enabled, credential not
/// rejected and not expired, with their windows and running steps.
///
/// # Errors
///
/// Returns [`StoreError`](crate::error::StoreError) on storage failure.
fn list_provider_account_candidates(
&self,
kind: String,
) -> StoreFuture<'_, Vec<ProviderAccountCandidate>>;
}