Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there a way to make schema filtering work with external policy? #126

Open
mike-van opened this issue Nov 19, 2023 · 4 comments
Open

Is there a way to make schema filtering work with external policy? #126

mike-van opened this issue Nov 19, 2023 · 4 comments

Comments

@mike-van
Copy link

Hi i'm fairly new to Fastify and Mercurius, I'm trying to setup a graphql api project for 1 of my side project. I saw there's a documentation to filter schema for auth policy directive, n it works great, but for my use case i prefer to use the external auth policy, is there a way to make external policy work for schema filtering, as i might need to expose the graphql playground for potential authenticated users. Here's a minimal snippets of my setup:

const schema = await loadSchema('src/schemas/*.graphql', {
		loaders: [new GraphQLFileLoader()],
	});

const options: MercuriusAuthOptions<any, any, MercuriusContext, TPolicy> = {
	mode: 'external',
	authContext(ctx): TAuthContext {
		const { device, location, role, staff, token, venue } = ctx;
		return { device, location, role, staff, token, venue };
	},
	async applyPolicy(policy, _parent, _args, ctx, _info) {
		const isRolesPolicySatisfied = policy.roles?.length
			? !!(ctx.auth!.role && policy.roles.includes(ctx.auth!.role.type as USER_ROLE))
			: true;
		const isUserRequiredPolicySatisfied = policy.isUserRequired ? !!ctx.auth!.user : true;
		const isVenueRequiredPolicySatisfied = policy.isVenueRequired ? !!ctx.auth!.venue : true;
		const isRoleRequiredPolicySatisfied = policy.isRoleRequired ? !!ctx.auth!.role : true;
		const isLocationRequiredPolicySatisfied = policy.isLocationRequired ? !!ctx.auth!.location : true;
		const isDeviceRequiredPolicySatisfied = policy.isDeviceRequired ? !!ctx.auth!.device : true;

		const areAllConditionsSatisfied =
			isRolesPolicySatisfied &&
			isUserRequiredPolicySatisfied &&
			isVenueRequiredPolicySatisfied &&
			isRoleRequiredPolicySatisfied &&
			isLocationRequiredPolicySatisfied &&
			isDeviceRequiredPolicySatisfied;

		return areAllConditionsSatisfied;
	},
	policy: {
		// TODO: Add more policies
		Query: {
			getCurrentMenu: {
				isVenueRequired: true,
			},
		},
		Mutation: {},
		Subscription: {},
		Location: {
			current_orders: {
				roles: AUTHENTICATED_ROLES,
			},
			venue: {
				roles: AUTHENTICATED_ROLES,
			},
		},
		Menu: {
			posCategories: {
				roles: AUTHENTICATED_ROLES,
			},
		},
		Category: {
			posItems: {
				roles: AUTHENTICATED_ROLES,
			},
		},
		Item: {
			posOptions: {
				roles: AUTHENTICATED_ROLES,
			},
		},
	},
};

type TPolicy = {
	isRoleRequired?: boolean;
	isUserRequired?: boolean;
	isVenueRequired?: boolean;
	isLocationRequired?: boolean;
	isDeviceRequired?: boolean;
	roles?: USER_ROLE[];
};

	await fastify.register(mercurius, {
		schema,
		resolvers,
		loaders,
		ide: true,
		graphiql: true,
		path: '/graphql',
		allowBatchedQueries: true,
		queryDepth: 10,
		jit: 1,
		context: buildContext,
		subscription: {
			emitter,
			context: buildSubscriptionContext,
		},
		validationRules: isRelease ? [NoSchemaIntrospectionCustomRule] : [],
	});
	
	await fastify.register(mercuriusAuth, options);
@mcollina
Copy link
Contributor

Does it work? Have you for any issues?

@mike-van
Copy link
Author

So when i tried to add filterSchema it crashed the app, seems like it doesnt work with external policy:

        mode: 'external',
	authContext(ctx): TAuthContext {
		const { device, location, role, staff, token, venue } = ctx;
		return { device, location, role, staff, token, venue };
	},
	filterSchema: true,

@jonnydgreen
Copy link
Collaborator

jonnydgreen commented Nov 21, 2023

What error are you seeing? Are you seeing something like this? https://github.com/mercurius-js/auth/blob/main/lib/validation.js#L31

Atm, we don't support this, and to be fair this isn't called out in the docs - something we certainly add for sure!

Would you be interested in adding this caveat to the docs and/or potentially adding support for schema filtering with external policy mode?

@Bugs5382
Copy link
Contributor

@jonnydgreen Let me take this up. I did not think of externalPolicy. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants