add: user grants

TODO: add grant creation api, grant tab in sessions tab of settings, grant api endpoints
This commit is contained in:
trisua 2025-05-31 14:38:38 -04:00
parent 7de2c2e935
commit bf27c51ad3
8 changed files with 98 additions and 7 deletions

View file

@ -1,6 +1,6 @@
use std::collections::HashMap;
use super::permissions::FinePermission;
use super::{oauth::AuthGrant, permissions::FinePermission};
use serde::{Deserialize, Serialize};
use totp_rs::TOTP;
use tetratto_shared::{
@ -43,6 +43,9 @@ pub struct User {
/// The user's Stripe customer ID.
#[serde(default)]
pub stripe_id: String,
/// The grants associated with the user's account.
#[serde(default)]
pub grants: Vec<AuthGrant>,
}
pub type UserConnections =
@ -251,6 +254,7 @@ impl User {
request_count: 0,
connections: HashMap::new(),
stripe_id: String::new(),
grants: Vec::new(),
}
}

View file

@ -3,21 +3,63 @@ use serde::{Serialize, Deserialize};
use tetratto_shared::hash::hash;
use super::{Result, Error};
#[derive(Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AuthGrant {
pub id: usize,
/// The name of the application associated with this grant.
pub name: String,
/// The code challenge for PKCE verifiers associated with this grant.
///
/// This challenge is *all* that is required to refresh this grant's auth token.
/// While there can only be one token at a time, it can be refreshed whenever as long
/// as the provided verifier matches that of the challenge.
///
/// The challenge should never be changed. To change the challenge, the grant
/// should be removed and recreated.
pub challenge: String,
/// The encoding method for the initial verifier in the challenge.
pub method: PkceChallengeMethod,
/// The access token associated with the account. This is **not** the same as
/// regular account access tokens, as the token can only be used with the requested `scopes`.
pub token: String,
/// Scopes define what the grant's token is actually allowed to do.
///
/// No scope shall ever be allowed to change scopes or manage grants on behalf of the user.
/// A regular user token **must** be provided to manage grants.
pub scopes: Vec<AppScope>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum PkceChallengeMethod {
S256,
}
#[derive(Serialize, Deserialize, PartialEq, Eq)]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum AppScope {
/// Read the user's profile (username, bio, etc).
UserReadProfile,
/// Read the user's settings.
UserReadSettings,
/// Read the user's sessions and info.
UserReadSessions,
/// Read posts as the user.
UserReadPosts,
/// Read messages as the user.
UserReadMessages,
/// Create posts as the user.
UserCreatePosts,
/// Create messages as the user.
UserCreateMessages,
/// Delete posts owned by the user.
UserDeletePosts,
/// Delete messages owned by the user.
UserDeleteMessages,
/// Manage stacks owned by the user.
UserManageStacks,
/// Manage the user's following/unfollowing.
UserManageRelationships,
/// Manage the user's settings.
UserManageSettings,
}
impl AppScope {
@ -27,6 +69,7 @@ impl AppScope {
for scope in input.split(" ") {
out.push(match scope {
"user-read-profile" => Self::UserReadProfile,
"user-read-settings" => Self::UserReadSettings,
"user-read-sessions" => Self::UserReadSessions,
"user-read-posts" => Self::UserReadPosts,
"user-read-messages" => Self::UserReadMessages,
@ -34,6 +77,9 @@ impl AppScope {
"user-create-messages" => Self::UserCreateMessages,
"user-delete-posts" => Self::UserDeletePosts,
"user-delete-messages" => Self::UserDeleteMessages,
"user-manage-stacks" => Self::UserManageStacks,
"user-manage-relationships" => Self::UserManageRelationships,
"user-manage-settings" => Self::UserManageSettings,
_ => continue,
})
}