Hey guys.
In our last video we were going through setting up user authentication and in this video we will be
looking at setting up rules to her boss to further control who can access what's know there are a few
things that we need to do.
Rules would already be enabled by virtue of the fact that we have individual user accounts and we already
set up the database for user authentication so we just need to have a few more tweaks and we will get
our rules based or our rules separation in fact in our application.
OK.
So we'll start our journey in our style of class and since allows me do I actually upgraded to visual
studio or community addition 2019.
So the interface may look a bit different as I go along.
But essentially it's pretty much the same as you which is what we started this course series in.
So we start with startup.
And once I want to do is actually create a few rules to begin with.
So in the context of our school management system we would probably have an admin a principal and let's
say a user or a teacher.
So we want at least three rules to begin with.
So what I'm going to do is define a function here in the start class that is actually going to go ahead
and create those rules as soon as the application will start so since that's what this class is here
for.
So just go ahead and create a function both creates you roles and users.
And what I'm going to do here firstly is include my application Beebe context to recall that application
VB context would have been defined in our identity model right here and it represents that direct connection
which we call a default connection to our database that is hosing our user beast tables.
So here a default connection is looking right at our database.
So what we want to do is initialize an object of that here because what we want to do is to do a few
database operations.
So we need to include our application B2B context and our father context Zee photo.
And then we see that it's telling us we need to include something so a nice keyboard shortcut is control
and dots and it will show us what moves up and we can skip that and then we see a new application DV
16 or maybe or that var can of the villa or so you could always just see a bar here for context equals
new application DV context.
Next we want to enable to monitors in the form of the role the manager and the user manager.
So I'm just going to initialize an object call it role manager and I'm going to say this is equal to
a new role manager and I can just say control that which will promise me as to what needs to be installs
included.
Sorry.
So I can just press enter and go right ahead and I want this to have identity a role which is going
to require another inclusion so control but once again press enter.
So as you go along you can just go ahead and include all of those libraries that need to be installed.
And this is just a part of the initialization.
So you can just go ahead and type along with me rule store identity rule.
Once again and all of this within the context of context so essentially we are initializing a road monitor
and we're passing in the identity rule and we it's we're initializing a constructor plus in rows store
with identity rule and the value of context here plus in the database that this rule manager should
be initialized within the context of how we do something similar for our user monitor.
So those duplicate that line and just change some of the words.
So this will be user manager.
This is no user manager.
So ultimately has this a similar setup this will be application user.
And this would be user store.
And once again application user and context to me is the saying no we actually need to put it into action.
So what I'm able to do is write an if statement to say that if a rule already exists.
If I rule does not exist then create it.
And well obviously it wouldn't create it if it's already exists.
So I'm actually going to create an admin user initially.
So if and when to say not and the role manager allows me to actually to find or run certain rules specific
operations so I can see rule exists.
And this function will actually go into the rules database and the real stable.
Sorry.
And check if a rule exists by this name.
So clear rule manager we'll see if there is a rule that exists with the name admin.
All right.
But in this case I'm thinking if not I want to see if there is no rule admin then do this.
And what I want to do is create the first rule.
So I'm just going to initialize something of type identity rule and then I'm one to give this role object
a name.
So the idea would be implied once it goes into the database.
But once you give it the name and the name I'm going to give it is admin and then I'm just going to
say room manager go ahead and create this rule so road manager once again has some rural specific operations
that help us to manipulate the rules stables so we don't have to do much work in getting data in and
all of this table.
As with regular table swans it's no use or our rules table as it would have been generated then.
We have certain operations given to us by the framework that helps us to manipulate these tables so
that I have the role.
I'm actually just going to create a user off but application user and I'll do my object initialization
which would then see user name so you could have done that.
Here you go.
Just then the curly braces here and then this field in name equals admin.
So I'm just doing it both ways just in case here in you to see sharp and you want to see how or P works
there certain ways to get there on this so I'll give this user name let's give it admin keep it simple
and the email sorry since to be mean at the bases and then GS to the management for sure com.
All right.
And then what we won't be able to do is actually just set the password directly here.
Lisa I don't want to because I would want to actually see the bar password is equal to and I'll just
say password just to keep it simple.
What do we call that our database is actually going to or at least our functions are actually going
to encrypt this password before it actually gets stored in the database.
So password is equal to this simple word.
I just I'm just doing this so I can actually remember but this is a verified practice going forward.
So then I'll save R Us Ah.
I'm just I'm just creating variables here is equal to and then here's where user manager comes in because
all we want to actually create are users.
So we call on our user manager object and then we see creates we know we can and then we're passing
in and if you look at the function overloads you see or you can create a user with no password.
All right.
You just class in the object of application user or you can actually create a pass or user with a password
and you pass in the user object or the application User object and whatever the password is in string
form.
So this function would actually handle that encryption and insertion into the database.
So this boss in our user object as well.
Or password and then just add a cursory check here to see if or creation.
So anytime you actually create carry out an entity framework action or function usually this function
will return some value.
So the so the so the user objects here are us our objects here will actually have a value so we can
see us are not succeeded.
All right.
So it will return a boolean if it was successful it also returns a list of arrows.
So yes if this is false then you will get a list of errors if this is true then obviously whatever you
try at work.
So if this operation was successful then we can see var results is equal to or use manager.
Once again we want to add a rule.
And after I finish writing this I'll experience user dot I'd be and the rule which is me or let me start
from the top.
So we check firstly if there is a rule called admin in our rules tables.
All right.
So rule manager act is our leads on with our royal stables our DC Does the rule exists.
Yes or no.
No.
If it does not.
Which it wouldn't.
At this stage then we want to firstly create a rule object and then fill it in with the data.
And in this case we want to give it the name admin and then we go ahead and create the rule.
So the rule needs to exist.
Then we go ahead and create an admin user and then we use that admin user password and then we say creates
this user with that password.
So now we would have an admin rule and we have a user called admin.
What we don't have is an association between our user and the rule.
So that is where this line comes in where it is if the user was successfully created.
Right.
And if it got this far then the rule would be successfully created.
If the rules created and the user was created then we want to see if it was successfully created then
we want to add a rule this user.
And that rule.
In other words no we want to create an association between this user idea whatever user I.D. and all
the science of this object.
Because once it's different more for us this operation this object is basically updated with the idea
coming from the database and we have the admin rule.
So this function will actually handle finding all the two ideas and associating them.
Now I think all of this is very important for the admin because admin users are a dime a dozen.
Usually you have one to very few admin users.
You don't go on creating admin users.
However for the principal or the supervisor and the teachers it's not that serious.
So what we can do is simply check if those rules exist.
So I'm just going to see if that's room manager DOT's role exists and this time when to search for the
school teacher.
So if there is no teacher rule then I'm just going to copy this code here and then I'm going to just
paste it there and I'm going to change zero name to teacher.
And there we have it.
So once again on the first run as of writing this code none of these rules exist.
So this will run and create admin and admin user.
This will run and create a teacher rule and I'm just going to put in one more for a supervisor which
is very similar to that.
Again super advisor and supervisor.
All right.
And I'm just going to control a shift and b to build and just ensure I have no errors.
All right.
So we have no errors and know that we've created all of this what we need to do is actually call our
function in our configuration function which runs as soon as the application starts.
So I'm just going to call this function.
I can just copy and paste it this it there and then we can execute and watch that our rules get created.
Okay so we got an error here.
If you are following up to this point in all of the lectures remember that we modified our application
user objects to actually have had dates of birth all right.
So as a result when we're creating this user in our startup sorry it is saying that we have an invalid
beads dates time results.
So we need to fix that.
So I'm just going to stop this real quickly.
And then what we need to do is actually add dates of birth here birth dates equals and other C beads
time gotten all to require me to do a fund that's using the system and then we can try this again.
OK.
So we see that our application came up successfully but I'm not quite interested in what's going on
here.
But quickly out of strand log in as the admin user which should have been created when this was started
up we'll go.
So we're not entirely interested in what is on this screen.
However we want to check our database to see that our rules were created.
So let's go over to survey X for having stopped the debug mode and say so too will data and we want
to see that or three year olds have been created.
And so sad so done.
So we have our three rules admin supervisor teacher and the respective I.D. And if I go to its been
its users and we should see or admin user OK I'm not seeing the in user going to have to check that
out.
I'm not entirely sure why we can get back to that.
So if admin user was not successfully created then that means that association was not going to be there
which would be found in user rules.
Right.
So there is no association.
So at least we have three rules admin supervisor a teacher and we have at least we have two users here.
No.
The thing is if we wanted to associate them at least manually then we just need our user I.D. phone
here in this forum and we just need a real I.D. found in this photo and we could just put them side
by side here manually.
And then we would have an admin user versus a teacher versus if that if that user I.D. appears twice
with two different roles then that user has those rules that have been assigned.
So let's just debug what happened why our admin user was not created.
And I have a strong suspicion if has to do with using a weak password when I want to tweet this quote
a bit and I'm actually just going to tweet this bit here and I'm going to run it before that if statements
just so I can debug what is happening some distance since I debug point here because it seems that parents
of the object successfully and I'm just going to go ahead and press run and see what happens.
All right.
So mid starts up we fix our breakpoint if we look in our user object we see that we have a Roku admin
and the ideas are there and then I can step through using a filter.
We go line by line so I have a password and then we have our function here which would actually create
this user and password.
So I press for them then it will go to the if statements which will then see user creation is successful.
Okay.
So if I press for that again then it should go into the if statement and proceed to associate the user
I.D. for that admin user with the roll.
So I'm not entirely sure why it did not work while it was a part of that statement or its our application
is up this time but I'm just going to stop because I'm not really interested in the application at this
moment.
And I'm going to go to my database and users and see if my eyes deceived me or not.
And there we go.
So our user has been created successfully.
So that means I should be able to log in with this admin user and if we look in user rules and we just
need to refresh.
I already did it but if you're not seeing can industry first query and you'll see that you have that
association user I.D. rule.
I'm not entirely sure why the code didn't run while it was in your statements but the fact is we really
don't want to run again which is why we would have put it inside if statement only happen if there is
no mineral.
So this kind of code you could actually put into an application you're deploying it for the first time.
And these are presets they can put any preset you wish you can create a function create your presets
and just call the function inside this configuration function in the start of class.
Know that we have successfully created some rules and created at least one user in the rule what we
want to do is and this is very very very introductory not best practice that's all but for the sake
of example I do it this way.
What we want to do is actually modify our registration process to include rules.
The first thing I want to do is go to my models and modify the identity model.
So the first thing I want to do is go over to models and modify my account view model and find the or
this model and I want to add here property to accommodate rules all right.
So I'm just going to create another required field you the display name.
User rules.
And this is going to be a string and I want to call it user or you'd also notes that in our database
the e-mail and the user name would get the same thing.
In this case they don't have the same thing what forever previously created one they have the same values.
So what I'm want to do is include user name as a property.
When registering and make sure that we use it user name separately.
I'm just going to put user name and this property user name.
Thanks though.
We want to initialize our combo box for the view for distribution so I'm just going to go into my columns
on trawler and what will be happening in this controller is I want to run our query against my rules
table to see all of the rules in the table and present them as options for distribution.
So the first thing I want to do is actually create a property for application to be 16.
Those remember that just so we will be releasing with our database.
And I'm just going to initialize its having done that.
We want to make sure that when the person user for our site goes through register and we render the
view we're actually rendering the list are combo box with all of their options.
So we just simply call view bug thoughts rules and there are many ways to do this I'm just going to
do it as a view above and call if I select this.
And this would actually go in handy later when we start looking at how we associate files and how would
we have dropped phones.
But in this situation a select list Firstly it takes the data source which would be context about rules
which would do us all rules but best practice would have us create the admin users outside of the box
not a lower user to treat or register and register as I'd been.
So while I'm white I'm not doing it as a best practice by allowing the user to choose their rule.
We can still explore why certain things are just a bad idea also.
So in this situation I would modify my data source and exclude the admin rules so I thought on teens.
So you can see where the name does not come to an app and then that would see exclude to and then we
can just put it to list make those easier.
And there we would have satisfied the very first constructor always see that there are nine of them
and we are able to employ one of the nine that is not this not with a select list you can actually see
when it is selected what value you want.
So I want the value name not the I.T. and also what should be displayed.
And I also want the name to be displayed.
So if you have a word with a combo box and HMO then you know that you always specify the value and you
specify the text to be displayed.
So this is essentially all we're doing is we're looking at this list of objects of type role and we
know that any variable or any object rather of type role has been to name and I.D..
So we're saying we want the name to be the value and we want name to be the displayed value.
Also right now we're doing all of that before we return the view.
Now in the view of this right click this and see Google to view what we want to do is include another
form group section for our newly created combo box.
So in a sense you copy and paste that form group and this would be a label for and we can change that
from confirming passwords to we use a rule for and we also have one for user name.
So just do this twice and probably put user name above e-mail.
All right.
Well let's do one at a time.
So let's do user name and we will see if that value.
So and this would also be a text box for as opposed to a password for a text box for her username.
All right.
And then likewise on here we actually would choose this the user rule for the label but we want our
H2 helper for draw up and down the list.
So it's a drop on the list and then we select our property user rule.
Put that in quotation marks and then we see that we want to use the select list and we are using in
view by its rules.
So we are implicitly converting whatever values instead of view bug URLs into a select list.
And do remember that that is what we set over here a view by the rules is a new select list.
So this implicit conversion should not feel considering that we already put in a select list there and
then we just have one more empty prior window and then that should take care of our distribution page.
And so we've modified the get or disappeared and the actual HMO.
Now we need to modify what happens when we post back.
So when a user actually comes in to be registered there are certain tweaks that need to occur here.
Well firstly we no need to modify our user name object to know that it is no longer taking e-mail what
it is all taking using it because we added that.
And then the next thing we want to do is what's going on is seeing function to see this that's user
manager dot add to rule.
So now we're actually going to associate this user with a rule and we would remember from the previous
activity that what we want is our user I.D. So user but I.D. and our rule by name which we would get
through model dot user rule.
All right.
So have a little fun here.
Oh I'm sorry.
I'm using a waits here so whatever I'm using it has to be a sync.
So wait a seen.
And there you go.
So each user manager and we are passing the user I.D. because the user would have been created from
this function call.
And if it was successful then we would automatically sign in.
And I mean you could always treat this you could always move this signing function after the creation
and the Association of the user with the role and then you could rewrote to the page.
And similarly if we have to render an error then what we would want to do is reload or select this because
when the page reloads with our arrows we add ons an empty combo box for the user to have to sit down
and figure out how do I get something back.
So we want to reload our view bug with this list such that when it returns this view it knows exactly
what data needs to go back in.
And so we can test this and ensure that our application works just fine.
No our application is up let's try and register a brand new user and see what the experience is like.
All right.
So now we see that we have user name and we have user roll with a dropdown stuff for seafood makes good
style this way using Bootstrap to make it look like I've dropped on that fits in with others.
But let's go ahead right now.
Some would just say test teacher or let's say teacher Y and the e mail address and the C I said e-mail
this.
That's user name.
So we need to modify our model.
So you take all of that slash user name.
All right.
So e-mail address would be teacher at school.
Date of birth.
Just deal with that that password.
I'll use this in Professor again and then user will you notice that this is a blank over when I click
you'll see that it actually has values excluding admin based on the query that we wrote to fill this
combo box.
The reason there is a blank space here is that in our code we did have a blank space in our each demo
in the form of this.
All right.
So that's what that would give us a blank space as a first on default.
So we can go back and these our decision by selecting our role as a teacher and then at the register.
And there we go.
So I'm just going to say but using the or combination for a teacher 1 and if I click manage or click
on the user name you see that you actually have some auto generated functions for the user here.
I won't get into that to be but we can definitely tell that our teacher has been created and I'm just
going to come also people more quickly and we people with the database and see what role this teacher
has been assigned.
So if I refresh the user's table then you'll see teacher coming up so we have a teacher at school come
with the email and we see that the card user name is coming across based on the changes that we have
made.
And if I go to the user and rules that we should see a second rule here.
Coming up with the teacher's I.D. and the teachers are all I.T. and there we go.
So we have the teachers I.D. And we have the teacher rule I.D. and that is essentially how you go about
creating rules.
Now the last thing I want to cover in this video is how you can go about authorizing a controller based
on the rule.
So we have discussed using author as to say that you are unable to access certain things control or
are the entire controller if you are not logged in.
Know what we want to do is see if you're not logged in on a particular rule.
Then you are restricted from accessing these things.
Now let's say for instance we already have admin who already have teacher teachers usually are the ones
who should be looking at the students and their details.
The admin might be the I.T. guy so admin might not necessarily be able to access all of this and that
that may be a far fetched scenario offensive that admin should be able to do of but just humor me for
this scenario and let's just see that anything inside of the students bunch Schroeder should only be
accessible to people who are in the teacher role.
So on the authorize attributes that is already here on our students controller I'm just going to put
an open and close parentheses and then I'm going to see rules and then you see the intent of census
seeing rows equal and then what's is expecting is a string with the rules that should be able to access
though you can actually have multiple rules here so you can see a teacher comma admin comma as many
as you need.
All right in this case because we only have two users in either.
I'm just going to demonstrate with teacher versus admin so let's go through this again.
A teacher is authorized to access everything instead of this students control.
We already load anonymous on index so that means an admin are not logged in person should be able to
access index.
However if anybody who is not in the teacher role logged in or otherwise attempts to go to details or
create or anything else inside this bunch folder then they should feel no let us test them know that
the application is OK.
I have realized that there is a bug where if you are in debug mode and you're already logged in.
Then when you try to do this operation it will prompt you to log in as though the author as attributes
is not working.
So to make sure that you get the most out of this this I recommend that you log off and you trying to
log in again so I logged off and log in and just show you some changes that I made to the logging process
where I changed the log in from email to username.
Usually we ask people to log in with username and password and in the same vein in the code I actually
updated the sign in managers.
So this is in a column controller and this is a post logging phone function change signing the Monitor
that password signing async to be module dots user name so I updated the log and model of user name
instead of e-mail and the signing function actually takes the user name and password.
So because we're using email as the user name up until know because we added user name as a field in
our registration process we want to make sure that we're sending and with user name and password which
means that all the two users would need to be updated.
User names.
That's not the email address any of those are some changes that I've made so you can go ahead and make
those changes.
But as it relates to also logging in this logging quickly as a teacher and then demonstrate that the
teacher can go to all students which allows anonymous but can also go ahead and go to its details delete
or creates and I'm just middle clicking to open these open new tubs so I can show you that each page
loads as we would expect since this person is in the cart to roll.
No what I'm want to do is sign up teacher and then log in as the admin user and no girls to students.
Which will allow me.
But then when I click on Create new it will prompt me to log in because my admin rule is not allowed
to access this page.
And so the person is love in what they're being prompted to log in again because they're not authorized.
So that is essentially how you can global using rules to control access to different parts of your application
and how you go boating in installing rules and customizing them to your purpose.
All of this is extensible because different people have different requirements but this is pretty much
although the box with minimal code you can leverage Microsoft's existing rules management system.
Thanks for watching and see you next time.