Time for the third assignment in this course.
In this module, we have been exploring user authentication in a lot of detail.
Now, in this assignment,
we will work further on user authentication.
We will add yet another category of accounts called as an Admin.
An Admin account is a super account that has
a lot of privileges of performing various operations.
An ordinary user account can only perform certain operations on our server.
Similarly, an unregistered request coming in from a client
that is not logged in can only perform certain operations on our server.
Now, we're going to modify our server such
that get operations can be performed by anyone.
You don't need to log into the system to perform get operations on
the various rest API endpoints except submission of comments.
For the remaining operations on the rest API endpoints,
the POST put and delete operations,
these will be restricted to be performed only by admin users,
an ordinary user cannot perform these operations.
Obviously, you don't want an ordinary user to be submitting new dishes, or promotions,
or leader information, or modifying existing information,
or even deleting these existing information.
This should be the privilege of only the system administrator for our server.
Also, we will ensure that an ordinary user can
post comments about specific dishes, that is acceptable.
Similarly, an ordinary user can update and delete comments that he or she has posted.
Other users or even the admin cannot update or delete comments posted by another user.
So, this is another restriction that we're going to place in our server.
Now, let's go ahead and examine how we're going to be going about
implementing this and how exactly our server does these operations.
First and foremost, I will illustrate to you how you
would create an admin account in your system.
You will realize that we have to go behind
the scenes to create an admin account simply because,
we don't want an admin account to be created by performing
the sign-up operation on our users/signup account.
This will leave our server vulnerable to attacks.
So, an admin account can only be set up
behind the scenes by directly accessing the database.
So, let's look at how we go about doing
this in the illustration that I am going to show you right after.
Now, to examine our database,
let me start the Mongo Ripple at the Command prompt,
and then go to the confusion folder and then let me
examine the users that are registered in my database at this moment.
So, you can see that I have just one user registered.
So, let me set up two additional accounts,
one for an ordinary user,
and one which is going to be an admin.
So, we will sign up the admin and the second user also from our sign-up point,
thereafter they will come back to the Mongo Ripple and then set up the admin account
explicitly by modifying the record in our database.
Going to Postman pin,
let me sign up two additional users.
So, we had earlier signed up one user with this name,
so I'm going to sign up another user into my system,
and so, a second user is now registered successfully.
Now, let me also register an admin account.
So, for the admin account,
I will set up the username as admin and then sign up an admin user.
So, we see that we have now added two new accounts to our system.
Going to the Mongo Ripple,
let me again repeat the
db.user.find() and let me do it pretty so that it looks more easier to read.
So, when I do this,
you can see that we have an admin account here with the user name as an admin.
Ignore the first name and last name,
I'll set up this first name and last name to be the same for all the three.
Then, we have the other user account that I have set up with the username here,
and the third user account that we already had in our database.
So, now we have three user accounts;
two user accounts here,
and an admin account.
Now, of course, you'll see that in the user accounts,
we have this flag called as the admin flag which is set to false for
any account that is signed up on this /users/signup endpoint.
That is the default way that you should set up accounts.
You cannot allow a user to configure an admin account
by doing anything directly on the rest API endpoint.
Instead, we will go behind the scenes and then in the Mongo Ripple,
I'm going to modify this record for the admin user by
saying db.users.update and then
we'll supply the username as admin here.
So, we're going to be updating verse record and then we'll say {$set:
recall how we were manipulating the MongoDB so we'll
say {$set: {"admin": "true" }}.
So, what we are doing here is that we are searching
for this user account with the username admin,
and then we are setting up the admin flag to true
here by using the $set option.
So, this is how we would update an account to be an admin account.
So, you see that this has modified the results.
So, let's again check the accounts.
Now, when you check the account,
you'll see that for the admin account,
the admin flag is now set to true,
so that is how you will end up creating an admin account.
Now, the Admin account as we would expect has additional privileges.
So, once you complete this assignment then,
you would notice that the get operation can be performed by any user on
the /dishes/dishes/aspecificdishendpoint/promotions
and the /promotions/specificpromotionendpoint and similarly,
for the leaders in points also.
But the POST, put,
and delete operations on these endpoints can only be performed by admin users.
Now, in addition, the comments endpoint,
we would allow only a registered user who has logged in to
access comments for a specific dish,
we will allow a logged in user to post comments.
We have already set this up in the exercise so,
when the user posts the comment,
we have ensured that we verify
the authenticity of the user and then when the comment is posted,
we have setup the author ID for the comment using the user ID.
So, we have already completed that.
But now, in addition,
for the put and the delete operations on comments,
only the user that has submitted the specific comment will be
allowed to do put and delete operations on his or her own comments.
Any other user cannot modify somebody else's comments.
Similarly, even the admin cannot modify somebody else's comments,
or delete somebody else's comment.
So, that's the second part of this assignment that you're going to be doing.
The third part is that an admin can query
the /users end point and ask for the list of registered users,
no other ordinary user can do this query.
So, this is the other restriction that we're going to put in there.
Now, in order to verify that a user is an admin,
we will first verify that the user is a registered user.
So, the verify user function that we have already implemented in the
authenticate.js should be applied even where you need to check for the admin.
First, you check that is a verified user, thereafter,
you will introduce another function called verifyAdmin in the authenticate.js
file which will check to ensure that the user is an admin.
Now, to check whether a user is an admin,
all that you need to do is to check the rec.user that is on
the request object rec.user there,
check to see whether the admin flag is true or not.
If the admin flag is true,
you will allow the normal process of proceeding further to the [inaudible] happen.
If the user is not an admin,
you will generate an error and send back an error message back to the client side.
So, that's how we're going to be handling the admin users account.
Now, when a user is trying to modify or delete his or her own comments,
we have to check to make sure that the author of the comment is the
same as the user that is trying to modify the comment.
Now, the rec.user also has the ID field,
so you need to cross check that with the author field of the comment.
If these two match,
then you will allow the user to perform the put or delete operations.
If they don't match,
then you will not permit the put or the delete operations on that specific comment.
So this is the other aspect that you're going to
be implementing as part of your third assignment.
Let's look at how all these things work by
using Postman to perform various operation on our server.
Going back to Postman,
let me first perform a GET operation on
dishes to just check to see what is in my database.
So, if I perform a GET operation on the dishes,
notice that I am not putting any authentication in the header.
GET operation is allowed by anybody.
So, when I perform the GET operation,
I can see that I already have one dish with a comment already in place in that dish.
This comment was posted by this user already.
So, we already have one dish in the system there.
So, this is perfectly fine,
I am going to delete the dish.
Now, to delete the dish,
obviously that operation cannot be performed by an ordinary user.
So, let me login as,
so you can see that I am logging in as a regular user.
So, let me login as a regular user.
So, when I login, I will get the token.
So, I'm going to copy this token and save it.
Now, that I have my token,
let me perform a DELETE operation on the dishes.
So, when I go to the DELETE operation.
So, let me select this GET and then do a DELETE operation with the dishes.
In the header, let me include the authorization here and you would notice
that when we paste in the request and then send the DELETE authorization,
you would notice that it immediately comes back with this message here,
as you can see in the preview,
it says "You are not authorized to perform this operation! "
Then the error code is 403 forbidden.
So, this is a message that has generated by
the verifyAdmin function that you're going to be implementing as part of this exercise.
So, if the user is not an admin,
then this is the message that your verifyAdmin will
generate and it will not allow the request to go beyond that point.
So, you can see that I have closed off the DELETE operation.
Now, how do you do this?
In your code, you have seen that in order to apply the verifyUser,
we set authenticate.verifyUser in the POST,
PUT, and DELETE operations.
Now, you can chain the middleware one after another.
So, we can say authenticate.verifyUser comma
and then following that you can say authenticate.verifyAdmin,
to apply the verifyAdmin right after the verifyUser.
So, if you want a operation to be restricted only to the admin,
you first do the verifyUser part and then immediately following that,
you apply the verifyAdmin middleware.
Right after that. So, if these two checks,
successfully pass through, then you will go onto perform the operation.
If the verifyAdmin check fails,
you will return this error message as you see
here and then abort the operation that part.
So, you will return the next error from your verifyAdmin,
if the user is not an admin.
So, I have demonstrated to you how you're going to
be using the admin users account to restrict operations for a PUT,
POST, and DELETE operations.
Same thing, POST and PUT operations will also not be permitted on any of these n parts.
Now, then let me demonstrate the other aspect here.
So, you saw that in there,
when we perform the GET operation,
you saw that there was already a comment that was posted by the username Jogesh,
the first user that is in my system.
Now, I'm going to login as the other user.
So, I will login as into my second account which is Muppala and then when I login,
I again get the token.
So, let me take this token here.
Let me copy this token.
Now, what I'm going to do is I will do a GET on the localhost dishes.
So, let me do a GET on the localhost dishes to show you the specific comment inside here.
So, this particular comment with this ID.
So, what I'm going to do is,
I'm going to copy that dish ID.
I'm also going to copy the comment ID from here and I'm going to perform
a DELETE operation on this specific dish
and recall that we have
the slash comments slash and then this particular comment ID.
Now, remember that this comment was posted by this username,
but I have now logged in myself as the other user with a different username.
So, when I now perform the DELETE operation using the other account,
you would immediately notice that in here it says,
"You are not authorized to delete this comment! "
Then it says 403, same thing.
If you try to do a PUT operation on that specific comment logged in as another user,
it'll say, "You are not authorized to update this comment!"
So, both PUT, DELETE and UPDATE of somebody else's comment is not permitted.
So now, let me log in as the admin at this point and then let me try to delete
that particular comment and you would see that the same message will be generated.
So, an admin also cannot delete or update somebody else's comments.
So, to login as an admin,
let me go into the POST here and then let me login as an admin.
Now, remember that these tokens will be valid for 33,600 seconds.
So, you can save these three tokens that you generate for the three users.
So, you don't need to keep logging in as that particular user.
As long as you use the right token in the header,
your operations will perform just fine identifying the three different users.
So, let me log in as the admin here.
So, when I log in as the admin,
I get the token here.
So, I'm going to copy and save this token.
Just remember which token belongs to who when you make a copy of this.
Now, going back to this, delete comment operation.
I'm going to go into the header and then I'm going to change this to the token for
the admin and then try to perform the same DELETE operation and then you see
that even the admin is not authorized to delete the comment posted by another user.
This is perfectly acceptable.
But let's try to delete the same comment,
by this user that created
that comment and you would see that that can be successfully done.
So, let's perform that operation.
So to do that, I'm going to go back and fetch the token that I have
got for the first user and then change the Authorization field.
Now, for this DELETE operation,
I'm going to change this to bearer,
and then this is the token for the first user with the username Jogesh.
So, when I try to delete that comment,
you will notice that the comment is now deleted successfully.
So, as you can see from the steps,
the comment can be only deleted by the user that created that comment.
Now, the next step,
when we do the DELETE operation on the dishes,
we saw earlier that if we did the DELETE operation as an ordinary user,
you get a message saying,
"You are not authorized to perform this operation!"
So, I'm going to change this token to the token of the admin and then
show you that an admin can perform the DELETE operation on the dishes and pot.
So, going into this request,
let me change the token to be the token for the admin user.
So, when I perform the DELETE operation as the admin user,
you will notice that the DELETE operation is
successful and then replies back with the message here.
Now, when I do a GET on the dishes endpoint,
you will notice that the GET operations shows that my dishes have been emptied.
Now, the other operation that you will also implement in this assignment,
is that we can do a GET operation on the slash users endpoint.
So, when you do a GET operation on the slash users endpoint,
you will notice that if you are not an authorized user,
it will say you are not authorized to perform this operation.
So, the localhost:3000/users/endpoint, you
are now going to be allowing this to be performed only by the admin.
So, if an ordinary user,
if you log in as an ordinary user with the header,
you will not be allowed to perform this operation.
Now, let me change this token to the token
off the admin and then you will see that
the admin will be allowed to perform this operation.
So, going to the GET,
let me change this token to the token for
the admin user and then when I perform the GET operation on that, it returns.
As you can see, the three users that are registered in my system,
it shows the user number one,
user number two, and user number three.
Of course, notice that the hash and salt are removed,
when the message is returned by the server-side to the client-side.
So, the hash and salt information will be never revealed outside.
So, Mongos will automatically take care of filtering
out that information before it sends back the user's information.
So, because you should not be revealing the hash and
salt information to the outside world.
So, this is the three user accounts information that is returned.
So, this is returned only if you perform the GET operation on
the slash users endpoint as the admin user.
If you perform the same request as any other user,
this will not be permitted.
So, again you will check first,
verifyUser and then check the verifyAdmin and only if it is an admin,
then this operation can be performed on this end point.
So, these are all the various tasks that you will do as part of this assignment.
The details of how these need to be done are documented in the assignment instructions.
So, read through the instructions before you proceed to complete the third assignment.
Have fun completing the third assignment.