mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: fix PERM_VIEW_DISPLAYNAME
This commit is contained in:
3 files changed
+54
-8
No files matched your search
@@ -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);
|
||||||
|
|||||||
@@ -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'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user