junobuild_auth/openid/
impls.rs1use crate::openid::jwt::types::cert::Jwks;
2use crate::openid::jwt::types::provider::JwtIssuers;
3use crate::openid::types::provider::{
4 OpenIdAutomationProvider, OpenIdCertificate, OpenIdDelegationProvider, OpenIdProvider,
5};
6use junobuild_shared::data::version::next_version;
7use junobuild_shared::ic::api::time;
8use junobuild_shared::types::state::{Version, Versioned};
9use std::fmt::{Display, Formatter, Result as FmtResult};
10
11impl OpenIdProvider {
12 pub fn jwks_url(&self) -> &'static str {
13 match self {
14 Self::Google => "https://www.googleapis.com/oauth2/v3/certs",
15 Self::GitHubAuth => "https://api.juno.build/v1/auth/certs",
18 Self::GitHubActions => "https://token.actions.githubusercontent.com/.well-known/jwks",
19 }
20 }
21
22 pub fn issuers(&self) -> &[&'static str] {
23 match self {
24 OpenIdProvider::Google => &["https://accounts.google.com", "accounts.google.com"],
25 OpenIdProvider::GitHubAuth => &["https://api.juno.build/auth/github"],
26 OpenIdProvider::GitHubActions => &["https://token.actions.githubusercontent.com"],
27 }
28 }
29}
30
31impl From<&OpenIdDelegationProvider> for OpenIdProvider {
32 fn from(delegation_provider: &OpenIdDelegationProvider) -> Self {
33 match delegation_provider {
34 OpenIdDelegationProvider::Google => OpenIdProvider::Google,
35 OpenIdDelegationProvider::GitHub => OpenIdProvider::GitHubAuth,
36 }
37 }
38}
39
40impl OpenIdDelegationProvider {
41 pub fn jwks_url(&self) -> &'static str {
42 match self {
43 Self::Google => OpenIdProvider::Google.jwks_url(),
44 Self::GitHub => OpenIdProvider::GitHubAuth.jwks_url(),
45 }
46 }
47
48 pub fn issuers(&self) -> &[&'static str] {
49 match self {
50 Self::Google => OpenIdProvider::Google.issuers(),
51 Self::GitHub => OpenIdProvider::GitHubAuth.issuers(),
52 }
53 }
54}
55
56impl JwtIssuers for OpenIdDelegationProvider {
57 fn issuers(&self) -> &[&'static str] {
58 self.issuers()
59 }
60}
61
62impl From<&OpenIdAutomationProvider> for OpenIdProvider {
63 fn from(automation_provider: &OpenIdAutomationProvider) -> Self {
64 match automation_provider {
65 OpenIdAutomationProvider::GitHub => OpenIdProvider::GitHubActions,
66 }
67 }
68}
69
70impl OpenIdAutomationProvider {
71 pub fn jwks_url(&self) -> &'static str {
72 match self {
73 Self::GitHub => OpenIdProvider::GitHubActions.jwks_url(),
74 }
75 }
76
77 pub fn issuers(&self) -> &[&'static str] {
78 match self {
79 Self::GitHub => OpenIdProvider::GitHubActions.issuers(),
80 }
81 }
82}
83
84impl JwtIssuers for OpenIdAutomationProvider {
85 fn issuers(&self) -> &[&'static str] {
86 self.issuers()
87 }
88}
89
90impl Display for OpenIdAutomationProvider {
91 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
92 match self {
93 OpenIdAutomationProvider::GitHub => write!(f, "GitHub"),
94 }
95 }
96}
97
98impl Versioned for OpenIdCertificate {
99 fn version(&self) -> Option<Version> {
100 self.version
101 }
102}
103
104impl OpenIdCertificate {
105 fn get_next_version(current_certificate: &Option<OpenIdCertificate>) -> Version {
106 next_version(current_certificate)
107 }
108
109 pub fn init(jwks: &Jwks) -> Self {
110 let now = time();
111
112 let version = Self::get_next_version(&None);
113
114 Self {
115 jwks: jwks.clone(),
116 created_at: now,
117 updated_at: now,
118 version: Some(version),
119 }
120 }
121
122 pub fn update(current_certificate: &OpenIdCertificate, jwks: &Jwks) -> Self {
123 let now = time();
124
125 let version = Self::get_next_version(&Some(current_certificate.clone()));
126
127 Self {
128 jwks: jwks.clone(),
129 updated_at: now,
130 version: Some(version),
131 ..current_certificate.clone()
132 }
133 }
134}
135
136impl Display for OpenIdProvider {
137 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
138 match self {
139 OpenIdProvider::Google => write!(f, "Google"),
140 OpenIdProvider::GitHubAuth => write!(f, "GitHub"),
141 OpenIdProvider::GitHubActions => write!(f, "GitHub Actions"),
142 }
143 }
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149
150 #[test]
151 fn test_openid_provider_jwks_urls() {
152 assert_eq!(
153 OpenIdProvider::Google.jwks_url(),
154 "https://www.googleapis.com/oauth2/v3/certs"
155 );
156 assert_eq!(
157 OpenIdProvider::GitHubAuth.jwks_url(),
158 "https://api.juno.build/v1/auth/certs"
159 );
160 assert_eq!(
161 OpenIdProvider::GitHubActions.jwks_url(),
162 "https://token.actions.githubusercontent.com/.well-known/jwks"
163 );
164 }
165
166 #[test]
167 fn test_openid_provider_issuers() {
168 assert_eq!(
169 OpenIdProvider::Google.issuers(),
170 &["https://accounts.google.com", "accounts.google.com"]
171 );
172 assert_eq!(
173 OpenIdProvider::GitHubAuth.issuers(),
174 &["https://api.juno.build/auth/github"]
175 );
176 assert_eq!(
177 OpenIdProvider::GitHubActions.issuers(),
178 &["https://token.actions.githubusercontent.com"]
179 );
180 }
181
182 #[test]
183 fn test_delegation_provider_to_openid_provider() {
184 assert_eq!(
185 OpenIdProvider::from(&OpenIdDelegationProvider::Google),
186 OpenIdProvider::Google
187 );
188 assert_eq!(
189 OpenIdProvider::from(&OpenIdDelegationProvider::GitHub),
190 OpenIdProvider::GitHubAuth
191 );
192 }
193
194 #[test]
195 fn test_delegation_provider_jwks_urls() {
196 assert_eq!(
197 OpenIdDelegationProvider::Google.jwks_url(),
198 "https://www.googleapis.com/oauth2/v3/certs"
199 );
200 assert_eq!(
201 OpenIdDelegationProvider::GitHub.jwks_url(),
202 "https://api.juno.build/v1/auth/certs"
203 );
204 }
205
206 #[test]
207 fn test_delegation_provider_issuers() {
208 assert_eq!(
209 OpenIdDelegationProvider::Google.issuers(),
210 &["https://accounts.google.com", "accounts.google.com"]
211 );
212 assert_eq!(
213 OpenIdDelegationProvider::GitHub.issuers(),
214 &["https://api.juno.build/auth/github"]
215 );
216 }
217
218 #[test]
219 fn test_automation_provider_to_openid_provider() {
220 assert_eq!(
221 OpenIdProvider::from(&OpenIdAutomationProvider::GitHub),
222 OpenIdProvider::GitHubActions
223 );
224 }
225
226 #[test]
227 fn test_automation_provider_jwks_urls() {
228 assert_eq!(
229 OpenIdAutomationProvider::GitHub.jwks_url(),
230 "https://token.actions.githubusercontent.com/.well-known/jwks"
231 );
232 }
233
234 #[test]
235 fn test_automation_provider_issuers() {
236 assert_eq!(
237 OpenIdAutomationProvider::GitHub.issuers(),
238 &["https://token.actions.githubusercontent.com"]
239 );
240 }
241
242 #[test]
243 fn test_openid_certificate_init() {
244 let jwks = Jwks { keys: vec![] };
245 let cert = OpenIdCertificate::init(&jwks);
246
247 assert_eq!(cert.version, Some(1));
248 assert_eq!(cert.created_at, cert.updated_at);
249 }
250
251 #[test]
252 fn test_openid_certificate_update() {
253 let jwks = Jwks { keys: vec![] };
254 let initial = OpenIdCertificate::init(&jwks);
255
256 let new_jwks = Jwks { keys: vec![] };
257 let updated = OpenIdCertificate::update(&initial, &new_jwks);
258
259 assert_eq!(updated.version, Some(2));
260 assert_eq!(updated.created_at, initial.created_at);
261 assert!(updated.updated_at >= initial.updated_at);
262 }
263
264 #[test]
265 fn test_openid_provider_display() {
266 assert_eq!(format!("{}", OpenIdProvider::Google), "Google");
267 assert_eq!(format!("{}", OpenIdProvider::GitHubAuth), "GitHub");
268 assert_eq!(
269 format!("{}", OpenIdProvider::GitHubActions),
270 "GitHub Actions"
271 );
272 }
273}