Hey guys we'll come back in this video we're going to get the party started officially and actually
look at how we can go about adding users and while managing their experience with our application so
we'll be adding users selecting the role that they're in and generating a default password and then
we'll have to modify or log in process such that when person's log in using that default password we
we redirect them to a screen that allows them to change this password.
Now before I move on I'm going to show you a little adjustments I made to my main window where I did
a little bar at the bottom here and I have the takes us is logged in as call on.
And the user name someone to show you how to do that.
And it's really simple but these simple things you know make your application come to life.
So what I did in my design for my mean window was to add what I call what they call sorry context strip.
So I went to a stateless strip brother.
So I went to the tool box and then I got inside of menus and the toolbars one that says status strip.
So I just drug that over dropped it though the bottom part here and then I did stateless label someone
to click stateless label initially what that looks like.
So I got tools trip status label all right.
But obviously that is what will get printed to the user that's not what we want printed to the user.
So what I did was modify the properties one by changing the name.
So I changed the name to something I could identify change it to TSA log in text.
That's what I called it.
But I also removed the text because I don't want that takes to be showing.
And then clearly whatever it takes is going to be displayed is going to be contextual.
Right.
So after renaming it and I'm going to delete this one that I just created because I don't need the.
All right.
So I guess it's going to be difficult for me to remove it because he got condensed but that's fine in
the window load function though I did say that I want the user name to be whatever we got back in our
user objects not user name.
So remember we have or user objects that we're sitting here and initializing instead of a constructor
once the person logs in who are passing over that entire object.
So we have access to everything about this user.
And then what I'm choosing to display in that text is and I got a TSA log in text.
All right.
So I call the TSA tool strip item.
That's just me.
That's my prefix that I'm using.
But I would say TSA log in text not text is going to be equal to.
And then I said logged in as Hold on.
And then I'm passing in that user name that I got from my User object.
Right.
So when the main window loads it will know who is logged in and it was really that simple.
All right.
So moving on what we want to do is activate our ad log in.
But right.
So we have the manage user screen we already have our database context object.
We already did our password reset and deactivate user functions and all we need some functionality instead
of add user.
So in order to add user I need another form which I did not create.
So we'll do that together.
And then when you right click my solution go to add take form and then I'm going to add the form and
I want to call it add user.
So I'm not allowing you to edit the user is just add users I literally just want to add user as a form
click add and then we make our usual cosmetic changes where we change the text in the address bar to
the user and then I'm just going to widen it a bit I'm also going to copy some stuff from all one of
our existing add edit screens of updated vehicles.
And the reason I'm copying this is all right someone to use our entire record and then I are the reason
I'm using our entire record is I just noticed that I'd edit vehicle did not have that you know that
label at the top.
We also didn't do the cosmetic changes so I may have overlooked that part with the edit vehicle but
we can make those adjustments later.
So I really just want the label.
So I'm taking this label and moving it all with the user putting into the top changing the text in there.
So that's AD user.
All right.
And then we can of course recenter it.
All right then I'm going to use my label.
So I have been using the table labeled for these forms so I want to use the container and it's going
to be the table layout panel.
All right.
And then what does a user have a user for user would probably want to set.
Only the user name.
Right so you don't want to allow your users are your admin user to be setting the password remember
where the hardcoded generic password.
So we'll leave that generic password that when they click submit that's all that gets grouped.
So I'm actually just going to resize this since it's not going to be that big of a window.
So I do user move or table I know our table container a little bit.
We bring over our labels so under common controls I bring over my label and then this label property
I'm going to set that takes to be user name.
All right.
And then I'm going to bring over a text box so then the text box for the user name sorry.
So don't forget where the things are text box so we can add the user name and then the next thing that
would be setting for this user is the role.
Now remember that the rules are all stored in a table called rules which means that I would probably
need a dropdown list.
So let me just copy and paste this username label and then I'm going to change this one to say rule
but then for the rule I'll be taking this from a predetermined list in a combo box.
So I made a struggle with this combo box and then we did a combo box before.
So what I'm going to do is just me at this table Leo to be bigger so that we can strip you know maximize
on the space a bit more we can expand our controls a bit more and then for the combo box we have to
modify the properties where Wanda wanted to actually be dropdown lists so I don't want anybody to be
able to type in there.
Also the functions are the items sorry would not be hardcoded.
So we'd have to set that from the code behind when this form loads.
All right.
So we need a load function so that it was at the farm.
How we've got the Lord function.
All right.
So in order to load in the items we did something like this already when we were adding the car into
our record.
So if you want we can go back to the add edit or into our record and then we can look at the load function
that we did for this one where we said we want to query the table for all of the cars in the table and
then we want to populate our combo box so we need to do something very similar where we just get back
to my design I want to see that first of my text box for the user name is going to be TB user name so
then we go to properties and change that TB user name and then the combo box is going to be CB rules.
All right CB rules or rule list or something like that.
But once you have the prefix and the appropriate title afterwards and so then what we want to do is
populate this combo box list with the rules and the appropriate value and data members.
So I need to initialize my database object.
All right.
So we have our database object.
The next thing that I want to do is to actually put the function call or the query in here some would
just have virals is equal to database objects dots table which is rules dot and then I just want to
list.
All right.
So I just want the entire list of rules phoned in the database which we know is really the I.T. the
admin sorry the I.T. the name on the short name.
Those are the columns.
And so then I'm went to say CB dot sorry CB rolls.
Right.
That's data source is equal to or or variable rules that we just declared.
And then CB rules that value member is equal to and then we'll see that it is I.D. and then we assess
CB rules that display a member sorry display member is equal to and then we're displaying the name not
the shirt name but the name this time.
So that's it.
The data source we set the volume member and we set the display a member.
And after all of that we want this ad user window to be launched on the click of the ad user button.
So Liam just go back to my manage user.
So this is a button click event.
So of course we know we need to declare an object the user is equal to new and then went to see it AD
user as my initialization.
Then I went to see AD user so that the objects MDI parents
is equal to and then it's going to be this dot MDI appearance remember that we just want to declare
them they appear to be that and then I'm going to see AD user dot show but then I remember of course
we want to make sure that only one instance of this shows.
So we need to put all of this inside of that statement so I need to check if I'm just going to say you
tills dot farm is open and then I pass in the name of the form that I want to check if it's open which
is AD user so if not meaning if the farm is not open then I want to do all of that.
So when you click ad user only one instance should ever appear because of this if statement.
No we're not finished with this.
The next thing that we want to make sure we have is the button.
So we have a quite a submit button and I'm also going to put a cancel button.
Right.
So you could submit that okay.
Yes this is a user you want to create and you could also consider operation it.
So let me just do those two buttons so button one.
I'm going to go to properties and I'm going to call it what I'm want to say submit firstly and then
it's going to have the name Beatty and submit and then for button 2 I'm going to make similar changes
where button to that name is going to be Beatty and cancel and the text is going to see cancel it and
then for the cancel button all I'm want to see is close.
So if it gets clicked I just said doesn't create that I click event and I'm seeing if you click cancel
just close the window.
That's easy enough right.
And then if you click submit then we want to do something else.
So when you click submit is when we actually want to add the user that you're entering to the database.
Right.
So then I need to declare a new object of type users.
I want to say var users equal to a new user all right and then I need to collect data from the forum
so let me do that first actually.
Someone to say var user name is equal to and then I know TB user name dot text.
So that's his user name.
That was just entered right.
And then would just say var roll I E is equal to the selected value of this combo box so CB rules dot
select Ted.
And that's index that's item about what I want is selected value.
Right.
Well then of course this is going to be of type object.
I need it on in so I'm just going to implicitly typecast it to an integer so no role.
I.D. is integer a selected value.
What does the Zi User object have.
So we have the user name we have the rule.
Well we don't give out a password and the active stuff.
Only if I just created the user.
I'm going to assume that the activity is true.
Right.
I don't know why I would create an inactive user someone to leave.
That's as true by default if they want to change it later on they can go ahead and do that from the
management screen.
But I have the role idea and I have the user name and then the next thing would be the password.
So if you recall we have a default password that we use when we recently did the reset password functionality
and I can review that and show you in the money's user we did reset password button where we set that
to the default password.
Now if I wanted to retain this as a default password then that means that I have it hardcoded here and
I have it hard both to hardcoded in this next function which is not good because then if I need to change
it I may change it one based on not remember it's a change that other place.
So it's easy if we have it's one pretty right.
So I'm actually just going to create another function in the utilize where I'm going to see default
hash password.
So I'm just going to take all of this.
All right and I'm just going to copy and paste it and I'm going to call the function default hashed
password.
So this is just me me.
You can name it something else but this one is not going to take any parameters because what I'm about
to do is hash the default password and return that top right.
So when's your return we replaced sorry.
The reference being made to the variable password or we had departments are here.
So the parameter is here now we have password.
I'm replacing this because I just took all department out of this one and I'm replacing it with a hard
coded password at 1 2 3.
So that means if we want to change that default password we need only change it here.
And every time we call this function it will just hash that default password that we have set.
Right.
So what I'm going to do having created this function is one go back to manage user and then I'm going
to change this entire block of code no to just use my new function.
And that's his default hashed password which takes no parameters.
So all it is going to do is return a hashed version of whatever that static takes that we set is.
So there are many ways you can make it more dynamic.
I'm just trying to keep it simple before the purpose of learning.
So we have YouTube's default attached password that was just hash whatever that text is that we the
programmers or the business has determined is unacceptable default password.
Right.
And so I'd use it instead of money user someone to use it again instead of user when I'm adding the
user I want the password to be YouTube's not default hushed password so they're getting a default password
also.
All right.
Now I have the minimum requirements for a user I have the username of the password on our bulletin said
activity status rule I.T. is not required in the user's tables so we soon get to that part but I'm going
to see user dots and then actually I'm is really all you can do it with with the initialize or some
was going to say var new user and the number's going to open and close the braces and then inside of
these open and close braces just a little indentation here we're going to see the user name that should
be here is equal to user name.
All right.
And then comma the password that this user is going to have is equal to the password variable comma
and then the final one is is active is true.
All right.
So when we're about to submit a new user we call it the user name that was entered collect the password
declare clear and you object of type user and then we fill in the columns put a similar code on their
backs isn't.
So we have user name is equal to username password is equal to password is active is true we can go
about adding someone to say D.B. dot users some know when to say add this record to the user stable
so a user database user stable add this user object and then after all of that we save changes.
All right now let's see if this works.
Someone to click Start.
I logged in as the admin user so that I have access to the money.
Users I click manage users.
No we still haven't populated this grid and will soon get to that but let's click Add a user.
And here we see our forum coming up.
So they put in the user name and then we can select the roll.
All right that looks good.
So I am going to put it in another user and would to say admin one and this person this new user is
going to be in the administrator role then click submit and I want to show you something.
So before I click submit I am going to put a break point right that line four to eight.
All right.
So are my line 48 are the last line of this function.
Because I want to check something with you.
So we're going to click submit and then it got this far with no arrows.
So my assumption is that it went through a created the user the password and then if we look at the
user object and just drilled on we will see that we actually have an idea associated with this user
so you can look at that hash.
That's an entirely different hash from what we're used to.
But what I want to point out is the fact that once we got this far and we added the record and we see
the changes it automatically updated or a user object to have the I.D. that it got after it was added
to the database.
All right.
So the relevance of that is remember that this user object is is plain it's dumb it's it's it's only
knows all we tell it.
So we only told it to have a user name were a little bit of a password and dove on is activity itself
true we didn't give it an I.D. I these are being auto generated by the database.
So the fact that it did this saved changes and then it continued it.
The code can reflect that it was saved in the database and it no has an idea of for and that will come
in handy and I'm going to show you exactly why.
So I'm just going to continue.
All right.
And then well you know we need to put it on our track catch and our success message and to close the
window after everything is done.
So we have all of that to do.
But I just want to focus on something first.
Now remember that we just added a user and we selected the rule from the dropdown however based on how
we have designed our rules.
So if I just refresh this through your on this query real quickly then you would see sorry I clicked
the wrong button.
So we'll see our new user being added here.
All right.
All it's in our user rules table we don't have any reflection of any new user with any new rules.
So of course if we're adding a new user and we're selecting the rule from the dropdown that we need
to insert the rule accordingly or the user rule association in this table where the new user that was
added with the idea that we just saw in this case was for has the rule I.D. that is associated with
what was selected from our dropped on list.
So we need to me that modification to our code.
So after we've saved the change to add the user we can now see var user I.D. is equal to our user object
dot the idea column on because no it has a value right.
Like we just saw.
No.
After getting that user I.D. and we already have a role I.D. and the Middle East changes to come on
are keeping consistent.
So overall idea of user I.D. then I can go ahead and see underscore DBA dots.
User rules are.
Sorry.
Sorry sorry.
Skipping ahead of myself there says a var user roll is equal to a new object of user rule which is my
table right.
So I'm creating an object of type user or.
And then just going to initialize it here and then the columns that I have our roll I.D. and user I.D..
All right.
So roll I.D. is going to be equal to the value that I got from my combo box and then user I.D. is going
to be equal to the value that I just got from a newly created user.
And then after I do this then we know the next thing would be to add the record to the database IDB
objects dot user rules dot add and then I'm going to see a user rule and then I'm going to say D.B.
dot save changes or it coming on nicely.
And then once this is done it will create the new user and then fetch the IP then assign him to the
rule are her right.
I send that user to the rule.
So before I go into it I'm just going to put in the try catch.
So just writing try pressing it up twice and then I've put all of that operation instead of the try
and then I'm not one to throw.
Instead I'm going to see a message box dot Sure.
And then the message box does show.
I'm just going to see an arrow has occurred or write something generic.
You can always get as specific as you want but then you know we've been through this quite a few times
and then after a successful ad operation I do want to display a message box saying sorry.
All right see a new user added successfully.
So just a new user added success fully.
And then I will close the window all right.
And then.
Well that's pretty much it for the ad user.
So let's just try it out one more time so I'm going to click start then we log in go to manage users
then add new user.
And then this time I'm going to save you Clark.
That's this person's username and I'm setting them to be view only.
And then I click submit and then it says news user added successfully I click Okay.
And then the other breakpoint is still there so I remove the breakpoint and then continue.
And then we're back at our main window.
We haven't done anything with the grid just yet.
But then if I go to my database and I read execute this query then I'm going to see a third rule.
Right.
With user I.D. five.
So remember that before no use ideals force and 0 5 and the rule I.D. 3.
And if I go over to users and re execute this query then I'm going to see my view clerk with use eighty
five and then the password because they both have the same default password.
So these two passwords are the same.
These two passwords are the same the hashes are the same right.
So it's I mean it's not but if the hashes are to see and the point is that you know if you look at it
you can't tell if I didn't tell you which one was which you wouldn't know which password or what the
English word or equivalent of these passwords would be.
So the next thing that's I want to do know is to modify my money's user's windows so that when the user
gets added or you know deactivated or something that it should reflect here that that data is going
to be affected.
So I'm actually going to do it.
I want you to pause the video and attempted yourself and I'm going to pause right here do it and then
I'll come back and explain it to you.
But I would really encourage you to try it on your own.
All right so I'm just going to walk you through the adjustments I made and I hope you you know pause
the video you attempted it and if you see a and feeling comfortable enough and you are aware you are
waiting on me then that's fine I'll walk you through what I did.
So I created a similar function to what we've been doing up on you know called populates grid and in
populate grid.
I run a query where I sit and he's yes I love cars.
That's because I actually copied and pasted the code from our previous work.
Right.
So in this case then we just change it quickly and so it shouldn't see a car as it should say users.
So I got the users I selected into that new abstract object getting the idea the user name the rolls.
So no I had to do kudos.
User rules that first default to get the first rule or you know it's a list of rules based on the data
construct.
But in reality it's one rule.
Right.
So I'm just saying give me the list.
I know it's only 1 in the list but the way they process it it see that list starts 1.
So since it's a list give me the first one in the list and then tell me the roll name.
All right.
And then the active status snow remember that these column was what I would do whatever the column name
is is what will be used as a column name for the grid.
So I don't want to use a name looking like that and you know name and what is name.
Name doesn't mean anything to an end user.
So I renamed the columns so I said whatever column has user name as the name set it to use a name name
should be rule name is active should be active.
And then we set the idea visibility to falls.
All right.
And then what I also did was I modified the constructor for the add user so when we click add user I'm
parsing in an object of this and this being the manage users form.
Right.
And then I didn't bother to do to construct.
So sometimes I did tools sometimes I did one.
So that did too.
Now the user you know one off of them.
So this time only did one because really and truly I don't think I'll be calling the ad user window
we vote on object off money users.
So you know you can mix and match it's up to you to determine what you may or may not need to do.
So I just modify the existing constructor to have the parameters of manage users and declared the private
object the private property sorry of moneys users initialized it here.
And so that's allowed me no.
After clicking submit to call on the populates grid function in the manage user's window.
All right.
So on so you click submit and it does all of the change it has to do to the database.
We showed the success message and then we refresh the grid and then we close this window.
All right.
And then I also call this populates grid for in manage users and manage users remember we add two other
buttons we had our reset password reset and we had the deactivate.
So the activity more than the bastard reset would need to refresh because for a change of the active
status then that's visible data changing because we have these active columns showing true or false.
So we need to refresh each time that is done.
And then I need to wire up this refresh button doesn't make sense we have 10 it doesn't work.
So let me just add the Click event to the refresh button and this refresh button is just going to see
populate grid.
All right.
So let's just look at this application.
All right.
So we opened up log then go to Monday's users so that's what our grid will look like.
So we have our test user notice I'm not showing the password of course right.
I mean it doesn't make sense to show the password this user.
Remember this was the first user we created and we didn't set the rules so that's going to be blank.
So I can actually just choose this one for the activations of me just click admin one and try this deactivate
the admin ones octu status has changed and then we see that it changes to forms there refreshes the
grid and it changes the falls.
Right.
So of course the grid doesn't look all that attractive with all this green space you can resize does
not want to prioritize those things.
I just want us to get the functional stuff under our hands right.
And so let me just creates one more user and then I'm just going to call this user Clark and this person
is going to be a data entry clerk submit and then click all key.
And then there we go.
So the window closes and then the clerk is there.
If I deactivate then the active status is no false.
All right.
And then just the same way if I click.
So if I.
Well let me refresh and then if I try and click one of these you are going to get those because of the
track catches it won't crash the program.
Right.
So those are the wonderful things that we have been able to accomplish with all of this.
No let me just put in one final function and that is to check if the default password is the password
being used when the user logs in.
So there are a number of ways that this can be accomplished right.
Pretty much the root of it.
What we're checking is if the the password that the user used to get authenticated is equivalent to
all we know is the default password.
All right.
So what I'm going to do is modify the main window load screen right so someone to have to create a new
form and that will be like a password reset for which is really just to text boxes on a submit button.
So I can just do that quickly.
Go to solution explorer add a new farm and then this one is just going to be reset password.
All right take add.
And then you know we can draw regular cosmetic adjustments or reset password and what I'm going to let
this one do really is it's going to be a very small window.
Our guest went out to labels and to text boxes.
All right so I just designed it off screen you can pause and design here is also what have two labels
one to say enter a new password one to say confirm password and then the two text boxes for either which
I renamed TB password and TB confirm password and then my button which I call B.T. and reset.
So when I don't click this well this form is going to have to talk to the database I'm going to have
to do my initialization as usual.
All right.
And then know that I have made a reference to my DB object what I'm going to have to do is retrieve
the user changed the password part and then see if the changes.
So if I'm going to need access to the user that should be modified then I went off to take it in as
a parameter.
Some would say user user and then I'll have my local so that's private user and then see the underscore
user and then initialize on the score users of the value of the user being passed in as a parameter.
All right.
And then.
All right.
So we've done quite a bit of work on the reset password.
I want to pause here and then I'm going to turn my focus again to the main windows so I'm just going
to close off these tubs that I don't need.
Right.
No.
All right.
And then on the main window the main window in the load function.
What I'm going to do is see that if the if the value of the user's hushed password is the same as the
default attached password then the person needs to reset password.
All right.
So what I'm going to say here is so in the window Lord I'm just going to make some space here and I'm
want to see.
So what I'm going to see and know is if and then say something like user.
So I have my user object here.
User dot password.
So I would already know the hushed password based on what's in the database.
And then I want to say if that password that's in the database is equivalent to utilize dots.
And then this would be default hashed password.
See that.
So I'm seeing if the password in the database is equivalent to the hushed password that is the default
attached password.
Remember this function is returning the hashed version of the default password.
So anybody who's as positive as those reset are was just created.
He's going to have whatever password this return.
And that is what is going to be stored in their records.
I'm saying if the user who is just logged in has the same password as the default hash password then
we need to launch window for a reset buzzer.
So I to Survivor reset password is equal to a new instance of the reset password window right.
And then this time I'm going to show dialog.
I noticed that this is seeing reset password.
So because I didn't create to constructor so it's expecting us to pass in some user object so that satisfies
that and then I went to see say reset password and then this time went to show it does dialog server
so that we we looked at all we can launch one window at a time.
Sure dialog is an excellent way to make sure you can just close it just like that.
Right.
So we're seeing reset password Dodge showed dialog.
Right.
And then what will happen is that the expectation is that the user will use that reset password dialogue
and actually change their password if they don't then that's a problem.
But hey so when the window lords we do that check and then we display the reset password windows so
no when they get that window then the expectation is that we one get when what.
Well we're going to get the values that they entered.
So that's the Save Our password is equal to and then we have TB password not text.
All right.
And then the next one is going to be TB confirmed puzzlers of are on firm on this score.
Password is equal to TB confirm us word not text all right.
And then first they'll want to compare them.
So I'm going to see if this word is not equal to confirm passwords.
So we know that that's a problem.
If you use any modern web site you know that the password on the gun for impostor bodies must be the
same.
Then it's going to see a message box
not sure our goal is going to warn the user that passwords will not much.
Please try again.
All right.
And then otherwise we're going to nose say that or on the score User object dot password is equal to
utilize dot hash password and then we're hashing whatever value they put in as the new password and
then once we're done with that we can see on this score D.B. dot save changes because we have access
to the actual objects coming from the database.
So we're going to try that.
This has worked for me in the past.
I'm not going to say if it is going to work.
No but I mean we're going to test it out.
No.
So let me start on that I'm going to log in with one of those new users that would obviously have one
of those new passwords someone to log in as the clerk.
So clerk.
And it would be kept to be a little B or D I'd say one two three.
That's the password that we set.
And then we okayed studying this that those are invalid.
It's telling us it's invalid because this user is set to inactive virus.
So at least something works.
So the clerk on the password.
But the user is inactive.
So that didn't work.
So let's try a test user instead someone to do test user.
And I'm going to type it in lowercase because in the in the actual database so it does mixed case.
So let me see if it works.
OK.
Does work.
And then they're telling me that I have to enter a new password.
Right.
So I'm going to change this password to the same word test user.
All right.
So we need to fix that because I didn't set the password char on the password and confirm password.
But let's try the reset password nonetheless All right.
So I noticed that it's and it does not work.
And I mean that's that's what I was fearful of.
To be honest.
But it's not a surprise to me when we can see whether that's some cozy house bit of work to do still.
So what happens is that even though the user object is passed over.
We're not we're technically not connected to the database by the time we hit this point right.
So we can't just DBC if changes because technically there were no changes made to the database.
All right.
So what's I'm going to do.
I'm going to exit debug mode and then we'll just make some final touches.
So first them setting the password char for my ticks boxes and so my password char here is going to
be asterisk for both of them so that you know we don't see the plain text when the person's typing in
their password.
So that's one.
Secondly what I'm going to have to do is still retrieve the actual user from the database right.
So I'm going to have to say var user notice not underscore user this time just user is equal to be a
dot and say users dot first or default and then lambda expression where I say cue arrow and then cue
Dot and I just want where that I'd be in the database matches that I.D. that is in my current user object.
Right.
So are those too much I want by that user.
And then I would say that this user that I just retrieved to the database so the connected to the database
here I'm seeing set that use it that I just retrieve to have the new password and then see if that change
is right.
Of course we want to as is you.
As is customary grab all of that instead of I try to catch.
Right try.
Try tab twice and then we're trying that operation I mean once that operation is successful we show
a message box to see that the password was reset successfully.
Of course you don't want to just print Sprint what the password was was so positive was reset success
fully.
All right.
And then after that we can close the password reset window and then if there is an exception I don't
want to throw.
But I will show our message boxing that there is an Arab peace Dragon an arrow has occurred.
Please try again.
All right.
And so we should have more success this time our own.
So let's try that again someone to log in with test user and the password is kept up the password.
W R D sign one two three log in and then it's going to process process process and then it's going to
tell me I need to reset my password so then I'm going to retype test user as the password reset password.
It was reset successfully.
Okay.
And then we move on some logged in as this user as you can see it on their test user is not an admin
so I don't have Monday's users and then I can go ahead and proceed and do anything else that the test
user is permitted to do.
And so that's a nice way to you know modify how we one view and interact with users how we check if
they have the default password or not and modify how their log in experience will look there are still
some gaps and I would like for you to fix those gaps and let me know what those gaps are so fully.
Can one identify them.
Because I know what they are is just that if I was to teach every single one of them then this video
would never end.
But I want you to identify those gaps and then let me know that you think these are gaps and then let
me know how you think we could go about fixing them.
And then you know we could work from there but for now that's all we can manage users and.