Skip to main content

tetratto_core/model/
oauth.rs

1use base64::{engine::general_purpose::URL_SAFE as base64url, Engine};
2use serde::{Serialize, Deserialize};
3use tetratto_shared::hash::hash;
4use super::{Result, Error};
5
6#[derive(Clone, Debug, Serialize, Deserialize)]
7pub struct AuthGrant {
8    /// The ID of the application associated with this grant.
9    pub app: usize,
10    /// The code challenge for PKCE verifiers associated with this grant.
11    ///
12    /// This challenge is *all* that is required to refresh this grant's auth token.
13    /// While there can only be one token at a time, it can be refreshed whenever as long
14    /// as the provided verifier matches that of the challenge.
15    ///
16    /// The challenge should never be changed. To change the challenge, the grant
17    /// should be removed and recreated.
18    pub challenge: String,
19    /// The encoding method for the initial verifier in the challenge.
20    pub method: PkceChallengeMethod,
21    /// The access token associated with the account. This is **not** the same as
22    /// regular account access tokens, as the token can only be used with the requested `scopes`.
23    pub token: String,
24    /// The time in which the token was last refreshed. Tokens should stop being
25    /// accepted after a week has passed since this time.
26    pub last_updated: usize,
27    /// Scopes define what the grant's token is actually allowed to do.
28    ///
29    /// No scope shall ever be allowed to change scopes or manage grants on behalf of the user.
30    /// A regular user token **must** be provided to manage grants.
31    pub scopes: Vec<AppScope>,
32}
33
34#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
35pub enum PkceChallengeMethod {
36    S256,
37}
38
39#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
40pub enum AppScope {
41    /// Read the profile of other users on behalf of the user.
42    UserReadProfiles,
43    /// Read the user's profile (username, bio, etc).
44    UserReadProfile,
45    /// Read the user's settings.
46    UserReadSettings,
47    /// Read the user's sessions and info.
48    UserReadSessions,
49    /// Read posts as the user.
50    UserReadPosts,
51    /// Read messages as the user.
52    UserReadMessages,
53    /// Read drafts as the user.
54    UserReadDrafts,
55    /// Read the user's communities.
56    UserReadCommunities,
57    /// Connect to sockets on the user's behalf.
58    UserReadSockets,
59    /// Read the user's notifications.
60    UserReadNotifications,
61    /// Read the user's requests.
62    UserReadRequests,
63    /// Read questions as the user.
64    UserReadQuestions,
65    /// Read the user's stacks.
66    UserReadStacks,
67    /// Read the user's layouts.
68    UserReadLayouts,
69    /// Read the user's domains.
70    UserReadDomains,
71    /// Read the user's services.
72    UserReadServices,
73    /// Read the user's letters.
74    UserReadLetters,
75    /// Read the user's products.
76    UserReadProducts,
77    /// Read guest logs as the user.
78    UserReadGuestLogs,
79    /// Create posts as the user.
80    UserCreatePosts,
81    /// Create messages as the user.
82    UserCreateMessages,
83    /// Ask questions as the user.
84    UserCreateQuestions,
85    /// Create IP blocks as the user.
86    UserCreateIpBlock,
87    /// Create drafts on behalf of the user.
88    UserCreateDrafts,
89    /// Create communities on behalf of the user.
90    UserCreateCommunities,
91    /// Create stacks on behalf of the user.
92    UserCreateStacks,
93    /// Create layouts on behalf of the user.
94    UserCreateLayouts,
95    /// Create domains on behalf of the user.
96    UserCreateDomains,
97    /// Create services on behalf of the user.
98    UserCreateServices,
99    /// Create letters on behalf of the user.
100    UserCreateLetters,
101    /// Delete posts owned by the user.
102    UserDeletePosts,
103    /// Delete messages owned by the user.
104    UserDeleteMessages,
105    /// Delete questions as the user.
106    UserDeleteQuestions,
107    /// Delete drafts as the user.
108    UserDeleteDrafts,
109    /// Edit the user's settings and upload avatars/banners on behalf of the user.
110    UserManageProfile,
111    /// Manage stacks owned by the user.
112    UserManageStacks,
113    /// Manage the user's following/unfollowing.
114    UserManageRelationships,
115    /// Manage the user's community memberships.
116    ///
117    /// Also includes managing the membership of users in the user's communities.
118    UserManageMemberships,
119    /// Follow/unfollow users on behalf of the user.
120    UserManageFollowing,
121    /// Accept follow requests on behalf of the user.
122    UserManageFollowers,
123    /// Block/unblock users on behalf of the user.
124    UserManageBlocks,
125    /// Manage the user's notifications.
126    UserManageNotifications,
127    /// Manage the user's requests.
128    UserManageRequests,
129    /// Manage the user's uploads.
130    UserManageUploads,
131    /// Manage the user's layouts.
132    UserManageLayouts,
133    /// Manage the user's domains.
134    UserManageDomains,
135    /// Manage the user's services.
136    UserManageServices,
137    /// Manage the user's channel mutes.
138    UserManageChannelMutes,
139    /// Manage the user's letters.
140    UserManageLetters,
141    /// Manage the user's guest logs.
142    UserManageGuestLogs,
143    /// Edit posts created by the user.
144    UserEditPosts,
145    /// Edit drafts created by the user.
146    UserEditDrafts,
147    /// Vote in polls as the user.
148    UserVote,
149    /// React to posts on behalf of the user. Also allows the removal of reactions.
150    UserReact,
151    /// Join communities on behalf of the user.
152    UserJoinCommunities,
153    /// Permanently delete posts.
154    ModPurgePosts,
155    /// Restore deleted posts.
156    ModDeletePosts,
157    /// Manage user warnings.
158    ModManageWarnings,
159    /// Get a list of all emojis available to the user.
160    UserReadEmojis,
161    /// Create emojis on behalf of the user.
162    CommunityCreateEmojis,
163    /// Manage emojis on behalf of the user.
164    CommunityManageEmojis,
165    /// Delete communities on behalf of the user.
166    CommunityDelete,
167    /// Manage communities on behalf of the user.
168    CommunityManage,
169    /// Transfer ownership of communities on behalf of the user.
170    CommunityTransferOwnership,
171    /// Read the membership of users in communities owned by the current user.
172    CommunityReadMemberships,
173    /// Create channels in the user's communities.
174    CommunityCreateChannels,
175    /// Manage channels in the user's communities.
176    CommunityManageChannels,
177}
178
179impl AuthGrant {
180    /// Check a verifier against the stored challenge (using the given [`PkceChallengeMethod`]).
181    pub fn check_verifier(&self, verifier: &str) -> Result<()> {
182        if self.method != PkceChallengeMethod::S256 {
183            return Err(Error::MiscError("only S256 is supported".to_string()));
184        }
185
186        let decoded = match base64url.decode(self.challenge.as_bytes()) {
187            Ok(hash) => hash,
188            Err(e) => return Err(Error::MiscError(e.to_string())),
189        };
190
191        let hash = hash(verifier.to_string());
192
193        if hash.as_bytes() != decoded {
194            // the verifier we received does not match the verifier from the stored challenge
195            return Err(Error::NotAllowed);
196        }
197
198        Ok(())
199    }
200}