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}