nsarrazin HF Staff commited on
Commit
0ab6df0
·
unverified ·
1 Parent(s): 587f3d3

feat(auth): Add admin & early access flags based on orgs membership (#1365)

Browse files
.env CHANGED
@@ -164,3 +164,6 @@ METRICS_ENABLED=false
164
  METRICS_PORT=5565
165
  LOG_LEVEL=info
166
  BODY_SIZE_LIMIT=15728640
 
 
 
 
164
  METRICS_PORT=5565
165
  LOG_LEVEL=info
166
  BODY_SIZE_LIMIT=15728640
167
+
168
+ HF_ORG_ADMIN=
169
+ HF_ORG_EARLY_ACCESS=
chart/env/prod.yaml CHANGED
@@ -328,6 +328,8 @@ envVars:
328
  }]
329
  WEBSEARCH_BLOCKLIST: '["youtube.com", "twitter.com"]'
330
  XFF_DEPTH: '2'
 
 
331
 
332
  infisical:
333
  enabled: true
 
328
  }]
329
  WEBSEARCH_BLOCKLIST: '["youtube.com", "twitter.com"]'
330
  XFF_DEPTH: '2'
331
+ HF_ORG_ADMIN: '644171cfbd0c97265298aa99'
332
+ HF_ORG_EARLY_ACCESS: '5e67bd5b1009063689407478'
333
 
334
  infisical:
335
  enabled: true
src/lib/types/User.ts CHANGED
@@ -10,4 +10,5 @@ export interface User extends Timestamps {
10
  avatarUrl: string | undefined;
11
  hfUserId: string;
12
  isAdmin?: boolean;
 
13
  }
 
10
  avatarUrl: string | undefined;
11
  hfUserId: string;
12
  isAdmin?: boolean;
13
+ isEarlyAccess?: boolean;
14
  }
src/routes/+layout.server.ts CHANGED
@@ -197,6 +197,7 @@ export const load: LayoutServerLoad = async ({ locals, depends }) => {
197
  email: locals.user.email,
198
  logoutDisabled: locals.user.logoutDisabled,
199
  isAdmin: locals.user.isAdmin ?? false,
 
200
  },
201
  assistant,
202
  enableAssistants,
 
197
  email: locals.user.email,
198
  logoutDisabled: locals.user.logoutDisabled,
199
  isAdmin: locals.user.isAdmin ?? false,
200
+ isEarlyAccess: locals.user.isEarlyAccess ?? false,
201
  },
202
  assistant,
203
  enableAssistants,
src/routes/login/callback/updateUser.ts CHANGED
@@ -9,6 +9,7 @@ import crypto from "crypto";
9
  import { sha256 } from "$lib/utils/sha256";
10
  import { addWeeks } from "date-fns";
11
  import { OIDConfig } from "$lib/server/auth";
 
12
 
13
  export async function updateUser(params: {
14
  userData: UserinfoResponse;
@@ -31,6 +32,7 @@ export async function updateUser(params: {
31
  email,
32
  picture: avatarUrl,
33
  sub: hfUserId,
 
34
  } = z
35
  .object({
36
  preferred_username: z.string().optional(),
@@ -38,6 +40,17 @@ export async function updateUser(params: {
38
  picture: z.string().optional(),
39
  sub: z.string(),
40
  email: z.string().email().optional(),
 
 
 
 
 
 
 
 
 
 
 
41
  })
42
  .setKey(OIDConfig.NAME_CLAIM, z.string())
43
  .refine((data) => data.preferred_username || data.email, {
@@ -53,11 +66,23 @@ export async function updateUser(params: {
53
  picture?: string;
54
  sub: string;
55
  name: string;
 
 
 
 
 
 
 
56
  } & Record<string, string>;
57
 
58
  // Dynamically access user data based on NAME_CLAIM from environment
59
  // This approach allows us to adapt to different OIDC providers flexibly.
60
 
 
 
 
 
 
61
  // check if user already exists
62
  const existingUser = await collections.users.findOne({ hfUserId });
63
  let userId = existingUser?._id;
@@ -77,7 +102,7 @@ export async function updateUser(params: {
77
  // update existing user if any
78
  await collections.users.updateOne(
79
  { _id: existingUser._id },
80
- { $set: { username, name, avatarUrl } }
81
  );
82
 
83
  // remove previous session if it exists and add new one
@@ -103,6 +128,8 @@ export async function updateUser(params: {
103
  email,
104
  avatarUrl,
105
  hfUserId,
 
 
106
  });
107
 
108
  userId = insertedId;
 
9
  import { sha256 } from "$lib/utils/sha256";
10
  import { addWeeks } from "date-fns";
11
  import { OIDConfig } from "$lib/server/auth";
12
+ import { HF_ORG_ADMIN, HF_ORG_EARLY_ACCESS } from "$env/static/private";
13
 
14
  export async function updateUser(params: {
15
  userData: UserinfoResponse;
 
32
  email,
33
  picture: avatarUrl,
34
  sub: hfUserId,
35
+ orgs,
36
  } = z
37
  .object({
38
  preferred_username: z.string().optional(),
 
40
  picture: z.string().optional(),
41
  sub: z.string(),
42
  email: z.string().email().optional(),
43
+ orgs: z
44
+ .array(
45
+ z.object({
46
+ sub: z.string(),
47
+ name: z.string(),
48
+ picture: z.string(),
49
+ preferred_username: z.string(),
50
+ isEnterprise: z.boolean(),
51
+ })
52
+ )
53
+ .optional(),
54
  })
55
  .setKey(OIDConfig.NAME_CLAIM, z.string())
56
  .refine((data) => data.preferred_username || data.email, {
 
66
  picture?: string;
67
  sub: string;
68
  name: string;
69
+ orgs?: Array<{
70
+ sub: string;
71
+ name: string;
72
+ picture: string;
73
+ preferred_username: string;
74
+ isEnterprise: boolean;
75
+ }>;
76
  } & Record<string, string>;
77
 
78
  // Dynamically access user data based on NAME_CLAIM from environment
79
  // This approach allows us to adapt to different OIDC providers flexibly.
80
 
81
+ // if using huggingface as auth provider, check orgs for earl access and amin rights
82
+ const isAdmin = (HF_ORG_ADMIN && orgs?.some((org) => org.sub === HF_ORG_ADMIN)) || false;
83
+ const isEarlyAccess =
84
+ (HF_ORG_EARLY_ACCESS && orgs?.some((org) => org.sub === HF_ORG_EARLY_ACCESS)) || false;
85
+
86
  // check if user already exists
87
  const existingUser = await collections.users.findOne({ hfUserId });
88
  let userId = existingUser?._id;
 
102
  // update existing user if any
103
  await collections.users.updateOne(
104
  { _id: existingUser._id },
105
+ { $set: { username, name, avatarUrl, isAdmin, isEarlyAccess } }
106
  );
107
 
108
  // remove previous session if it exists and add new one
 
128
  email,
129
  avatarUrl,
130
  hfUserId,
131
+ isAdmin,
132
+ isEarlyAccess,
133
  });
134
 
135
  userId = insertedId;