/ opencodehub / src / lib / permissions.ts
swadhinbiswas Initial commit of OpenCodeHub source · 12/11/2025
1110042
77 lines · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { getDatabase } from "@/db";
import type { Repository } from "@/db/schema";
import { repositoryCollaborators } from "@/db/schema";
import { and, eq } from "drizzle-orm";

export type PermissionLevel = "admin" | "write" | "read" | "none";

export async function getRepoPermission(
  userId: string | undefined,
  repo: Repository
): Promise<PermissionLevel> {
  // Public repos are readable by everyone
  if (repo.visibility === "public") {
    if (!userId) return "read";
  } else {
    // Private repos are not readable by anonymous users
    if (!userId) return "none";
  }

  // Owner has full access
  if (userId && repo.ownerId === userId) {
    return "admin";
  }

  if (!userId) return "none";

  const db = getDatabase();

  // Check collaborator status
  const collaborator = await db.query.repositoryCollaborators.findFirst({
    where: and(
      eq(repositoryCollaborators.repositoryId, repo.id),
      eq(repositoryCollaborators.userId, userId)
    ),
  });

  if (!collaborator) {
    return repo.visibility === "public" ? "read" : "none";
  }

  switch (collaborator.role) {
    case "owner":
    case "maintainer":
      return "admin";
    case "developer":
      return "write";
    case "guest":
      return "read";
    default:
      return "read";
  }
}

export async function canReadRepo(
  userId: string | undefined,
  repo: Repository
): Promise<boolean> {
  const permission = await getRepoPermission(userId, repo);
  return permission !== "none";
}

export async function canWriteRepo(
  userId: string | undefined,
  repo: Repository
): Promise<boolean> {
  const permission = await getRepoPermission(userId, repo);
  return permission === "write" || permission === "admin";
}

export async function canAdminRepo(
  userId: string | undefined,
  repo: Repository
): Promise<boolean> {
  const permission = await getRepoPermission(userId, repo);
  return permission === "admin";
}