-
Notifications
You must be signed in to change notification settings - Fork 189
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
Closes Issue #2153 - Limit how a user becomes an admin #2153 #2239
Conversation
…ew PUT route for admins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also lacks tests, which I'd like to see get added with these changes.
src/api/users/src/routes/users.js
Outdated
@@ -111,6 +111,8 @@ router.post( | |||
next(createError(409, `user with id ${id} already exists.`)); | |||
} else { | |||
const user = new User(body); | |||
// no user can be created as an admin by default | |||
user.isAdmin = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this code into a new middleware function that happens just before the route's logic gets hit. Maybe call it validateUserRights()
and it can simply set user.isAdmin
to false
.
The logic in the route should be focused on talking to the db and returning HTTP results, nothing more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
validateUserRights
created.
src/api/users/src/routes/users.js
Outdated
next(createError(404, `user ${id} not found.`)); | ||
} else { | ||
const user = new User(body); | ||
// no user can be created as an admin by default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same, this can be done via middleware.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/api/users/src/routes/users.js
Outdated
const userRef = db.doc(id); | ||
const doc = await userRef.get(); | ||
|
||
if (!doc.exists) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code seems to be duplicated between a few put
calls now. Can you extract it into middleware and share it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Duplication removed, code moved to updateUser
in schema.js
src/api/users/src/routes/users.js
Outdated
// this route is only accessible by administrators | ||
// it allows the modification of the isAdmin property | ||
router.put( | ||
'/:id/admin', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great, but one question: the naming implies that you are only setting the admin
aspect of this record vs. all fields, yet you are allowing other fields to be updated here. I would limit it to just the admin change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also done in updateUser
src/api/users/src/routes/users.js
Outdated
validateId(), | ||
validateUser(), | ||
validateEmailHash(), | ||
isAuthorized((req, user) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arrow functions with body statements that immediately return a value should be rewritten as inline expressions:
isAuthorized((req, user) => user.roles.includes('admin')),
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
Following. |
Still have to add tests but I think this is heading in the right direction. |
@@ -0,0 +1,8 @@ | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did this file, and the other config/export/*
files, get added?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the change to development.yml
add a single user to the emulator up its bootup. This user as the isAdmin
flag set to true, as without this we'd have no way to make a user an admin during testing.
The problem stems from having no way of creating an admin without first having an admin to create an admin.
@@ -45,7 +45,8 @@ services: | |||
volumes: | |||
# Copy firebase.config into the container so we get proper ip/port binding | |||
- ../config/firebase.json:/home/node/firebase.json | |||
command: firebase emulators:start --project telescope --only firestore | |||
- ../config/export:/export | |||
command: firebase emulators:start --project telescope --only firestore --import=/export |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
src/api/users/src/models/schema.js
Outdated
next(createError(404, `user ${id} not found.`)); | ||
} else { | ||
// if makeAdmin is true turn the user into an admin, if not use body to update user. | ||
const user = new User(makeAdmin ? { ...body, isAdmin: true } : body); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't allow downgrading a user from Admin to normal, which we should support. We should accept a value {isAdmin: true|false}
on the body and use that instead of hard-coding here.
…also allowed users to demote admin status
Given #2555, I wonder if this PR should be closed and migrated to a different issue at a later date (once the suprabase work has been merged)? |
Agree, this can get closed for now; though, I think it's a good starting point for what needs to happen. |
Co-authored-by: Josue [email protected]
Issue This PR Addresses
Closes #2153
Type of Change
Description
This PR limits how a user can become an admin:
PUT
andPOST
routes to setuser.isAdmin
tofalse
.isAdmin
.Checklist