Skip to main content

rustauth_plugins/device_authorization/
mod.rs

1//! OAuth 2.0 device authorization plugin.
2
3mod errors;
4mod options;
5mod routes;
6mod schema;
7mod store;
8
9use std::sync::Arc;
10
11use rustauth_core::error::RustAuthError;
12use rustauth_core::plugin::AuthPlugin;
13
14pub use errors::{
15    ACCESS_DENIED, AUTHENTICATION_REQUIRED, AUTHORIZATION_PENDING, DEVICE_CODE_ALREADY_PROCESSED,
16    EXPIRED_DEVICE_CODE, EXPIRED_USER_CODE, FAILED_TO_CREATE_SESSION, INVALID_DEVICE_CODE,
17    INVALID_DEVICE_CODE_STATUS, INVALID_USER_CODE, POLLING_TOO_FREQUENTLY, USER_NOT_FOUND,
18};
19pub use options::{
20    DeviceAuthorizationOptions, DeviceAuthorizationOptionsBuilder, DeviceAuthorizationOptionsError,
21    DeviceAuthorizationSchemaFields, DeviceAuthorizationSchemaOptions,
22};
23pub use routes::{
24    DeviceApprovalRequest, DeviceCodeRequest, DeviceCodeResponse, DeviceTokenRequest,
25    DeviceTokenResponse, DeviceVerificationResponse,
26};
27pub use store::{DeviceAuthorizationStatus, DeviceCodeRecord};
28
29pub const UPSTREAM_PLUGIN_ID: &str = "device-authorization";
30
31/// Build the device authorization plugin.
32pub fn device_authorization(
33    options: DeviceAuthorizationOptions,
34) -> Result<AuthPlugin, RustAuthError> {
35    options
36        .validate()
37        .map_err(|error| rustauth_core::error::RustAuthError::InvalidConfig(error.to_string()))?;
38    let schema_options = options.schema.clone();
39    let options = Arc::new(options);
40    Ok(AuthPlugin::new(UPSTREAM_PLUGIN_ID)
41        .with_version(crate::VERSION)
42        .with_schema(schema::device_code_table(&schema_options))
43        .with_endpoint(routes::device_code(Arc::clone(&options)))
44        .with_endpoint(routes::device_token(Arc::clone(&options)))
45        .with_endpoint(routes::device_verify())
46        .with_endpoint(routes::device_approve())
47        .with_endpoint(routes::device_deny())
48        .with_error_code(errors::plugin_error_code(
49            INVALID_DEVICE_CODE,
50            "Invalid device code",
51        ))
52        .with_error_code(errors::plugin_error_code(
53            EXPIRED_DEVICE_CODE,
54            "Device code has expired",
55        ))
56        .with_error_code(errors::plugin_error_code(
57            EXPIRED_USER_CODE,
58            "User code has expired",
59        ))
60        .with_error_code(errors::plugin_error_code(
61            AUTHORIZATION_PENDING,
62            "Authorization pending",
63        ))
64        .with_error_code(errors::plugin_error_code(ACCESS_DENIED, "Access denied"))
65        .with_error_code(errors::plugin_error_code(
66            INVALID_USER_CODE,
67            "Invalid user code",
68        ))
69        .with_error_code(errors::plugin_error_code(
70            DEVICE_CODE_ALREADY_PROCESSED,
71            "Device code already processed",
72        ))
73        .with_error_code(errors::plugin_error_code(
74            POLLING_TOO_FREQUENTLY,
75            "Polling too frequently",
76        ))
77        .with_error_code(errors::plugin_error_code(USER_NOT_FOUND, "User not found"))
78        .with_error_code(errors::plugin_error_code(
79            FAILED_TO_CREATE_SESSION,
80            "Failed to create session",
81        ))
82        .with_error_code(errors::plugin_error_code(
83            INVALID_DEVICE_CODE_STATUS,
84            "Invalid device code status",
85        ))
86        .with_error_code(errors::plugin_error_code(
87            AUTHENTICATION_REQUIRED,
88            "Authentication required",
89        )))
90}