Advertisement
djbob2000

Untitled

Jan 27th, 2025
12
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.70 KB | None | 0 0
  1. import { FdMemoryCacheOptions } from "@server/fd/fd-toolbox/cachings/fd-memory-cache-options";
  2. import { Permission } from "@/fd/fd-toolbox-web/permissions/permission.resource";
  3. import { PermissionPackageToPermission } from "@/fd/fd-toolbox-web/permissions/permission-package-to-permission.resource";
  4. import { PermissionDto } from "@server/auth/permission-dto";
  5. import {
  6. PermissionLevel,
  7. permissionType,
  8. PermissionType,
  9. } from "@/fd/fd-toolbox-core/auth/permissions/permission-enums";
  10. import { setCoreCache, tryGetObjectFromCoreCache } from "@server/fd/fd-toolbox/cachings/core-memory-cache";
  11. import { fdCacheKeys } from "./constants/fd-cache-keys";
  12. import { addListValueToDictionary, addMapValueToMap } from "@server/fd/fd-toolbox/services/dictionaries";
  13. import { RoleToPermission } from "@server/auth/role-to-permission";
  14. import { getRoleToPermissionPackages } from "./models/roles/role-to-permission-package-db";
  15. import { getPermissionPackageToPermissions } from "./auth/permissions/permission-package-to-permission-db";
  16. import { getAllIncludingUserToRoles } from "@server/auth/role-db";
  17. import {
  18. resourceSchema,
  19. permissionSchema as permissionTable,
  20. roleToPermissionSchema,
  21. } from "@packages/plugin/schema";
  22. import { eq, getTableColumns } from "drizzle-orm";
  23. import { getQuery } from "@server/web/drizzle";
  24. import { UserRole } from "@/users/user-role.resource";
  25. import { getPermissionCacheKey, createShallowPermission } from "./permissions/permissions";
  26. import { parseJson } from "@/lib/utils";
  27.  
  28. export async function getUserRoleIdsToRoleLevels() {
  29. const roles = await getAllIncludingUserToRoles();
  30.  
  31. const userRoleIdsLevels = new Map<string, Map<string, PermissionLevel>>();
  32.  
  33. for (const roleItem of roles) {
  34. if (roleItem.userRoleList) {
  35. for (const userRoleItem of roleItem.userRoleList.filter(
  36. (ur: UserRole) => ur.roleId === roleItem.id,
  37. )) {
  38. addMapValueToMap(userRoleIdsLevels, userRoleItem.userId, userRoleItem.roleId, roleItem.level);
  39. }
  40. }
  41. }
  42.  
  43. return userRoleIdsLevels;
  44. }
  45.  
  46. export async function saveRoleToPermissionsToCache(
  47. rolePackageToPermissions: Map<string, string[]>,
  48. ids: string[],
  49. type: PermissionType,
  50. ) {
  51. let cacheKeyPrefix: string = fdCacheKeys.roleToDefaultPermissions;
  52.  
  53. if (type === permissionType.resource) {
  54. cacheKeyPrefix = fdCacheKeys.roleToResourcePermissions;
  55. } else if (type === permissionType.property) {
  56. cacheKeyPrefix = fdCacheKeys.roleToPropertyPermissions;
  57. }
  58.  
  59. for (const id of ids) {
  60. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  61.  
  62. if (!rolePackageToPermissions.has(id)) {
  63. await saveRoleToPermissionsToCacheById(id);
  64. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  65. }
  66. }
  67.  
  68. return rolePackageToPermissions;
  69. }
  70.  
  71. export async function getRoleToPermissionList() {
  72. return getQuery(roleToPermissionSchema);
  73. }
  74.  
  75. export async function getUserPermissionCacheKey(type: PermissionType, userId: string) {
  76. return getPermissionCacheKey(type.toString(), userId);
  77. }
  78.  
  79. export async function getUserResourcePermissionCacheKey(
  80. type: PermissionType,
  81. resourceName: string,
  82. userId: string,
  83. ) {
  84. const resourceKey = await getPermissionCacheKey(type.toString(), resourceName);
  85. return getPermissionCacheKey(resourceKey, userId);
  86. }
  87.  
  88. export async function saveUserPermissionsToMemoryCache(
  89. userPermissionKey: string,
  90. type: PermissionType,
  91. userPermissions: Map<string, PermissionDto>,
  92. ) {
  93. const cacheKey = await getUserPermissionCacheKey(type, userPermissionKey);
  94. await saveToMemoryCache(cacheKey, userPermissions);
  95. }
  96.  
  97. export async function getUserRoleIdsToRolePermissionLevels(userId: string) {
  98. const roleIdsLevels = new Map<string, PermissionLevel>();
  99. const memoryCacheKey = await getPermissionCacheKey(fdCacheKeys.userRolePermissionLevels, userId);
  100.  
  101. const cachedUserRoleIdsLevels = tryGetObjectFromCoreCache<Map<string, PermissionLevel>>(memoryCacheKey);
  102.  
  103. if (cachedUserRoleIdsLevels) {
  104. return cachedUserRoleIdsLevels;
  105. } else {
  106. await saveUserRoleIdsToRolePermissionLevelsToCache();
  107. const rolesToLevels = tryGetObjectFromCoreCache<Map<string, PermissionLevel>>(memoryCacheKey);
  108. if (rolesToLevels) {
  109. return rolesToLevels;
  110. }
  111. }
  112.  
  113. return roleIdsLevels;
  114. }
  115.  
  116. export async function savePackageToPermissionsToCache(
  117. rolePackageToPermissions: Map<string, string[]>,
  118. ids: string[],
  119. type: PermissionType,
  120. ) {
  121. let cacheKeyPrefix;
  122.  
  123. switch (type) {
  124. case permissionType.resource:
  125. cacheKeyPrefix = fdCacheKeys.packagesToResourcePermissions;
  126. break;
  127. case permissionType.property:
  128. cacheKeyPrefix = fdCacheKeys.packagesToPropertyPermissions;
  129. break;
  130. default:
  131. cacheKeyPrefix = fdCacheKeys.packagesToDefaultPermissions;
  132. }
  133.  
  134. for (const id of ids) {
  135. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  136. if (!rolePackageToPermissions.has(id)) {
  137. await privateSavePackageToPermissionsToCache(id);
  138.  
  139. await addMapFromCache(rolePackageToPermissions, id, cacheKeyPrefix);
  140. }
  141. }
  142.  
  143. return rolePackageToPermissions;
  144. }
  145.  
  146. export async function getPermission(id: string) {
  147. const cacheKey = await getPermissionCacheKey(fdCacheKeys.permission, id);
  148. let permission = tryGetObjectFromCoreCache<Permission>(cacheKey);
  149.  
  150. if (permission) {
  151. return createShallowPermission(permission);
  152. } else {
  153. await savePermissionsToCache();
  154. permission = tryGetObjectFromCoreCache(cacheKey);
  155.  
  156. return permission && createShallowPermission(permission);
  157. }
  158. }
  159.  
  160. export async function addPackageToPermissions(
  161. rolesToPermissions: Map<string, string[]>,
  162. packageToPermissionList: PermissionPackageToPermission[],
  163. type: PermissionType,
  164. ) {
  165. for (const packageToPermission of packageToPermissionList) {
  166. const permission = await getPermission(packageToPermission.permissionId);
  167. if (permission?.type === type) {
  168. addListValueToDictionary(
  169. rolesToPermissions,
  170. packageToPermission.permissionPackageId,
  171. packageToPermission.permissionId,
  172. );
  173. }
  174. }
  175. }
  176.  
  177. export async function savePermissionsToCache() {
  178. const query = getQuery(permissionTable, {
  179. ...getTableColumns(permissionTable),
  180. resource: getTableColumns(resourceSchema),
  181. });
  182.  
  183. const permissions = await query.leftJoin(
  184. resourceSchema,
  185. eq(permissionTable.resourceId, resourceSchema.id),
  186. );
  187.  
  188. const permissionCachePromises = permissions.map(async (rawPermission) => {
  189. const permission = createShallowPermission({
  190. ...parseJson<Permission>(rawPermission),
  191. resourceId: rawPermission.resourceId ?? undefined,
  192. resourcePropertyId: rawPermission.resourcePropertyId ?? undefined,
  193. name: rawPermission.name ?? undefined,
  194. action: rawPermission.action ?? undefined,
  195. resource: rawPermission.resource ?? undefined,
  196. });
  197.  
  198. const cacheKey = await getPermissionCacheKey(fdCacheKeys.permission, permission.id);
  199. return saveToMemoryCache(cacheKey, permission);
  200. });
  201.  
  202. await Promise.all(permissionCachePromises);
  203. }
  204.  
  205. export async function getRoleToPackages(ids: string[]) {
  206. const roleToPackages = new Map<string, string[]>();
  207.  
  208. for (const id of ids) {
  209. await addMapFromCache(roleToPackages, id, fdCacheKeys.roleToPackages);
  210. if (!roleToPackages.has(id)) {
  211. await saveRoleToPermissionPackagesToCache();
  212.  
  213. await addMapFromCache(roleToPackages, id, fdCacheKeys.roleToPackages);
  214. }
  215. }
  216.  
  217. return roleToPackages;
  218. }
  219.  
  220. async function addMapFromCache<T>(map: Map<string, T[]>, id: string, cacheKeyPrefix: string) {
  221. const memoryCacheKey = await getPermissionCacheKey(cacheKeyPrefix, id);
  222. const cachedValue = tryGetObjectFromCoreCache<T[]>(memoryCacheKey);
  223. if (cachedValue) {
  224. map.set(id, cachedValue);
  225. }
  226. }
  227.  
  228. async function saveRoleToPermissionsToCacheById(id: string) {
  229. const rolesToResourcePermissions: Map<string, string[]> = new Map();
  230. const rolesToDefaultPermissions: Map<string, string[]> = new Map();
  231. const rolesToPropertyPermissions: Map<string, string[]> = new Map();
  232.  
  233. const roleToPermissionList = await getRoleToPermissionList();
  234. let roleIds = [id, ...roleToPermissionList.map((x) => x.roleId)];
  235. roleIds = [...new Set(roleIds)];
  236.  
  237. await addRoleToPermissions(rolesToResourcePermissions, roleToPermissionList, permissionType.resource);
  238. await addRoleToPermissions(rolesToDefaultPermissions, roleToPermissionList, permissionType.default);
  239. await addRoleToPermissions(rolesToPropertyPermissions, roleToPermissionList, permissionType.property);
  240.  
  241. await saveToMemoryCacheByCacheKeyPrefix(
  242. rolesToResourcePermissions,
  243. fdCacheKeys.roleToResourcePermissions,
  244. );
  245. await saveToMemoryCacheByCacheKeyPrefix(rolesToDefaultPermissions, fdCacheKeys.roleToDefaultPermissions);
  246. await saveToMemoryCacheByCacheKeyPrefix(
  247. rolesToPropertyPermissions,
  248. fdCacheKeys.roleToPropertyPermissions,
  249. );
  250. }
  251.  
  252. async function addRoleToPermissions(
  253. rolesToPermissions: Map<string, string[]>,
  254. roleToPermissionList: RoleToPermission[],
  255. type: PermissionType,
  256. ) {
  257. for (const roleToPermissionItem of roleToPermissionList) {
  258. const permission = await getPermission(roleToPermissionItem.permissionId);
  259. if (permission?.type === type) {
  260. addListValueToDictionary(
  261. rolesToPermissions,
  262. roleToPermissionItem.roleId,
  263. roleToPermissionItem.permissionId,
  264. );
  265. }
  266. }
  267. }
  268.  
  269. async function applyPermissionsToPackages(
  270. permissionMap: Map<string, string[]>,
  271. permissionList: PermissionPackageToPermission[],
  272. permissionTypeParam: PermissionType,
  273. packageIds: string[],
  274. ) {
  275. await addPackageToPermissions(permissionMap, permissionList, permissionTypeParam);
  276.  
  277. if (permissionMap.size === 0) {
  278. for (const packId of packageIds) {
  279. permissionMap.set(packId, []);
  280. }
  281. }
  282. }
  283.  
  284. async function privateSavePackageToPermissionsToCache(id: string) {
  285. const packagesToResourcePermissions = new Map<string, string[]>();
  286. const packagesToDefaultPermissions = new Map<string, string[]>();
  287. const packagesToPropertyPermissions = new Map<string, string[]>();
  288.  
  289. const packageToPermissionList = await getPermissionPackageToPermissions();
  290.  
  291. let permissionPackageIds = [id];
  292.  
  293. permissionPackageIds = permissionPackageIds.concat(
  294. packageToPermissionList.map((x) => x.permissionPackageId),
  295. );
  296. permissionPackageIds = Array.from(new Set(permissionPackageIds));
  297.  
  298. await applyPermissionsToPackages(
  299. packagesToResourcePermissions,
  300. packageToPermissionList,
  301. permissionType.resource,
  302. permissionPackageIds,
  303. );
  304.  
  305. await applyPermissionsToPackages(
  306. packagesToDefaultPermissions,
  307. packageToPermissionList,
  308. permissionType.default,
  309. permissionPackageIds,
  310. );
  311.  
  312. await applyPermissionsToPackages(
  313. packagesToPropertyPermissions,
  314. packageToPermissionList,
  315. permissionType.property,
  316. permissionPackageIds,
  317. );
  318.  
  319. await saveToMemoryCacheByCacheKeyPrefix(
  320. packagesToResourcePermissions,
  321. fdCacheKeys.packagesToResourcePermissions,
  322. );
  323. await saveToMemoryCacheByCacheKeyPrefix(
  324. packagesToDefaultPermissions,
  325. fdCacheKeys.packagesToDefaultPermissions,
  326. );
  327. await saveToMemoryCacheByCacheKeyPrefix(
  328. packagesToPropertyPermissions,
  329. fdCacheKeys.packagesToPropertyPermissions,
  330. );
  331. }
  332.  
  333. async function saveRoleToPermissionPackagesToCache() {
  334. const rolesToPackages = new Map<string, string[]>();
  335.  
  336. const roleToPermissionPackageList = await getRoleToPermissionPackages();
  337.  
  338. for (const roleToPermissionPackage of roleToPermissionPackageList) {
  339. addListValueToDictionary(
  340. rolesToPackages,
  341. roleToPermissionPackage.roleId,
  342. roleToPermissionPackage.permissionPackageId,
  343. );
  344. }
  345.  
  346. await saveToMemoryCacheByCacheKeyPrefix(rolesToPackages, fdCacheKeys.roleToPackages);
  347. }
  348.  
  349. async function saveToMemoryCacheByCacheKeyPrefix(
  350. idsToPermissions: Map<string, string[]>,
  351. cacheKeyPrefix: string,
  352. ) {
  353. const savePromises = Array.from(idsToPermissions.entries()).map(async ([key, value]) => {
  354. const newKey = await getPermissionCacheKey(cacheKeyPrefix, key);
  355. await saveToMemoryCache(newKey, value);
  356. });
  357.  
  358. await Promise.all(savePromises);
  359. }
  360.  
  361. async function saveUserRoleIdsToRolePermissionLevelsToCache() {
  362. const userIdRoleIdsToRolePermissionLevels = await getUserRoleIdsToRoleLevels();
  363.  
  364. const savePromises = Array.from(userIdRoleIdsToRolePermissionLevels.entries()).map(
  365. async ([userId, rolePermissionLevels]) => {
  366. const key = await getPermissionCacheKey(fdCacheKeys.userRolePermissionLevels, userId);
  367. await saveToMemoryCache(key, rolePermissionLevels);
  368. },
  369. );
  370.  
  371. await Promise.all(savePromises);
  372. }
  373.  
  374. async function saveToMemoryCache<T extends object>(key: string, value: T) {
  375. const fdMemoryCacheOptions: FdMemoryCacheOptions = {
  376. absoluteExpirationRelativeToNowSeconds: 24 * fdCacheKeys.secondsInAHour,
  377. };
  378.  
  379. setCoreCache(key, value, fdMemoryCacheOptions);
  380. }
  381.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement