Add approval request HTTP surface
This commit is contained in:
@@ -27,6 +27,41 @@ pub(super) async fn require_machine_access(
|
||||
Ok(credential)
|
||||
}
|
||||
|
||||
pub(super) async fn require_approval_access(
|
||||
state: &Arc<AppState>,
|
||||
path: &AgentRoutePath,
|
||||
headers: &HeaderMap,
|
||||
required_scope: PlatformApiKeyScope,
|
||||
) -> Result<crank_registry::PlatformApiKeyRecord, StatusCode> {
|
||||
let secret = bearer_token(headers).ok_or(StatusCode::UNAUTHORIZED)?;
|
||||
let secret_hash = hash_access_secret(secret);
|
||||
let Some(api_key) = state
|
||||
.registry
|
||||
.get_approval_api_key_by_secret_for_agent_slug(
|
||||
&path.workspace_slug,
|
||||
&path.agent_slug,
|
||||
&secret_hash,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
|
||||
else {
|
||||
return Err(StatusCode::UNAUTHORIZED);
|
||||
};
|
||||
|
||||
if !approval_allows_scope(&api_key.api_key.scopes, required_scope) {
|
||||
return Err(StatusCode::FORBIDDEN);
|
||||
}
|
||||
|
||||
let used_at = OffsetDateTime::now_utc();
|
||||
state
|
||||
.registry
|
||||
.touch_platform_api_key(&api_key.api_key.workspace_id, &api_key.api_key.id, &used_at)
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
|
||||
Ok(api_key)
|
||||
}
|
||||
|
||||
pub(super) fn bearer_token(headers: &HeaderMap) -> Option<&str> {
|
||||
let value = headers.get(AUTHORIZATION)?.to_str().ok()?;
|
||||
let (scheme, token) = value.split_once(' ')?;
|
||||
@@ -136,6 +171,20 @@ fn allows_scope(scopes: &[PlatformApiKeyScope], required_scope: PlatformApiKeySc
|
||||
}
|
||||
}
|
||||
|
||||
fn approval_allows_scope(
|
||||
scopes: &[PlatformApiKeyScope],
|
||||
required_scope: PlatformApiKeyScope,
|
||||
) -> bool {
|
||||
scopes.iter().any(|scope| match required_scope {
|
||||
PlatformApiKeyScope::Approve => matches!(scope, PlatformApiKeyScope::Approve),
|
||||
PlatformApiKeyScope::Deny => matches!(scope, PlatformApiKeyScope::Deny),
|
||||
PlatformApiKeyScope::ReadPending => matches!(scope, PlatformApiKeyScope::ReadPending),
|
||||
PlatformApiKeyScope::Read | PlatformApiKeyScope::Write | PlatformApiKeyScope::Deploy => {
|
||||
false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn security_level_rank(level: OperationSecurityLevel) -> u8 {
|
||||
match level {
|
||||
OperationSecurityLevel::Standard => 0,
|
||||
|
||||
Reference in New Issue
Block a user