| 1 | //! Workflow jobs' tokens: `G1T_TOKEN` (and `GITHUB_TOKEN`, its alias) for |
| 2 | //! one job of a g1t Actions run. Each acts as the repository's workspace, |
| 3 | //! reaches that repository only, holds the scopes the job's `permissions:` |
| 4 | //! give it, and ends when the job does. See migration 0030. |
| 5 | |
| 6 | use g1t_contracts::identity::{CreateJobTokenArgs, CreatedAccessToken, RevokeJobTokensArgs}; |
| 7 | use g1t_contracts::time::SQL_NOW; |
| 8 | use worker::Result; |
| 9 | |
| 10 | use crate::Identity; |
| 11 | use crate::tokens::Grant; |
| 12 | |
| 13 | /// No job runs longer than a day, whatever its caller asks for. |
| 14 | const MAX_JOB_TTL_SECONDS: u64 = 24 * 60 * 60 + 600; |
| 15 | |
| 16 | impl Identity { |
| 17 | pub async fn create_job_token(&self, a: CreateJobTokenArgs) -> Result<CreatedAccessToken> { |
| 18 | let created = self |
| 19 | .mint_for_workspace( |
| 20 | &a.workspace.id, |
| 21 | &a.name, |
| 22 | a.ttl_seconds.clamp(60, MAX_JOB_TTL_SECONDS), |
| 23 | &Grant::asked(&Some(a.scopes.clone())), |
| 24 | ) |
| 25 | .await?; |
| 26 | self.db |
| 27 | .prepare("UPDATE access_tokens SET repo = ?, job_id = ?, job_run_id = ?, job_pulls = ? WHERE id = ?") |
| 28 | .bind(&[ |
| 29 | format!("{}/{}", a.repo.namespace, a.repo.name).to_lowercase().into(), |
| 30 | a.job_id.as_str().into(), |
| 31 | a.run_id.as_str().into(), |
| 32 | u32::from(a.pull_requests).into(), |
| 33 | created.info.id.as_str().into(), |
| 34 | ])? |
| 35 | .run() |
| 36 | .await?; |
| 37 | Ok(created) |
| 38 | } |
| 39 | |
| 40 | /// Ends a job's tokens: they stop working at once. |
| 41 | pub async fn revoke_job_tokens(&self, a: RevokeJobTokensArgs) -> Result<bool> { |
| 42 | if a.job_id.trim().is_empty() { |
| 43 | return Ok(false); |
| 44 | } |
| 45 | self.db |
| 46 | .prepare(format!( |
| 47 | "UPDATE access_tokens SET expires_at = {SQL_NOW} |
| 48 | WHERE job_id = ? AND (expires_at IS NULL OR expires_at > {SQL_NOW})" |
| 49 | )) |
| 50 | .bind(&[a.job_id.as_str().into()])? |
| 51 | .run() |
| 52 | .await?; |
| 53 | Ok(true) |
| 54 | } |
| 55 | } |