core: fix PERM_VIEW_DISPLAYNAME

This commit is contained in:
undefined committed 2024-05-12 17:33:23 +08:00
1 parent 597ec6f202
commit 19fd8b13ab
3 files changed
+54 -8

No files matched your search

+52 -6
View File
@@ -1,8 +1,10 @@
import { makeExecutableSchema } from '@graphql-tools/schema'; import { makeExecutableSchema } from '@graphql-tools/schema';
import { graphql, GraphQLSchema } from 'graphql'; import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
import { defaultFieldResolver, graphql, GraphQLSchema } from 'graphql';
import { resolvers, typeDefs } from 'graphql-scalars'; import { resolvers, typeDefs } from 'graphql-scalars';
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import { Context as PluginContext } from '../context'; import { Context as PluginContext } from '../context';
import { PERM, PRIV } from '../model/builtin';
import * as bus from '../service/bus'; import * as bus from '../service/bus';
import { Handler } from '../service/server'; import { Handler } from '../service/server';
@@ -42,13 +44,18 @@ export function registerResolver(
const wrappedFunc = async (arg, ctx, info) => { const wrappedFunc = async (arg, ctx, info) => {
const res = await func(arg, ctx, info); const res = await func(arg, ctx, info);
if (typeof res !== 'object' || res === null) return res; if (typeof res !== 'object' || res === null) return res;
const node = value.includes('!') ? value.split('!')[0] : value; let node = value.includes('!') ? value.split('!')[0] : value;
if (handlers[node]) Object.assign(res, handlers[node]); const isArray = node.includes('[');
node = node.replace('[', '').replace(']', '');
if (handlers[node]) {
if (!isArray) Object.assign(res, handlers[node]);
else if (res instanceof Array) for (const i of res) { Object.assign(i, handlers[node]); }
}
ctx.parent = res; ctx.parent = res;
return res; return res;
}; };
if (handlers[typeName]) handlers[typeName][key.split('(')[0].trim()] = wrappedFunc; handlers[typeName] ||= {};
else handlers[typeName] = { [key.split('(')[0].trim()]: wrappedFunc }; handlers[typeName][key.split('(')[0].trim()] = wrappedFunc;
bus.emit('api/update'); bus.emit('api/update');
} }
@@ -66,15 +73,53 @@ let schema: GraphQLSchema;
let schemaStr = ''; let schemaStr = '';
root = handlers.Query; root = handlers.Query;
const applyAuthDirective = (s) => mapSchema(s, {
// eslint-disable-next-line consistent-return
[MapperKind.OBJECT_FIELD]: (fieldConfig) => {
const authDirective = getDirective(s, fieldConfig, 'auth')?.[0];
if (authDirective) {
const { resolve = defaultFieldResolver } = fieldConfig;
return {
...fieldConfig,
async resolve(source, args, context, info) {
if (authDirective.perm) {
const perm = PERM[authDirective.perm];
if (!context.user.hasPerm(perm)) throw new Error(`Permission denied: ${authDirective.perm}`);
}
if (authDirective.priv) {
const priv = PRIV[authDirective.priv];
if (!context.user.hasPriv(priv)) throw new Error(`Permission denied: ${authDirective.priv}`);
}
return await resolve(source, args, context, info);
},
};
}
const ifDirective = getDirective(s, fieldConfig, 'if')?.[0];
if (ifDirective) {
const { resolve = defaultFieldResolver } = fieldConfig;
return {
...fieldConfig,
async resolve(source, args, context, info) {
if (ifDirective.perm && !context.user.hasPerm(PERM[ifDirective.perm])) return null;
if (ifDirective.priv && !context.user.hasPriv(PRIV[ifDirective.priv])) return null;
return await resolve(source, args, context, info);
},
};
}
},
});
export function rebuild() { export function rebuild() {
try { try {
const defs = [ const defs = [
...Object.keys(unions).map((i) => `union ${i} = ${unions[i]}`), ...Object.keys(unions).map((i) => `union ${i} = ${unions[i]}`),
'directive @auth(perm: String, priv: String) on FIELD_DEFINITION',
'directive @if(perm: String, priv: String) on FIELD_DEFINITION',
...typeDefs, ...typeDefs,
...Object.keys(types).map((key) => { ...Object.keys(types).map((key) => {
let def = ''; let def = '';
if (descriptions[key]?._description) def += `${setDescription(descriptions[key]._description)}\n`; if (descriptions[key]?._description) def += `${setDescription(descriptions[key]._description)}\n`;
def += `type ${key}{\n`; def += `type ${key} {\n`;
for (const k in types[key]) { for (const k in types[key]) {
if (descriptions[key]?.[k]) def += ` ${setDescription(descriptions[key][k])}\n`; if (descriptions[key]?.[k]) def += ` ${setDescription(descriptions[key][k])}\n`;
def += ` ${k}: ${types[key][k]}\n`; def += ` ${k}: ${types[key][k]}\n`;
@@ -87,6 +132,7 @@ export function rebuild() {
typeDefs: defs, typeDefs: defs,
resolvers, resolvers,
}); });
schema = applyAuthDirective(schema);
schemaStr = defs.join('\n'); schemaStr = defs.join('\n');
} catch (e) { } catch (e) {
console.error(e); console.error(e);
+1 -1
View File
@@ -40,7 +40,7 @@ registerValue('User', [
['avatarUrl', 'String'], ['avatarUrl', 'String'],
['tfa', 'Boolean!'], ['tfa', 'Boolean!'],
['authn', 'Boolean!'], ['authn', 'Boolean!'],
['displayName', 'String'], ['displayName', 'String @if(perm: "PERM_VIEW_DISPLAYNAME")'],
['rpInfo', 'JSONObject'], ['rpInfo', 'JSONObject'],
]); ]);
+1 -1
View File
@@ -232,7 +232,7 @@ export default class RecordModel {
judger: null, judger: null,
}; };
if (isRejudge) upd.rejudged = true; if (isRejudge) upd.rejudged = true;
await RecordModel.collStat.deleteOne(rid instanceof Array ? { _id: { $in: rid } } : { _id: rid }); await RecordModel.collStat.deleteMany(rid instanceof Array ? { _id: { $in: rid } } : { _id: rid });
await task.deleteMany(rid instanceof Array ? { rid: { $in: rid } } : { rid }); await task.deleteMany(rid instanceof Array ? { rid: { $in: rid } } : { rid });
return RecordModel.update(domainId, rid, upd); return RecordModel.update(domainId, rid, upd);
} }