Skip to content

Commit

Repository listing follows a fine-grained token's selection; job tokens never get workflow files

syntaqxcommitted Parent3393711Browse files
2 files+27−20/2 viewed
+6−0
259259 // What g1t has nothing behind grants nothing.
260260 let (oidc, _) = parse(&json!({ "id-token": "write", "discussions": "write" })).unwrap();
261261 assert_eq!(oidc.scopes(), ["repo:read"]);
262+ // A job's token never changes workflow files, whatever it asks for:
263+ // `workflows` is no permission a job's token has.
264+ assert!(!scopes.contains(&"workflow_files:write"));
265+ let (files, unknown) = parse(&json!({ "workflows": "write", "contents": "write" })).unwrap();
266+ assert_eq!(unknown, ["workflows"]);
267+ assert!(!files.scopes().contains(&"workflow_files:write"));
262268 }
263269
264270 #[test]
+21−2
421421 })
422422 .map(|membership| membership.slug.as_str())
423423 .collect();
424− let granted: Vec<&str> = viewer
424+ let mut granted: Vec<&str> = viewer
425425 .iter()
426− .flat_map(|user| &user.grants)
426+ .flat_map(|user| {
427+ let token = user.token.as_deref();
428+ user.grants
429+ .iter()
430+ .filter(move |grant| token.is_none_or(|token| token.covers_repo(&grant.repo_id, &grant.workspace)))
431+ })
427432 .map(|grant| grant.repo_id.as_str())
428433 .collect();
434+ // A fine-grained token's selected repositories, where its owner's
435+ // membership reaches them.
436+ if let Some(user) = viewer.as_ref()
437+ && let Some(reach) = user.token.as_deref().and_then(|token| token.fine_grained.as_ref())
438+ && let Some(workspace) = reach.workspace.as_deref()
439+ {
440+ granted.extend(
441+ reach
442+ .repo_ids
443+ .iter()
444+ .filter(|id| access::granted(user, access::RepoRef { id, namespace: workspace, private: true }).is_some())
445+ .map(String::as_str),
446+ );
447+ }
429448 let mut params: Vec<JsValue> = vec![
430449 serde_json::to_string(&reading)?.into(),
431450 serde_json::to_string(&granted)?.into(),