headless_lms_models/library/oauth/scopes.rs
1//! The OAuth scopes this provider knows.
2//!
3//! Scopes are validated per client against `oauth_clients.scopes`; this registry spells the scope
4//! strings with cross-cutting meaning once.
5
6use super::mcp::McpScope;
7
8/// Scope carried by device-flow tokens issued to native/editor clients (e.g.
9/// the TMC CLI / VSCode extension). It gates access to the exercise-services
10/// client API and is also checked by tmc-server when it introspects
11/// courses.mooc.fi tokens.
12pub const EXERCISE_SERVICES_SCOPE: &str = "exercise-services";
13
14/// Asks for a refresh token. Allowed alongside any resource's scopes.
15pub const OFFLINE_ACCESS_SCOPE: &str = "offline_access";
16
17/// Every scope the provider supports, as discovery advertises them.
18pub fn supported_scopes() -> Vec<&'static str> {
19 let mut scopes = vec![
20 "openid",
21 "profile",
22 "email",
23 OFFLINE_ACCESS_SCOPE,
24 EXERCISE_SERVICES_SCOPE,
25 ];
26 scopes.extend(McpScope::all_strs());
27 scopes
28}
29
30/// Scopes a client registered through a Client ID Metadata Document may request: the MCP scopes
31/// and `offline_access`.
32pub fn metadata_document_client_scopes() -> Vec<String> {
33 McpScope::all_strs()
34 .into_iter()
35 .chain([OFFLINE_ACCESS_SCOPE])
36 .map(str::to_string)
37 .collect()
38}