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 journals.
68    UserReadJournals,
69    /// Read the user's notes.
70    UserReadNotes,
71    /// Read the user's layouts.
72    UserReadLayouts,
73    /// Read the user's domains.
74    UserReadDomains,
75    /// Read the user's services.
76    UserReadServices,
77    /// Read the user's letters.
78    UserReadLetters,
79    /// Read the user's products.
80    UserReadProducts,
81    /// Create posts as the user.
82    UserCreatePosts,
83    /// Create messages as the user.
84    UserCreateMessages,
85    /// Ask questions as the user.
86    UserCreateQuestions,
87    /// Create IP blocks as the user.
88    UserCreateIpBlock,
89    /// Create drafts on behalf of the user.
90    UserCreateDrafts,
91    /// Create communities on behalf of the user.
92    UserCreateCommunities,
93    /// Create stacks on behalf of the user.
94    UserCreateStacks,
95    /// Create journals on behalf of the user.
96    UserCreateJournals,
97    /// Create notes on behalf of the user.
98    UserCreateNotes,
99    /// Create layouts on behalf of the user.
100    UserCreateLayouts,
101    /// Create domains on behalf of the user.
102    UserCreateDomains,
103    /// Create services on behalf of the user.
104    UserCreateServices,
105    /// Create letters on behalf of the user.
106    UserCreateLetters,
107    /// Create products on behalf of the user.
108    UserCreateProducts,
109    /// Send coins on behalf of the user.
110    UserSendCoins,
111    /// Delete posts owned by the user.
112    UserDeletePosts,
113    /// Delete messages owned by the user.
114    UserDeleteMessages,
115    /// Delete questions as the user.
116    UserDeleteQuestions,
117    /// Delete drafts as the user.
118    UserDeleteDrafts,
119    /// Edit the user's settings and upload avatars/banners on behalf of the user.
120    UserManageProfile,
121    /// Manage stacks owned by the user.
122    UserManageStacks,
123    /// Manage the user's following/unfollowing.
124    UserManageRelationships,
125    /// Manage the user's community memberships.
126    ///
127    /// Also includes managing the membership of users in the user's communities.
128    UserManageMemberships,
129    /// Follow/unfollow users on behalf of the user.
130    UserManageFollowing,
131    /// Accept follow requests on behalf of the user.
132    UserManageFollowers,
133    /// Block/unblock users on behalf of the user.
134    UserManageBlocks,
135    /// Manage the user's notifications.
136    UserManageNotifications,
137    /// Manage the user's requests.
138    UserManageRequests,
139    /// Manage the user's uploads.
140    UserManageUploads,
141    /// Manage the user's journals.
142    UserManageJournals,
143    /// Manage the user's notes.
144    UserManageNotes,
145    /// Manage the user's layouts.
146    UserManageLayouts,
147    /// Manage the user's domains.
148    UserManageDomains,
149    /// Manage the user's services.
150    UserManageServices,
151    /// Manage the user's channel mutes.
152    UserManageChannelMutes,
153    /// Manage the user's letters.
154    UserManageLetters,
155    /// Manage the user's products.
156    UserManageProducts,
157    /// Edit posts created by the user.
158    UserEditPosts,
159    /// Edit drafts created by the user.
160    UserEditDrafts,
161    /// Vote in polls as the user.
162    UserVote,
163    /// React to posts on behalf of the user. Also allows the removal of reactions.
164    UserReact,
165    /// Join communities on behalf of the user.
166    UserJoinCommunities,
167    /// Permanently delete posts.
168    ModPurgePosts,
169    /// Restore deleted posts.
170    ModDeletePosts,
171    /// Manage user warnings.
172    ModManageWarnings,
173    /// Get a list of all emojis available to the user.
174    UserReadEmojis,
175    /// Create emojis on behalf of the user.
176    CommunityCreateEmojis,
177    /// Manage emojis on behalf of the user.
178    CommunityManageEmojis,
179    /// Delete communities on behalf of the user.
180    CommunityDelete,
181    /// Manage communities on behalf of the user.
182    CommunityManage,
183    /// Transfer ownership of communities on behalf of the user.
184    CommunityTransferOwnership,
185    /// Read the membership of users in communities owned by the current user.
186    CommunityReadMemberships,
187    /// Create channels in the user's communities.
188    CommunityCreateChannels,
189    /// Manage channels in the user's communities.
190    CommunityManageChannels,
191}
192
193impl AuthGrant {
194    /// Check a verifier against the stored challenge (using the given [`PkceChallengeMethod`]).
195    pub fn check_verifier(&self, verifier: &str) -> Result<()> {
196        if self.method != PkceChallengeMethod::S256 {
197            return Err(Error::MiscError("only S256 is supported".to_string()));
198        }
199
200        let decoded = match base64url.decode(self.challenge.as_bytes()) {
201            Ok(hash) => hash,
202            Err(e) => return Err(Error::MiscError(e.to_string())),
203        };
204
205        let hash = hash(verifier.to_string());
206
207        if hash.as_bytes() != decoded {
208            // the verifier we received does not match the verifier from the stored challenge
209            return Err(Error::NotAllowed);
210        }
211
212        Ok(())
213    }
214}