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

Reworked page authorization to use locals/hooks #24

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

JPW03
Copy link
Collaborator

@JPW03 JPW03 commented Aug 23, 2023

Note that this is ONLY for page authorization, so no authentication for actions for now. (I've been looking into whether Sveltekit actions can be invoked externally with custom POST requests, but haven't found anything yet. If I do find something, then authentication for actions would be necessary)

I did some testing to see if the permissions could accidentally carry over between pages where the permissions are supposed to change; there were no problems. Also while doing so I did confirm that +layout.server.svelte files do run every time a page is loaded (which includes all parent layouts, from top to bottom, even if parent() is not called).

@JPW03 JPW03 requested a review from clxxiii August 23, 2023 11:01
@JPW03 JPW03 linked an issue Aug 23, 2023 that may be closed by this pull request
2 tasks
Copy link
Collaborator

@clxxiii clxxiii left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry for not getting to this earlier. I'm struggling to find a prettier way to say this, so I'm going to be a bit harsh:

The goal of this pull request seems a little pointless. perms is an abstract object in that it lacks meaning unless it's properties are verified. If perms.edit is true or if perms.edit is false, it ultimately makes no difference to the behavior of the program unless the state of perms is checked.

The issue this pull request attempts to solve is that the SvelteKit router can skip some code in favor of speed. If the router skips code that handles whether a user is able to access a page, and the state of their permission has changed since the last time it ran, the router continues to use the old state.

The changes you made now determine a users access based on an external variable perms which is updated for every request, rather than pulled straight from the database. That's a good change and it increases readability, but since perms itself is abstract and does not determine the user's access to the site, this change is, as I said it earlier, pointless. That being said, you already wrote it, and it's a step in the right direction so I think after you fix a few of my comments it's good to push.

For all I know the sveltekit router is basically a magic box that does whatever it wants, so relying on it for something vital like authorization can cause some edge cases. The edge cases it creates aren't a huge deal when 2-3 users are running tournaments. So I'd say there's no point in rushing it before the 'Run a Tournament' milestone.

When the ability to create your own tournaments is made public, we should look into entirely reworking how authorization is done. I have some ideas for how to do that, but we should collaborate more on that when we come to it.

import EditPageSetting from '$lib/components/tournament-page/edit-page/EditPageSetting.svelte';

export let data: PageServerData & LayoutServerData;
export let data: PageServerData & LayoutServerData & LayoutData;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use LayoutData, the LayoutServerData type is redundant, as it's fully covered by LayoutData

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't know that, thanks.


if (!editPerms) {
export const load: LayoutServerLoad = async ({ locals }) => {
if (!locals.perms?.edit) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of what I was talking about in the initial review comment:
This does not fix the problem of "authorization being in layout files", because the if statement that determines whether the user is able to access the site or not still exists in the layout.

@@ -10,7 +10,7 @@
let { tournamentName, teams, rounds } = data;
let selectedMatch: db.MatchWithTeams | undefined = undefined;

function onDrop(updatedTeams: db.TeamWithMembers[]) {
function onDrop(updatedTeams: db.TeamWithMembersAndMatches[]) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine, but in the future please isolate any changes like this to direct commits to the main branch, or a "General Improvements" branch with a list of the improvements you made.
Otherwise it's hard to tell when I'm reviewing whether the code you wrote is relevant to the pull request or not.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's difficult to tell but this is just a random type safety error fix, and I agree a general improvements branch would be a good idea.

@@ -17,8 +17,8 @@ export const load: LayoutServerLoad = async ({ params, parent }) => {

// Team captains have a member_order of 0
const isTeamCaptain = team.Members.some(
(member) => member.osuId === user?.id && member.member_order === 0
(member) => member.osuId === locals.user?.id && member.member_order === 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This bit actually faces the opposite problem:
If code in +page.server.ts is run after every request (which I'm not confident it is, but for this example it does) and you have an isTeamCaptain check in that file, the variable isTeamCaptain will only be up-to-date when the layout file is run again, which if we're not to trust the router, is not after every request.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still can't find explicit documentation saying it runs on every request but all my testing shows that bost +page.server.ts and +layout.server.ts run on every request, even if the contents of the page itself don't update due to sveltekit's smooth page transitions like when use:enhance is used (this is a bug I'm currently dealing with for the mappool creator). The files that don't update on subsequent requests are +page.ts and +layout.ts.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function runs every time the SvelteKit server receives a request — whether that happens while the app is running, or during prerendering — and determines the response.

https://kit.svelte.dev/docs/hooks#server-hooks-handle

@JPW03
Copy link
Collaborator Author

JPW03 commented Aug 30, 2023

Clearly I misintepreted the auth in hooks idea as "reducing the re-use of code in routes" rather than removing the auth code completely. I agree removing the auth from the route entirely would be better. I think last time we discussed this neither of us were sure how exactly to implement purely hook based authentication, and if you're not even sure if the hooks run every time flawlessly then (ignore that, misread the 2nd last paragraph of the review) we should discuss this soon.

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

Successfully merging this pull request may close these issues.

Authorization using hooks.server.ts
2 participants