Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit da6bab0

Browse files
✨ Add authorization for API keys
1 parent 592556b commit da6bab0

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

src/helpers/authorization.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { User } from "../interfaces/tables/user";
1+
import { User, ApiKey } from "../interfaces/tables/user";
22
import { Organization } from "../interfaces/tables/organization";
33
import {
44
ErrorCode,
@@ -148,15 +148,36 @@ const canUserGeneral = async (user: User, action: Authorizations) => {
148148
return false;
149149
};
150150

151+
const canUserApiKey = async (
152+
user: User,
153+
action: Authorizations,
154+
target: ApiKey
155+
) => {
156+
// A user can do anything to her API key
157+
if (target.userId == user.id) return true;
158+
159+
let secureAction = action;
160+
if (action === Authorizations.CREATE)
161+
secureAction = Authorizations.CREATE_SECURE;
162+
if (action === Authorizations.READ) secureAction = Authorizations.READ_SECURE;
163+
if (action === Authorizations.UPDATE)
164+
secureAction = Authorizations.UPDATE_SECURE;
165+
if (action === Authorizations.DELETE)
166+
secureAction = Authorizations.DELETE_SECURE;
167+
168+
const owner = await getUser(target.userId);
169+
return await canUserUser(user, secureAction, owner);
170+
};
171+
151172
/**
152173
* Whether a user has authorization to perform an action
153174
* @param ipAddress IP address for the new location
154175
*/
155176
export const can = async (
156177
user: User | number,
157178
action: Authorizations,
158-
targetType: "user" | "organization" | "membership" | "general",
159-
target?: User | Organization | Membership | number
179+
targetType: "user" | "organization" | "membership" | "api-key" | "general",
180+
target?: User | Organization | Membership | ApiKey | number
160181
) => {
161182
let userObject;
162183
if (typeof user === "number") {
@@ -165,7 +186,10 @@ export const can = async (
165186
userObject = user;
166187
}
167188
let targetObject;
168-
if (typeof target === "string") target = parseInt(target);
189+
if (typeof target === "string") {
190+
let newTarget = parseInt(target);
191+
if (!isNaN(newTarget)) target = newTarget;
192+
}
169193
if (typeof target == "number") {
170194
if (targetType === "user") {
171195
targetObject = await getUser(target);
@@ -188,6 +212,8 @@ export const can = async (
188212
return await canUserMembership(userObject, action, <Membership>(
189213
targetObject
190214
));
215+
} else if (targetType === "api-key") {
216+
return await canUserApiKey(userObject, action, <ApiKey>targetObject);
191217
} else {
192218
return await canUserGeneral(userObject, action);
193219
}

src/rest/user.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -138,12 +138,9 @@ export const getApiKeyForUser = async (
138138
dataUserId: number,
139139
apiKey: string
140140
) => {
141-
if (await can(tokenUserId, Authorizations.READ_SECURE, "user", dataUserId)) {
142-
const apiKeyDetails = await getApiKey(apiKey);
143-
if (apiKeyDetails.userId != dataUserId)
144-
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
141+
const apiKeyDetails = await getApiKey(apiKey);
142+
if (await can(tokenUserId, Authorizations.READ, "api-key", apiKeyDetails))
145143
return apiKeyDetails;
146-
}
147144
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
148145
};
149146

@@ -154,12 +151,8 @@ export const updateApiKeyForUser = async (
154151
data: KeyValue,
155152
locals: Locals
156153
) => {
157-
if (
158-
await can(tokenUserId, Authorizations.UPDATE_SECURE, "user", dataUserId)
159-
) {
160-
const apiKeyDetails = await getApiKey(apiKey);
161-
if (apiKeyDetails.userId != dataUserId)
162-
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
154+
const apiKeyDetails = await getApiKey(apiKey);
155+
if (await can(tokenUserId, Authorizations.UPDATE, "api-key", apiKeyDetails)) {
163156
await updateApiKey(apiKey, data);
164157
await createEvent(
165158
{
@@ -202,12 +195,8 @@ export const deleteApiKeyForUser = async (
202195
apiKey: string,
203196
locals: Locals
204197
) => {
205-
if (
206-
await can(tokenUserId, Authorizations.DELETE_SECURE, "user", dataUserId)
207-
) {
208-
const apiKeyDetails = await getApiKey(apiKey);
209-
if (apiKeyDetails.userId != dataUserId)
210-
throw new Error(ErrorCode.INSUFFICIENT_PERMISSION);
198+
const apiKeyDetails = await getApiKey(apiKey);
199+
if (await can(tokenUserId, Authorizations.DELETE, "api-key", apiKeyDetails)) {
211200
await deleteApiKey(apiKey);
212201
await createEvent(
213202
{

0 commit comments

Comments
 (0)