Ruby on Rails 6+ Code-Along: Professional Authentication and Authorization App MVP [2021] | Yaroslav Shmarov | Skillshare

Ruby on Rails 6+ Code-Along: Professional Authentication and Authorization App MVP [2021]

Yaroslav Shmarov, Ruby on Rails Software Engineer &Teacher

Ruby on Rails 6+ Code-Along: Professional Authentication and Authorization App MVP [2021]

Yaroslav Shmarov, Ruby on Rails Software Engineer &Teacher

Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
54 Lessons (6h 22m)
    • 1. 01 01 introduction

    • 2. 01 02 create development environment, install ruby on rails 6, create app

    • 3. 01 03 push application to github

    • 4. 01 04 PRO TIP ssh connection push to github without re entering password

    • 5. 01 05 hello world generate a static page

    • 6. 01 06 connect heroku run application in production

    • 7. 01 07 PRO TIP delete changes, undo commits

    • 8. 01 08 AWS no space left on device add 20 gb storage

    • 9. 02 01 Install bootstrap with yarn and webpacker

    • 10. 02 02 Bootstrap basic usage

    • 11. 02 03 Install and use Fontawesome icons

    • 12. 02 04 Responsive screen width

    • 13. 03 01 gem devise basic installation

    • 14. 03 02 navbar with bootstrap fontawesome and devise, partials, messages partial

    • 15. 03 03 customize devise views with bootstrap

    • 16. 03 04 devise confirmable

    • 17. 03 05 users index and user show pages

    • 18. 03 06 devise trackable

    • 19. 03 07 create fake users with seeds

    • 20. 03 08 redirect user to specific page after sign in

    • 21. 03 09 users can be deleted

    • 22. 03 10 devise lockable

    • 23. 03 11 users can be banned and unbanned

    • 24. 04 01 gem omniauth google oauth2 social log in with google

    • 25. 04 02 gem omniauth github social log in with github

    • 26. 04 03 gem omniauth twitter social log in with twitter

    • 27. 04 04 gem omniauth facebook social log in with facebook

    • 28. 04 05 display user data from social log in

    • 29. 04 06 Social login in production

    • 30. 04 07 credentials and encryption

    • 31. 04 08 Make credentials work in production (heroku)

    • 32. 05 01 Create and edit User roles

    • 33. 05 02 assign default role to user after creation

    • 34. 05 03 Authorization only admin user can edit user roles

    • 35. 06 01 responsive tables with bootstrap

    • 36. 06 02 Disappearing flash messages with toastr

    • 37. 06 03 footer at the end of page

    • 38. 06 04 styling for true false values

    • 39. 06 05 styling user views

    • 40. 06 06 3 ways to change background color for the app

    • 41. 07 01 gem devise invitable create and invite users to the app

    • 42. 07 02 devise invitable docs and views going deeper

    • 43. 07 03 button to Resend confirmation instructions to unconfirmed users

    • 44. 07 04 button to Resend invitation to unconfirmed users

    • 45. 07 05 Authorization for resend confirmation instructions

    • 46. 07 06 Authorization for resend invitation

    • 47. 08 01 gem invisible captcha no bot sign ups

    • 48. 08 02 sending emails in production with Amazon SES

    • 49. 08 03 gem exception notification receive emails if errors in production

    • 50. 08 04 rename app from ruby gems bootcamp to superauth

    • 51. 09 01 user name can be edited

    • 52. 09 02 strong params only admin can edit roles, any user can edit names

    • 53. 09 03 strong params authorization user can edit his own profile

    • 54. 10 01 user can not ban himself

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

When creating a Web application, you usually have to start with the two key elements:

  • Authentication - User log in, user account management.
  • Authorization - User roles and permissions.

Code-Along and build a Web App MVP covering all aspects of Log-In, User Management, and Role-Management functionality.

Core topics covered:

  • Basic authorization via email (Devise)
  • Social log in via Google
  • Social log in via Facebook
  • Social log in via Twitter
  • Social log in via Github
  • Devise confirmable
  • Devise trackable
  • Devise lockable
  • Devise invitable - Inviting users to join the app via email
  • Banning users
  • Deleting users
  • Editing user profile
  • Managing user roles (admin, teacher, student) without any gems
  • Role-based access to different features (example: only admin can ban a user) without any gems
  • Blocking bot registrations 
  • Sending transactional emails in production (Amazon SES)


  • Chapter 0 - Introduction
  • Chapter 1 - Hello World. Install Ruby on Rails. Git.
  • Chapter 2 - Basic styling. Bootstrap. Fontawesome.
  • Chapter 3 - Advanced User Authentication, User Management
  • Chapter 4 - Log in with social accounts
  • Chapter 5 - User Roles and Authorization (without gems!)
  • Chapter 6 - Styling the app
  • Chapter 7 - Inviting users via email to join our app
  • Chapter 8 - Preparing for production
  • Chapter 9 - PRO FEATURE - Strong params authorization
  • Chapter 10 - Bonus features, Adjustments and Improvements
  • Chapter 11 - Next Steps

By the end of the course you will have created a boilerplate, based on which you can build any business application of your dream.

This course can be interesting for Ruby on Rails developers of all levels: for beginners and for veterans.

As a beginner, you will get the whole experience of thinking and building the core lifesystem of any modern Web Application.

As a veteran, you will get acquainted with some exquisite approaches for problem-solving, and features that you could have not encountered in the past.

We are not going to cover the fundamentals of what Ruby and Rails are: there are other, more basic courses for that.

Instead, we will dive straight into coding along and building our application step-by-step, feature-by-feature.

As well all enrolled students will have access to the source code, and support materials

Demo of the final application

Any questions or hesitations? DM me on twitter

Looking forward to seeing you inside the course!

Meet Your Teacher

Teacher Profile Image

Yaroslav Shmarov

Ruby on Rails Software Engineer &Teacher


Hi, I'm Yaroslav, a Ruby on Rails Developer and Teacher.

10 years ago I started out by building language school management "software" in MS Access for family's business. I knew there should be a better way in "the magic world of programming", so I spent years learning until I finally released my first real software product, that the school has been running on since 2015.

Today I develop commercial CRM and SaaS applications with Ruby on Rails. I've also won 7 hackathons building fascinating projects with this technology!

Nowadays, thanks to online courses like this one you don't need years of theory to start creating meaningful software.

I love Ruby on Rails for it's simplicity and speed of development: you have the frontend,... See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Your creative journey starts here.

  • Unlimited access to every class
  • Supportive online creative community
  • Learn offline with Skillshare’s app

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.



1. 01 01 introduction: Hello, my name is Yaro and I will be your instructor for this course. Now, then create an any Ruby on Rails application. There are two critical things that you have to take into consideration. Authorization and authentication. Authentication is all the aspects of user login functionality. And authorization is given uses different roles and permissions to access different parts of the application. So I invite you to look at the screen and see the application that we are going to go the long and built step-by-step feature by feature. Now, you see we can log in with a different social accounts. And lets say we will look in, for example, with Twitter login in. And here I've looked in and I see my personal profile. Ok, let's have a look at all the users. And there are two uses in the application. He has the first user, here's the second user. We can see the roles of each user. So these are the user is an admin and the student, I have logged in as a student and you see I have my social image from my social media accounts from which I logged in. Now I can see which use bob band, which funds ball confirmed and so on. I can edit my self. So I will go and edit. I can change my name. Let's say I will change my name, I will submit. Okay? And you see I can also have these actions TO ban, ought to delete. Now if I try to bend this other user, I am not authorized to do it. If I tried to delete this other user. I'm also not authorized to do it because I am not an admin user. Then I can invite the user to join the application. Let's invite somebody. Okay, send the invitation. And the invitation has been sampling. I will go to users and I see that this new user was graded, but he's not confirmed. He didn't accept his invitation. And I can actually resent the invitation instructions. Now I can also search by any user, by a part or by who'll e-mail. So I will say at example, and I can find this user. I can also open that personal profile of any user and seek His personal information. Now if I look in as another user, if I log in as an admin. So it'll be with GitHub. This is the account that has an admin role. I can go to edit once again and you see I can also edit roles. So admins can edit roles of different users, but simple uses cannot edit other roles. Now, I can ban any user. So see, I have been this user. I can unbundle user. I can delete users and basically do anything I want for the end-user. So we are going to create an application in which we can invite users, edit uses, band uses, delete them, track that information, change their personal information. And it's a great boilerplate for any Ruby on Rails application that you want to build on top. So I invite you to join the cause and see you inside. 2. 01 02 create development environment, install ruby on rails 6, create app: Hello. This is the first lesson. And what we're going to do is we're going to install Ruby on Rails. Now, for the purposes of this course, we're not going to install Ruby on Rails on our local machine. We're going to do everything in the cloud. So for me personally, I'm using a Windows computer and it is much more comfortable and easier to do everything in the cloud than install anything for software development on my local machine. So for this, I'm using AWS Cloud nine. And here you can see I've already logged into AWS. And in the meantime, you can also create an account and log into AWS. And then you log in, you'll have services. So I opened services and I go down to develop a Tools. And here I have Cloud9. So I'm opening Cloud9. And here they're going to create a new development environment that we are going to install Ruby and that they are going to install Rails and where they're going to do our development and everything connected to our Voc with Ruby on Rails. So here I'm going to create a new environment. I press great environment. Let's give it a name. Let's say groom beam. Jan's mood can. Okay, now if we go to the next step, and here they are going to select Ubuntu server. Now this is important, not Amazon Linux moved to server. It is going to affect the wave install everything else in our development environment and other press Create environment. And it can take a minute or two for the environment to be graded. Now regarding the price, and basically you've just created your AWS account is going to be fully for the first year. But after the first year, basically I paid lottery dollars per month for all my usage. So because your choice, either you can stop install Ruby on Rails locally or you can do it in the cloud is idle. Now, I will leave a couple of links. So that's going to link to go Rails batteries and instruction on how to install Ruby on Rails on your local machine for Ubuntu, Mac or Windows. But I definitely don't recommend installment on Windows, but because it'll take you quite a long time and it doesn't pay off. It's much easier to build the development in the cloud toiling. So now you've seen we've created this environment. Now we are connecting in just a moment. Okay, so here is our cloud nine development environment. Basically, we have a file structure, will have console, and have a place fabric and view the files and added them. So here I will press, read me. Let's see. Here we have a file. They can. Delete something we can type something you control, as you see it was saved out w, we exit this file. So basically it is a normal development environment. And now I'll just customize it a bit. So now we have our file structure and we have our console. You can open any file and it will be in the separate tab from the console. And we can use it as editing files you like. Okay, so now we're going to see it. We'll really have Ruby and Rails installed. Let's type ruby version and Rails version. Now you see we already have Ruby six month Reagan's told from the box and Rails five, but these are outdated versions. Now there already exists a Ruby version. Let's see, 2.7.2 and trails version 6.1. So now we are going to install the latest version of Ruby on Rails. And here is a small blog post that I wrote, but there are all the tips and prompts on how to do it quickly. So let's see what are the enlist doors will type are either analyst and will give us a list of all the rhombic oceans that we have installed. It's another going to install the latest version. I've m install Ruby 272. Okay. And all their install the latest version of rail Ruby. So C, it's going to take 30 megabytes of space. Okay, it has been downloaded. Now I will press Control L to clean up the console. And let's type either analyst, you seem have two versions of Ruby installed. This font that they're asterisks is the bonded pair using by default, it's not going to change the default version. We will say, I am default, use 2.1.2. Okay. And if you type are they enlist the seal this asterisks on newer version. So nobody can total delete the old version or the M uninstall 2.6.3. Okay, and now we are going to install the latest version of Rails. So there's going to be gem install rails 6.1 as it is set on the official website. Ok. And now it can take couple of minutes to install Rails because it has quite a lot of dependencies. So I will pause the video now and come back when Rails is downloaded. Okay, some of you see that the Rails was gone loaded and we can type rails version and we have the latest version of Rails installed. But now there are some additional dependencies. The finito download and install for Ruby and Rails six the Belk correctly. So they're going to run this command. And this one then sudo apt-get update to update our system. And now they're going to also install Postgres QL. They're going to install reddest and John, that we all need for urban rail six to work correctly. So they want to install 30 megabytes? Yes. Enter. And I will wait for another minute for it altogether installed. And that's basically it with setting up Ruby on Rails six. Now we are already going to be able to create our first application. We'll just wait until it installs. Also, you will have the links to the files that we use right after this lecture. So in the next lecture, there are links to this blog post to installing Ruby on Rails locally and so on. Okay, so we'll put installed Postgres scale. Another cannot command you conflict version. First all press Control L to clean up the console. And we see we have postulate scale than 0.15 install. Okay? Now I think they're ready to create our first true morale six obligation. So let's do it. We will type rails new and often UV give the name of our application. So let's name it the gems bootcamp. That's unlimited, RubyGems bootcamp, and will need to select which database you want to use for our application. Now they are also only going to use Postgres girl, none other. So minus d postgres SQL. So it is basically the most popular database in Ruby and Rails in 1020 Yvonne. And most of the new projects use both grayscale and I highly recommend using grayscale and nothing else. And it will be much more easier for you whenever you create a new Rails app to add this database was grass girl. It'll make working easier. So now they're creating our first Ruby on Rails application. And you can also take couple of minutes because we are installing all the prerequisites now is you create the additional Ruby on Rails applications tend to be much faster because it will have everything necessary already pre-installed. But now they are again creating our first application and it will need some time to download all the files that I need for Ruby on Rails do run properly. Okay, So it took around five minutes. And finally we have our urban rail Six application created. So let's see if it actually works. Cindy. So we will go to this folder CD, RubyGems bootcamp. Now, I'm not going to type the whole name. I just start typing. Let's say are you and I press Tab and it automatically finds this folder. So okay, I open this folder and let's try typing rails server to start the application and see if it works. Now, I started the server and proceed the application running. We'll go to Preview, Preview running application. Let's open it in the browser. And here we have this error logged host. So they're going to add this line, the owl Development dot RB. They're going to open our application. I'm going to config and environments development RB. And here we are going to add this line. So basically they are vitalist and thus adress that AWS generated for us for running the application in development. So I will see the server off Control C and Rails S fonts again. And we'll see if it works. I was taught and have this role. Ubuntu does not exist. So we've created the web installed grid scale, but they didn't set it up properly. So to set up postgres scale problem correctly, they're going to go and run this command. Sudo SU postgres. We're going to switch the server off. Control l sudo SU post crust, solo exhibition, PostgreSQL ONE. Then they're going to type Craig user interactive. Then we'll name the user Ubuntu VI exit. So when we did run these commands to basically finished installing Postgres girl. Okay, now we will restart. And database does not exist. So they'll need to create a database again, control C, control l, and the type rails db, Great. So they are greater than our database for our application. So see, the database was created and novel start Rail server once again. And yay, you're on rails. So they have successfully created our first Ruby on Rails application. And that is it for this lesson. 3. 01 03 push application to github: Okay, so in the previous lesson, the credit, our first urban rail Six application and not have all the Skoll generated, prevented bound some changes in the files, for example, in development dot RB. And now we want to save all our changes. Now usually in software development aerobically uses good for saving and tracking all the changes that they did in the code. So we are going to use github. Github is basically a website where you begin upload, allow code and track all the changes on older versions of the skull. So here I'm already logged in and I encourage you to create an account. And if you already have an account, then you go to your profile and you go to plus and create a new repository. So you create a new repository and you're going to give the name to this repository so they can named Ruby gems bootcamp. But I'm going to do it not from my account, I'm going to do it from this casino account. And now you can make it public or private. I'm going to make it private. And I'm going to create this repository. Now, there's going to be a link of the list lesson to a form that you can fill in. And if you fill in this form, I will give you access to my repository. So OK, I've created this empty repository and how am I going to use it? So here I have my code, this whole file of the application and fee, I have an empty repository. So I'm going to type git init. I'm going to show you the server off Control C, Control L to clean it up and get in it. Now I'm going to type, basically, let's type git status. And here we see all the files that were added and all the folders. So we're going to type git, add all get at minus a. And if I type git status once again you see everything is growing. So all the files, we'll add it. Okay, and now they're going to type git commit m. So git commit to master or domain. And we're going to say initial commit. Okay? Now if I type git status, the scene on brain, brunch Martha, nothing to commit. The country is clean. Now we're going to add this remote branch. We're going to connect this remote repository to our application. So I type this command. Let's see again, you get status. Okay? And I will type git push origin Maine. Let's see what happens. Okay, it says failed to push. Now I will go back and theta looks like identity type, git branch and Maine. And again, I will add this remote and a type git push. Okay, so yes, I basically just forgot to type git branch and Maine. So my username for GitHub is going to be my email and my passport. And now all the application has been pushed up to GitHub. So all this gold. So if I go to the GitHub repository, I refresh. And I see that all the code was boosted to GitHub. So you have a copy of all the code on GitHub, all the changes that you did locally. So that's it. We have just created a GitHub repository and post our code down. 4. 01 04 PRO TIP ssh connection push to github without re entering password: Okay, so now we have pushed our code to GitHub and you can see it here. Here is our repository. We see there was an initial commit, the opening, and we can see what Executive Information was committed. So basically, everything that is automatically generated when you create a new application. And you see the comment was made by Ubuntu. So it doesn't say Your nickname or whatever and doesn't show your avatar. So to show your personal details here, they're going to have a couple of commands that will add the command git config global username, and you will add your username just here. And the same video, email, git config global user email, and you will bus in your email. So all the next comments that you make will be shown with your name and email. Now, also, remember that when we made the push to GitHub and you type git push, we had to type in our username and our possible. And if they don't all Kohlberg, it can become not to their most pleasant experience type in your username for GitHub and possible each time you want to make a push. So not to have to type in your username and password all the time. They're just going to connect via, as a stage, it is a more secure and correct way to connect to github. So here also have a small hint, a small guide on how to connect sage soul. Let's go and do it. So they're going to generate a key with your email. So as SHE region and type in my email address. Okay, under the file in which you will save it, I'm going to save it just in the root. So I press just enter. And the passphrase. I ended up passphrase, I'm under the gun and ampere. Okay, and here we have created a key. So they're going to give the skied to GitHub and they're going to authenticate ourselves to GitHub, this secret key. So what do we do next? We are going to basically and mosquito that SSH agent. And they're going to add the scheme does h. Okay? And next we're going to open the scheme. So I'm moving to the scheme. I have dot PUB, I open it, I have the scheme, and I'm going to copy it to my GitHub settings. So here I have a link to GitHub as a sage. I'm going to paste this information that I got from this ePub file. So how they open the spot file, I created an SSH key, run this command. It gave me an ID file. I opened it. I open it. I put it here in the US sage. And I will name this SSH key as Ruby gems boot camp. Okay? And here I've created this new SSH key. And now Wilczek, if it folks. So I'm going to type as HD and get at Now Control L. I'll show you a token that yes, hello, you've successfully authenticated, Okay, now I got git push and I still have to put in my username via that. So because if I type git remote v, You see I'm connected to GitHub via HTTPS, but not via SSH. So now I'm going to change the HTTPS connection to SSH connection. So there's also a small tip here. I'm going to say git remotes that oral origin. So good at GitHub, basically this is the thing that sets as age but not HTTPS. So like this. And next I'm going to have the username and the repository. Dalda get. So git remotes that oral origin get at cause ego, RubyGems, boots, bootcamp. Okay, now type git remote, v one scan. And here you see I have origin at good at, not HTTPS. So now they're connected by as a sage. So Control L and I will type in git push. So now I'm trying to push once again to get hot. And you see I didn't have to type any usernames or muscles. It automatically tried to push to GitHub. But as evidence up to date as we then make any changes, there was nothing to convert. So basically what we did now is we assigned a username to our user in this environment so that when the next comment is going to be built from Ubuntu, but from your username and reconnected to git hub via SSH so that we don't have to use any possible in the future. That's it. Thank you. 5. 01 05 hello world generate a static page: Okay, so now we have connected GitHub and let's try to start the server or the application once again, sorry, type rails S. And here is the Iranian server application. So we see that they have been static page. It's a blank application and now they're going to create a couple of pages on our own. So they'll speed of server off and type rails generate. Controller will name the controller static pages and interdict pages. We're going to have, let's say a two different pages. One is going to be the landing page. And the second one is going to be privacy policy. Because most of the applications nowadays have to have a privacy policy to work correctly. So what is the door? Ve generated a few different files. If they go into the app folder, we see in controllers that we generated a file called static pages controller. We have two methods here, two actions here, London page and privacy policy. And if we go to the US, we have a new folder called static pages. Fun file is London page, and the second file is privacy policy. And in this basis we can have simple HTML and they can edit it just as good bond. So how does this work? Now we're using we've created a controller and views. And we also have some changes in a file called roots. So if we go to config and called the GAVI have roots. So these two lines, both medical injected get static pages slash London page and get static pages slash privacy policy. So if the start our server and go here. If we go to slash static pages, slash landing page. So slash static pages slash landing page. What will happen? Let's see, let's fade. Yeah, so you have this static HTML rendered from this landing page, static pages, landing page. Here it is. So how does it felt? Basically, we have our roots. So it is our kind of Arles, both the type in the browser. So we have a static pages slash London page. And this path looks for the controller name static pages. So the go-to app controllers, static pages. And in the static pages controller that have London page, the Lenin Page Action. And as we have our views, in our views we have a folder called static pages. Here we have a landing page and privacy policy. So the application by default than colon London page would render this London page view. So we can edit this Lennon page just as we want to go to this page, HTML dot ERB, we can type in something like a h one. So header is like big text. And here we'll have hello. Felt. Refresh. And here we have, there's just hello world. So like this beep generated to static pages. Now let's also add some basic navigation. So we are going to have links to different pages. Let's say on the London page will have a link to the privacy policy and then privacy policy. And we'll have the link to Lenin page. You have the type, the villa type equals link to. Then we will have privacy. Always seeing. And it will have at Boston privacy policy. Now to how denote which buffer. It will go to slash roots. We'll see all the available boths in our application. So over here we have static pages, landing page, button, select various private, Suppose above. So it can be something like this aesthetic of pages private. Suppose. Now you see that this kind of code says that inside we will have Ruby code and this link two is a Ruby method. So if the refresh and go to 30 pages, landing page, you have this link to privacy policy. You will press this link. Building medical, we'll go to static pages, privacy policy page. And just like this, in our privacy policy, we're going to have a link to our London beige and static pages, landing page. So you see, we have all this multiplication, the two different pages, and we can navigate from one page to another. Now, once again, how does it felt in our browser? And we are on our website and we have some kind of oral oral. Their application understands that static pages is a controller and privacy policy is an action with a view. So here we have a controller, static pages and landing page privacy policies are actions with views. And inside this views we can have plain HTML and we can also have elements of Ruby code. So that's basically it. But now let's do one more thing. Let's change the default oral. So see if you don't have any slashes. We have just our application. We have this default Ruby and Rails page. And if we don't find it, let's say that we want to see our landing page by default. So we will go to this route's file. There it is. And Hebert, we'll add a route buff. So we'll say root. And the root will go to static pages, landing page. Now note that here the c, not the path, not 30 pages slash London page, but they're controller name and the action name directly. So let me refresh the page. By default we have this root page. And if we go to static pages and we have nothing. If you go to study pages, landing page, they have London page. If you go to privacy policy, we have privacy policy. But again, the static basis thin doesn't look real nice. And if you don't need Ireland and page rendered both in the default rule and in static pages. Solver can move of the Second World War. And now we refresh. And you see you will have only two pages left, stick pages slash privacy policy. And you see this linked London page doesn't work anymore because the spot doesn't exist anymore. So the path was deleted from roots, the spot from rules, and it doesn't exist anymore. Okay, so we're going to remove this code. And let's see, we have our static pages privacy policy, and we have our default page. Now, let's make it so that if you don't have to have that controller in the oral mankind to access privacy policy. So they're going to go back to our roots. And once again, they're going to save unlike gap, the privacy policy, doom, static pages, privacy policy. And the refresh and you see it is kind of a shorter oral. So I said, we don't need to go to static pages slash privacy policy. They go directly to privacy policy and get the controller name static pages and the action named privacy policy. So here is our privacy policy page, and now let's once again make the links Voc. So here we'll have, we'll have a link to London page and it's going to be just root of. So we have this rule. They can just make it like home. Link to home. And here we don't have the static pages private suppose, but they'll just have privacy policy both. And you can check it in our routes sludge rules. Here we have our root path and privacy policy above that links to the controller name, static pages and the action named privacy policy. So they're going to London page and here they're going to have just privacy policy buff. Now if we go back to our application and here we have our landing page, hello world and linked to the private. Suppose they're gonna go there, they see that brother, suppose a content and a link to go home. So now we have two pages in our application, and it looks quite nice. Now, let's save our changes and commit them to github. So I switched the server off, Control C, Control L to clean up. And I type git status. And here are all the changes we did. Now we see in the routes.rb, the added all these lines than in static pages, a CSS file, we didn't do anything and they're not going to use this file. So we're going to check it out. Basically, they're not going to have it anymore. Once again, I press git status or actually we're going to remove it. So we don't need this file. Now once again and get status. Okay, then folk, I will go there. Total assets, stylesheets, deletes static pages as CSS. Now again, Control L git status again, then static pages controller. And static pages controller. The basically credit this controller and two actions to view an action to view the lemon page and an action to view the privacy policy. Next, the credit aesthetic pages helper. The I'm not going to use it now. And created a folder in views slash static pages. Soap uses static pages, and here we have two HTML pages. And we also created a test page. We're not going to use it either for the purposes of this lesson and from help us, we can also remove our static pages helper. And then I'm going to use it in the near future. So git status. Once again, what did we do? If we changed our roots? We created a controller and we created a folder in our views. Okay, let's save and get at all git status. We see all the changes of all kind of edit to get nominated to comment them. Git, commit domain. And we are going to say rails generate controller static pages. Okay? And the diver, good push. And you see we didn't have that type a possible. It was automatically push to GitHub. So I will go back. I'll go though our application on GitHub. And let's see you seem I see my name. I am the one who made the comment. And the C rails generate controller static pages. If I go to the commit history, I see this comment, I open it. And I can see all the history, all the changes that made the urine this lecture. So basically like this, we can see all the versions of our application and all the changes to the goal. And that's it for this lecture. Thank you. 6. 01 06 connect heroku run application in production: Okay, so now we have created our application that has to Pages and let's make it visible to the whole internet. So let's push it to production. Now to push obligation to production, they're going to use Heroku, So this is an upside on which you can host your application for free. So you need to look into Heroku. I've already done it and here is the list of applications that I have running. And when you're done, you can go back here to your application and you can type Heroku. Afraid. Now you see we didn't install Heroku, so we need to install Heroku. So the snap install Heroku. And we will add the classic and the end. Ok, so Haruki has been installed. We can take a few seconds. Okay, now V type heroku create and it says invalid credentials provided. So I need to look in. You'll see I'm prompted to log in. I have this link that I can open in the browser. Has all Gulag in, actress look in, and I get this IP address mismatch. So this is a quite common era. And what I'm going to do, I'm going to type control C, And I'm going to type heroku login minus I. So they're going to log in through the console. I type my email and my password. Let's see if it folks. Okay, I logged in. And now finally I can type hero crate. And you see an obligation was created and was given a random name, limitless temple, whatever. If I go to my Heroku dashboard and refresh. Let's see if this application for adult here, I'm Kevin, have this limitless temple. Ok, and if we open this application, so if we go to this open app, or we can open it by typing here. By present here. Press open. You see Heruko welcome to your new app. So all this is a blank application. And now we're going to push our application to Heroku. So how are we going to do it? Whatever type git push, heroku master. And it says fail to push some refs. Okay, let's try git, push heroku main. And now it works. Previously it was monster, Now the main. So it will take also around five minutes proposal application to Heroku for the first time, for it to be created and for all the dependencies to be installed. So it will continue. And for now I'll press balls. Okay, and obviously that humans have passed and application was finally pushed to Heroku. So if the refresh this page, we see Hello World. And at this address, application is accessible to anybody in the internet. Now we can also give this application button name. So we can say Heroku rename and we can name it, for example, Ruby, gems boot camp. And it was renamed. So we go to the new address. And here the applications available at the new address and not available at the old address. So now the successfully managed to push our application to Heroku. And you can show this address with anybody in the internet and they will be able to access your application. Now, I go to this page of the application in heroku. Lets have a look at it. I go to my applications, I see RubyGems bootcamp, and thorough old tales of the application. So on the main page, if you consider overview by using Heroku Postgres scale, we've done been push, so van deploy. And we consider logs as well. If we go to resources, what can we see? We see that we are using Heroku Postgres and we can add additional add-ons. You can go to find more add-ons to civil they offer in deploying. And we can also say that can automatically Bush to Heroku whenever changes are made in Github, how do we do it? We go to deploy GitHub and select tribal name, and it will be Ruby. Now in my case it will be casino. And I will look for boot camp. So I found this application. I press connect. Let's see. Okay, now choose a branch to deploy. It'll be Maine. And I press enable automatic deploys. So whenever I make any changes in the application and push them to GitHub, there will be automatically pushed to Heroku. I don't have to type git push heroku master on my own because it'll automatically pushed from posts from GitHub to Heroku whenever I push changes to GitHub. Now let's go to metrics. So here I don't see anything because it is available usually for beta versions of Heruko activity, again, restored in the overview. It is all the changes that were made. Access it is you can grant access to the application, talk to users, and incidents. You can add a custom domain. You can upgrade the stack. You can change the name of the application. You can delete the application, transfer their application to somebody else. You can pause the application. So basically eyebrows maintenance mode on. And if I go to the application, you see it says offline for maintenance, I switch it off. And the application continuous Burkean. And here you can also connect the custom domain for your application so that it will be available not at RubyGems, Bootcamp dot But if you buy the domain, RubyGems, then it will be available at this domain if you set it up correctly. Now, we're not going to do it right now. So basically, we've deployed our application to Heroku, to production. It is available to anybody in the Internet. And we made a small overview of how Heroku box. So that's it for this lecture. Thank you. 7. 01 07 PRO TIP delete changes, undo commits: Okay, and now they're going to go through some more tips. And then using Git and GitHub. Here we have our repository how application, and let's type git status. So that won't any new changes made since the last Bush. Now lets say we will go to our readme and good African and type something else. Okay, they'll go to type git status and MVC, the redundant was modified. Now let's take this db folder and let's say we'll delete this seeds.rb. Now type git status, we see seeds or B was deleted. So put a pebble to revert these changes. All good. Clean. And git reset hard. Okay. And the changes we're reverted just like this so that Git status and no changes were made. So this took Man's good clean FDI together with git reset hard, will revert any changes you made since the last comment. It is really helpful when you want to dry and dusty different features and undo them later on. Ok. Now the Muslim lets say we will change our domain and we will save our changes and push them to GitHub and git status. Get all git commit muster. Thus the comet and git push. Okay, we pushed it to GitHub. Now let's go to the GitHub repository. And here we have this three comments, but they don't really like this comment. So let's delete this comic completely. How are we going to do it? They're going to do it like this spill type git reset had and git push F. So git push force, basically, Weibull opened our repository at the version of the previous comment, the previous comment to the last one. So rails generate controller static pages. And we've boosted the current version of the application and this previous commit to GitHub. So I will refresh. And you see this previous comment was totally deleted. So it can make the general experience of working get easier as well. Let's try one more thing. Let's say we will edit our rebellion and get at all. And git commit master, dust. Don't. And we'll say git status. You see we are above the head of our previous committed files by one comment. And what we want to edit this comment. So we made some changes in the comic, but we want to basically undo it and continue editing this comment. So we'll type git reset, soft head, vm. And let's see if it folks. So you see with unchecked VIP on down the, the previous comment and we continue, can continue editing it. Using git status. We will make some changes to the file and get status. So C, two files for modified. Now we can add to GitHub once again and push. And let's see. So people created a comic. We have undone the comic and committed once again. And now again, as we were doing this all just to learn how to use a good savings. V are going to undo this one last time. So I'm just going back and typing git reset. Ok. So now been lost time, they're going to delete the last comment that typing git reset had. Hope and git push F. So let's see. We'll go to our repository and you either see this comment does not belong to any range because we deleted it from this main branch. So here we have just two comments. And that's basically it in this lesson to learn better how to save changes, how to undo changes using deep. 8. 01 08 AWS no space left on device add 20 gb storage: Now, while talking of AWS Cloud nine, at some point of time, you can have a red message that you're running out of space and that you need to resize your environment. So here's how you're going to do it. Basically, here are a couple of links. I will add them in the description that will help you. So first, needed to create a file called the resize dot SH in the root folder. So I'll just here New File, okay, and not inside the app, but inside the Root Folder. New File, resize dot h. Okay, then they open this file. And based on this contents inside, it's basically stopped that was given by AWS on their own and run this command. So I pasted this information I saved. Now I'm going to the environment folder and running this command, SSH, or size as h, and the size is going to be 20 gigabytes. So at the moment, if we go to our AWS dashboard and go to EC2 and two instances. So here are all the instances I have running all my Cloud9 environments, but most likely will help just fun. And if the go-to volumes right here, you will see the size. So by default it's going to be eight or ten gigabytes for you. And this environment is named RubyGems bootcamp, in my case. And it's the rubygems bootcamp is the first one. It has ten gigabytes by default. And now I'm going to make it 20. So around this command, It's running, its resizing. And okay, it's done. Now let's have a look here. I will refresh this page and it must be 20 gigabytes. Let's have a look and see that it is RubyGems bootcamp. And the size is 20 gigabytes. Okay, looks good. Now we'll go back to instances. And we will rearrange this instance. So I selected actions, instance sudden. Now note here, yeah, it does Instance state remote instance, Andrew Bolt, just to definitely know that all the changes are taken, effect successful rebooted. I'm going back. You see, they're reconnecting and a virile connect than our space issue will be obsolete. So they're going to have enough space for all our development needs. 9. 02 01 Install bootstrap with yarn and webpacker: Okay, so here is our application, and now it looks through the basic theory, just two pages and there isn't any, any styling. So before we continue to add real Ruby on Rails features, we'll add some basic styling selected is more comfortable and more pleasant to use the application. And for this, we're going to use the CSS library called Bootstrap. Basically it provides a lot of different beautiful clauses, CSS classes that we can use for making our application look modern and stylish. Now, how are we going to install it in Ruby on Rails five. And previously you would use Jiang, something like Bootstrap region. You would add the gem to our Gemfile. And you've John bundle and import the CSS and JS. Bach. As we're using Ruby on Rails six, we're using yarn and backpacker. So John is a package manager and we can directly install Bootstrap using yung without needing any gem. So they're going to run yarn at Bootstrap. And couple of more commands. Actually doing stole urban rail, bootstrap on Ruby on Rails six properly. They're going to follow the small guide that I wrote previously. They're going to install, they're going to add the John at jQuery and Bootstrap. So then going to need jQuery and Poppa Jazz for Bootstrap drawn properly. So I'm switching the server off. And I type beyond abject very Poppa Jazz and Bootstrap. Now they are being added. And let's see what has changed git status. So that file package JSON was modified. Here it is. And you see bootstrap, jQuery and poverty as possible added. And the file John Locke was also edited. Okay, now next, they're going to create a new directory style sheets inside App JavaScripts. So here we have our app. And the app, you have JavaScripts. And inside Jo's groups, they're going to create stylesheets directory. So make directory and the name, the directory, and you see it was created from the console. We didn't have all created by hand. And inside this directory, there are going to create a file application as CSS. So here it is, and then enter the file application as CSR's. Okay. Now in the file environmental js, we are going to add the following code. They're actually going to replace the gold with disco. So you see I opened the search bar and how did they do it? I press the Control E and you see I'm in the search. So I type environment and I see Environment j, us. Okay, here it is. And I will replace the scold basically and add inject vary. And Papa gs to the environment JS. Okay. Now they're going to go do our layouts. Dog, use layouts, application HTML. And here we are going to add one more line. It is going to be style sheet back DAG application. So what does it do? It basically says that we will go to our backs to JavaScript and the AED application SCSS toga initializing this file. Now we have an obligation assessors in assets, stylesheets application, CSS, and we have style sheet back DAG. You see JavaScript Baghdad in JavaScript's backs, application JS and stylesheet back dug in JavaScripts. Style sheets, obligation as SSS. Okay, and now in application JS, they're going to add the Bootstrap. So I'm going to application JS. And inside here, the add-in Bootstrap JS, Bootstrap CSS, and the require this file obligation as CSS. So they're kind of initializing this file inside the application JS. Okay, now let's see if we managed to add Bootstrap. So I go back to the console and type rails server. And I will open it in a new window. Enter. So it's launching. You see the application is compiling. We've added some new packages, so it needs some time to compile. It was added and now let's have a look. Ok, you see the phones have changed the previous funds and the new phones as well, the color of the links and the layout, the heights, and so on. So like this, it looks a little Bootstrap and like this without any CSS unprimed. Ok. Ok, looks fine. So we briefly and quickly added bootstrap to our application. Now let's just comment out changes. Control C, control l, git status. Git add, told git commit, monster, install, bootstrap. And that's it. Now we tried to see how Bootstrap works. So let's start our server and they'll try to add some Bootstrap to our application. So here we have to use, let's go to our views. We have our static pages, landing page. And let's open the Bootstrap documentation and tried to add something. Let's go to docs. And let's save it. We'll add code. Kim have our COGS. So I'll just go with the code of a code and add it to our landing page. And you see we have a bootstrap code editor. So you will need to explore how Bootstrap folks and the real tang of Ruby on Rails projects use Bootstrap, CSS, and it is good to know how it works. They'll explore more about how Mozart folks in the following videos. But that's it for now. Vi installed bootstrap. So that's it. Thank you. 10. 02 02 Bootstrap basic usage: Okay, so we have just installed Bootstrap, and let's go back to our application. So we are in the root folder now, environment. Now let's go to the application folder, CD, Ruby gems, bootstrap. Again, I'm not going to type the whole name and just starting to type and pressing Tab and it finds the post suitable fullname. Okay, and in civic get some kind of error actually worn and required Ruby 2x three is not installed. Console run this command. Okay, what does it give us this morning? Let's see, in Gem file we have Ruby to 72, but here we have this other file, Ruby version. It says 2x three. So simply, in this file we will replace 2x three with 272 because anyway they are using to 72. Okay. Let's go back and see if they have the spawning. No, no bone-in anymore. Okay, now let us start our server. Now Civic at this orange message because of Jim seasonal data. So let's go to our gem file and can have all the channels that they use. At the moment. We have Rails was grayscale, Boomer for the server, sauce and so on. And we get this orange message from the seasonal data. Generally, obligation can join fine without this jump. So if you want, you can just remove it, run bundle update and you're fine to go. Okay, so back to our application. He has our app. We have two pages, HelloWorld and private supposing. So the root page and privacy policy. We've installed bootstrap. So what can we do with Bootstrap? Let's see. I just wanted to documentation and we can add the different elements. You see, a bootstrap gives us a class called container for example. So let's cope with this clause and let's add it somewhere in our application. For example, in the Latin page, let's place this all into a container. And going to London page. And I'm going to put the oldest text into this container. Okay, now we have four spaces. I'll make it two spaces. Actually, I will go to the settings and change the settings for caps to be two spaces, not four spaces. Okay. So I put all this text into the container and now let's refresh. And you see it has moved. So they're going to have some evil spacing from both sides. Now, if go Here we see also contain a fluid. Let see what container fluid would go. And you see there is a tiny spacing, but it is already much fiber. So if we look here, then you see this regular container width, for example. And this is academic fluid with but this is just one of the many examples of Bootstrap provides. So let's go to the documentation, for example, and see the components. And there are many components, there are alerts badges. Here is an example of a badge. So we can copy this badgers into our application and see how they would look. You see basically this styles and given by bootstrap. So they give us rounded the tooltip, they give the specific color. We can cope with this bottom image inside and customize it as v like. So you're free to explore bootstrap. One of the things that I really like, our navigation balls, not balls. So we can just copy our nav bar somewhere in our application. And here you have a full width functional navbar. Now I will paste it on the beginning of the space, for example. And have already have a page that looks something like a website with an f bar. Of course, the links are not clickable yet. They just lead you to the same path as you are all now. But it already looks like something. So really the best way to learn bootstrap is to try to go through the dogs and build something on your own. And this is just a small introduction. And that's basically it. 11. 02 03 Install and use Fontawesome icons: Being a Ruby on Rails developer, your expected usual To be a full-stack software developer. So you should know both backend and some front-end and Bootstrap that we have installed is kind of a frog front-end framework. And the thing that we're going to install for front-end that is really commonly used is Font Awesome icons. So carers this website Font Awesome. And it provides a lot of icons that we can implement in our website. And let's try to install it and see how it works. So for example, here's the step site. They go to free option and they have lots and lots of icons that they can input into our website to make it look more complete, more live. So let's go to the documentation and see how it works. I go to start for free, most likely will not need that paid version. And let's see, OK, we can install it by Yang just as pre-installed on Bootstrap. And let's see. So we have this command, John at Font, Awesome Font, Awesome free. I copied. And I'll spare you the server off control C, control l. And I run this command, young elephant, awesome fluorine. Okay, it's been added. Let's keep looking at the documentation. So what else can the need? Yeah, next steps, reference to either CSS or JS. Oh, so they're going to add the in our application JS. Let's go to Application JS. They're just going to run at the command. Import Font, Awesome Font, Awesome free CSS, o, like this. So as we have imported that JS and CSS for Bootstrap, the same way we are going to import the CSS for Font Awesome frame. Okay, and now let's start our server Rail server. And let's try to add some kind of icons. Now, it's taken quite a while to start because it's compiling the new packages that we have added to our application. Okay, so let's go to the icons and tried to add some icons. Now the icons are being opened. Again, click the free. And let's find an icon called home for example. Okay, here we have home. I'll open it in a new tab. And let's go to this icon and just paste it in our landing page. For example, we can paste it next to the nav bar name. We can do it like this. So here we have home sign. Looks quite nice. We can try adding an icon to our link of the privacy policy. For example, let's go to our privacy policy link and let's turn it into a Bootstrap button first of all, so it is going to have the clause bottom, bottom, large button. Warn him like this, and we will add this icon. Now the icon needs to be added here. But two, we cannot just add an HTML icon really nicely in the text solvable. This link into a block. Basically we will have linked to private. Suppose, suppose clause bottom warning, doom. Now if we start room beam due action, we have to end it with an AMD calls. And inside we will have privacy policy. And inside we will also have this link to, let's say document will find document. Let's say file vault. Okay. Let's take that HTML file vault and added here. So here we have been linked to privacy poster that is just text in line, that is modern logic. One warning. And here we have block in which you have the HTML for the icon and that texts for the privacy policy. Let's see how it looks. And here we have two links, both lead to the same destination, but both hostile differently. One of them has also the Font Awesome icon. So you're free to explore different icons and competent into your application and make it look more lively. And that's it. 12. 02 04 Responsive screen width: Okay, and now let's see if our application is mobile responsive. So I'm using the browser Firefox. And I go to Inspect Element one scan, right-click. And here, and here I have this button to see the responsive design mode. And you see by default our application is responsive. Why is it so? Because as the latest Rails applications that are created in rail 6.1, what medical have this line in the layouts application HTML, ERB. So you see this metatag, if you bought the device width is automatically added in your new application. And it's really cool. What if we remove this bag? Okay, I removed the tag. I will start the server. And you see it's not mobile responsive. Now with the stack, the application is mobile responsive. So just like this. 13. 03 01 gem devise basic installation: Okay, so now we have an application with just a couple of pages and they are going to add our first gem. So a jump is kind of an add-on and addition to Ruby on Rails app that was already pre-coded and that can be integrated into the application. And the gem is going to be for authentication. So for login in, so they're going to let users log in and the jump is going to be named device. So the Google gem devise, and this is possibly the most popular authentication solution for Ruby on Rails. So here's the source code of this Chung and they are going to install it. Now let's go directly to the installation instructions. So they sit, get him started and they add the gem devise to our gem file. Now let's go to our gem file. And first of all, let's clean it up a bit. I'll just remove the commented out code. I'm pressing Control D to delete the lines of we don't need. And if I don't adjust so that our Gemfile looks cleaner. Again. Now it looks cleaner and at the end, and I didn't jump device. Okay, now I stop the server and Zhang bundle. So the command bundle basically installs this jump. Okay? Now the run the command rails generate, devise, install. And let's see what this command does. So it created a file in the initializers folder named Device dot RB. And it created a locales file device, English YAML, and it gave us some additional instructions. So in conflict environments development RB, we need to add this line. Okay? They're going to config and environments, development or beam. And they're adding this line basically. And the slides will be needed for sending emails in development. So for example, you won't do reset your password or get a possible conformation. And this line helps us redirect emails to localhost in development. We'll come to this back later once again than let's go and see, okay, we need to have a root in our routes.rb. Let's go to our routes.rb and already have a root page. Ok. Next we need to have flash messages. So they're going to cope with this flash messages and add them in excuse layouts application HTML. Let's go to our app. Then. Use layouts application HTML. So they are going to add them above yield. Right here. Like this. Now, let's have a quick look at the structure of this application HTML file. So the format is HTML and HTML we have had and a muddy in the head. We have different files that include stylesheets, java scripts, tags, meta tags, the title of the application. And in the body they are going to have yield. Yield is basically fund via all the pages are going to be generated. So they're removed yield than the static pages as London page and privacy policy cannot be rendered. They'll just get this page without any information under root. And this class notice and alert are different messages that we are going to get from the application like you have successful in or recorded was deleted or whatever. Ok, let's continue. We can generate device fuse, but we will do it later. Okay, let's go back to the installation instructions. So we have added this to our development RB. Now, as we are using AWS Cloud nine, V and I'm going to have host as local host. They're going to have something slightly different. So I will comment this out. And the host is going to be this oral. So I go by the URL of the application and I'm going to add it right here. So host and this URL of the application. Okay, now going back to the Docs and wanting to run rails generate devise modal. So modal is there kind of name of the users that are going to authenticate? So for example, can be clients or companies or users. The most common one is user. So we'll type rails generate devise user, control, l. Rails generate devise user. And let's see what it gives us. So it creates a migration db, migrate device create users, and they are creating a new table in our database. It's going to be called users that an email field, password field than at a field for resetting the possible. And for the remember me, Like button to remember me. Okay, and then they're adding a new modal in AP modals, user_data, RB, and the credit, a new model called user. And the user is going to use device. And it is going to be authenticate double registrable, recoverable from memorable, and validate double by default. Okay, what else did the crate, the creative task. So and, and you root, so the roots, the sea device for users. Now let's start our server and see. And the server didn't stop because they didn't run rails db migrate. Now in the old version of Rails, you would need to switch the server of Andrew run rails db migrate. But in the newest version of Rails, you don't have to do it. You just run, run pending migrations. So the migrations per run. And here they are logged into the application. The actual just open the application. They didn't login. They didn't see any links to log in, and they were not forced to look into use the application. Vice that. Let's go back to the Docs. Okay, beyond rails db migrate and we need to add some like before action authenticate user. So for example, for some looking at some pages, the user needs to be locked in. And for looking on other pages, the user doesn't have to be logged in. So we can add before action authenticate user, and it shouldn't be added in a controller. So let's go to all controllers. And we have just two controllers, ApplicationController and static pages controller. If they add this to our application controller, Let's see. Ok, they cannot see the contents of our application before the login. And you see here we have this alert. You need to sign in or sign up before continuing and have this device generated fields following in. There also have a page for signing up, a page for forgot your possible. And these are all generated by the jump device. So let's sign up. I'm going to sign up. And here you have successfully signed up. So they sign in to the application and the center contents. And here you see the nav bar was moved because we have our lobes on top of the navbar. So successful and managed to sign into the application. Let's see what else the gem devise gives us. It gives us something like current_user. So we can see which current user is logged in. Let's go to our application, HTML, and let's try to find the current user. So equals current_user. And here we have an active record, the object of the current user. So we can get something like current_user dot id or current user dot email. And the sea from which email via logged in at the moment. Looks nice. And let's also add some links to, let's say log out. Now actually I will go to my blog and here I have some links that I've saved for future use. So let's try to add them into our application. I will add them above yield. And you see I have them added in Hamel format. It is not ERB, so it is not usable. So I will turn it into ERB just like this. And we'll go through this code right away. You see I'm identities, ERB tags. And we need to have an end in the end of this if statement. Okay? And so how is it going to work? If we have a current user object, then they will see a link to the current user, email to the user. And we will see a link to log out. Otherwise, if you don't have a current user, if they had not signed in, they will see a link to log in auto register. Let's see if it works. Ok, no method for user path. Let's see what else we have in our rules. We have new user session, user session destroying New User possible path. Okay, so here are the paths that we have. Let's try. See. If we can access this path. You use a possible path. And if the press than the gut, the link to forgot your passport. But now it's not what we want nationally a page to change the email or change possible. Actually it should be added user registration path. And it will lead us to edit user. So we can edit the email the possible and change the possible and cancel all kind of delete the account. Okay? So we have our current user and we can look out. Look out, and you get this undefined method, email. Why do they get it? Because we are not locked in and we don't have a current user. And that's five. We should have this method under the if statement, if currentUser or we can already totally deleted because we already have this current user in our link. So now we're not locked into the application. And we said the slope in and register that we added on the header. On top of the yield. I will remove this current_user email. And what do we have? We have looked in register. I'll try to look in. I am locked in and have the email of the current user and they can look out. Let's create a new user. I create a new user, and now I am logged in as this other user. So it kind of works. 14. 03 02 navbar with bootstrap fontawesome and devise, partials, messages partial: Ok, so previously we've installed the gym device. Let us look into the application. And if you look in the C, the current user email and a link to log out. Now, they're going to make this navigation luke better. So in the same blog post, I have a link to the nav bar that we can use in our application. It is an EPA that I created on my own based on Font, Awesome bootstrap device, and the basic Rails links. So let's cope with this navbar and put it into our application. Now, they're going to create a separate file variable, keep our nav bar, our header. So we'll name it header dot h dot PRB and pays the Xcode inside. And they will access this header as a bombshell from our body. So we will type render. And they're going to render the partial in layouts slash header. And we can delete this previous navigation. Let's see if it works. Okay, I didn't close the gap. Okay, and here's our new navbar. So we have basically brand-name that you can change. A logo that was just my Font, Awesome icon, a link to the homepage, the name of the current user, email, a link to his account settings. And you see the current page is marked as active. So this page is active. Now the homepage is active. In the sign out. We again see the same Nepal and the look in pages active, the sign up pages active. So looks nicer. Now let's look back into the application and heavier and visit the old Nepal that we added in our landing page. So it will remove the snowball that for edit just as an example in our landing page. And looks fine. Ok, now you see we also have this space that is taken by our notices and alerts. So let's also move our notices and alerts into a partial. We'll name it messages. Messages dot HTML, dot ERB. And we will just paste in this lines into messages from the beginning and say render layout messages. And they're going to run that this message is under the header. So they don't take up space above. Okay? But now you see we have the space been taken under the nav bar. So we will say that we want to take up the space with the notice and the load only if we have a notice or an alert. So we can say if notice dot present, then we will take up the space. Else-if alert dot present, take up the space. Otherwise. And let's see. Ok, the space isn't been taken. Now let's log out and you see we get this message you need to send in Lausanne before continuing. So we can also add some kind of background motive, the try notice, background success for notice, and background danger for a load. Now this background success and danger of bootstrapper color clauses. So let's try to log in and you simply get this invalid email are possible. And you see it's already styled as red. And if the successful log in, they get this message signed in successfully. So it kind of works. We've updated our nav bar and we have updated our and we get our loads and notices. Now of course, you can easily customize your nav bar. Let's go to the Bootstrap website and go to dogs, find nav bar, and see how we can change the color, color schemes. So we can have it for example, nav bar, dark background, primary or Nakba light, and some kind of color. Let's try now. But doc Background dog will go back to our header and say Navbar, dark background doc. And you see the colors have changed. So basically we've added a nice-looking navbar to our application and we've updated our loads and notices. And that's it for this lecture. 15. 03 03 customize devise views with bootstrap: Okay, so now our application looks more alive. And two, they're going to make it look even better. So you see, these are our log in sign up and the other device views. And they start from the very, very beginning of the page. So it's really not nice. First of all, don't make it so that all the content in the page, a star is centered inside a container. So we'll go to our application HTML. And they are going to add this yield into a container. So it will say div class container. And we will input to this whole yield. So all the in-app content into a container. And you see it's already a slightly centered. So if you look out, you see the Log In and the forgot password and sign up are already kind of slightly centered. Now, if we put it into a container fluid, it'll already start again, not from the very beginning, but there's going to be some space. So it already would look better. Now, I would prefer going for that container for now. So okay, now let's look at this device views. Notice they are not available in our views because they get them directly from the gem devise. So now we're going to copy these views into our views folder. So let's go to the gym device and find that they can generate views. Now it must be somewhere here. So configuring views, rails generate devise views. So we'll run rails generate devise views. Control C control l. Rails generate devise views. And you see and you folder inside the US named device was generated. And it has all the folders, confirmations, mailers, buzzwords, registrations, sessions, Shad and unlocks. And these are basically all the available device views. So now we can easily edit the view for a login, for example. And we can go to sessions, new slogan in the login, innovate, create and use session. And we can add it. For example, we can add some kind of tool here. Now to make our views. For device to look nice. They're going to go again to bootstrap. So get Bootstrap and they're going to put them all into codes. So here we have called a god usually contains a header, a body, and a footer. So we have a called, a cold body called texts for example. So let's try adding a COD. We will say div class called. And this is all going to be in the scold. And underneath they're going to have a div called header at the width called Knowledge check if called header exists, called header, yes. Called body and God, footer. Let's see if this works. Okay, we've added some kind of code, but we didn't close all the diffs. Okay, so here I have a chord on the very top. And you see the code is added and there is no space, no space in between the navbar and the code. So again, an application that can add some kind of additional beat egg, for example. So that there is going to be some minimal space. Or it can be a break. Let's see what embrace couldn't do. Basically the same effect. And all they're going to put this log in into the card header. And this is going to be the cold body, and these links are going to be in the cold footer. So I go here and I'm going to move log in to called header. The form is going to be in cold body. And these shared links are going to be in the code folder. And already looks nicer. So I'm going to perform the same action for sign up for, forgot your password and for all the other pages. I'm not going to film it. You can do it on your own or you can copy the code that I will have in them. But this is basically an easy way of how you can customize your device views. 16. 03 04 devise confirmable: Okay, so now we have styled our navigation for device. We have this Log In and Sign Up links. We have massless tide will diffuse pollock in, Sign Up, Forgot possible, and actually put it they go and type for what possible. We'll put in some kind of random email. And you see the email was not found. So there is no account associated with this email. But if we do the same with an email that is registered in the application, you seem to get the skew will receive an email with instructions on how to start your possible and how do we get this email? Well, in our development environment, the easiest way is to just see it in our logs. So here you see we've made the commit and here is the contents of the email. So divides mailer reset password instructions that date. Then from police changing at config initializers, devise at Okay, we can change this from address. So we can go to config. Here, will go to initializers and find, devise RB and fabric and say change this mailer sender. So we will, let's say name it. Ruby, gems Bootcamp, or let's just say hello. At core seagull does my So next email will be sent from hello and that'll be visible in the sand the address, and you see the sphere, you can configure any possible e-mail address as a sander. But of course, in some cases it can be sent in the spam folder because it isn't authenticated. So reply to, please change met config initializers. Wow. Okay. Than to Hungary descended to the email that we are trying to recover, subject rosette passport instructions. And you have got this line. You can change the possible by going to the link below. And here you see we've got this address that we configured in our development dot RB. So the email was sent to this isn't in the Action Mailer default options. And they get this user's password edit. And they have this reset password token. So this unique reset password token, this one lets us reset the password of the user. And if it is leaked, then somebody can hijack somebody else's account. So this is kind of a secure information. So in the open this link, you see we can change the password for that user. So I will put in a possible. Okay. And you see the possible has been changed, successful VR signed in. So this baby can recover, are possible in development. Now let's go back to our user dot RB, and let's go to our modals. Modals used at RB. And so here are our default device settings and we're going to add some new device options. We're going to add confirmable. Lockable began at trackable and routable. So confirmable would mean that a user needs to confirm his account. So that if somebody registers from somebody else's email or a fake email, he won't be able to access the application until he confirms gets email. For example, I sign in with random email, ladies, and i will not be able to access the application until I confirm my email address. So for this, we're going to add devise confirmable. So I'm going to add this confirmable setting to USA dot RB, like this. First, we add confirmable here. Now let's go to the device documentation. Let's find confirmable. And here we can see that dogs for confirmable. Now actually will go back and we'll go to the device, Vicki. And here there's BY something like add confirmable. I'll find cone farmable. Okay, there are over a 125 pages how to add confirmable to users. So let's open this particular article. And what do we need? We need to add user I'll be registrable and confirmable. B had registered trouble by default and they've just added confirmable. Next, we are going to add this migration. Rails generate migration and confirmable device. Okay. I'm switching the server off. Control C. Control l. Okay. Its something different. I need to cooperate funds again at confirmable to devise. And we've created a new migration. But this migration is empty. So we need to put this contents inside. Okay, so to our users table, they're adding the confirmation token. That moment when the user was confirmed as a date, time, the moment when the confirmation message was sent, and the confirmation token. And we are going to update all the uses that already exist in the application as confirmed. So by adding this particular command, you said all the existing users as already confirmed in the application. You can omit this command if you like. Okay. So let's run rails, the beam migrate. And let's go back. Okay, so next we can change our settings in device. Let's have a look at our application. Let's start Rail server. And let's sign up as a new user. Okay. And we get undefined local, derivable, unconfirmed email. What can this be? Now, let's see, undefined local variable and confirmed email. And here in this migration we have this optional unconfirmed email. So if we go into device RB settings and look for reconfigurable, and you get this message. So manifold to have confirmable set to true. So if we use confirmable Andrew, confirmable than we need to add this column unconfirmed email. So let's add it. In our migration. Actually foster will run rails db rollback. Well the migration. And we will add the scone once again. Okay? And they're going to run them aggressions again. Otherwise you could just central unfathomable to false if you like. But Python to keep reconfigurable. So v are going to run the migration null rails db migrate. And let's try to start the server. So I was creating a new user. Okay, I'll try it once again. Ok. So I created a new user and I get the senior to send in the full continuum. Okay, let's try to sign in. And you see you have to confirm your email address before continuing. So by default we cannot continue the cannot open the application until we confirmed our email address. Now what did we want to allow users to access the application, for example, for two minutes before confirming that email will go back to the device settings. And here we have the sediments for confirmable. Let's find it here. Here are all the configurations for confirmable. So the first one to see by default, it is 0 days, meaning the user can access the website without confirming that account. And we can allow the unconfirmed access, let say for two minutes. Ok. Let's try login in. Let's say ten minutes. And yes, I need to restart the server for the changes in an initialize it to take place. Okay. I'll try to log in and you see I managed to look in. But two, I'm not able to keep using this account in a few minutes until I confirm. Now let's see what other confirmable Seconds There are. So confirmed within three days, meaning there are maximum three days to confirm. So imagine you can access the implication for ten minutes before confirming. And if you don't confirm than their conformation token will expire in three days or it will not expire at all. So by default it is nil, meaning there are no restrictions, so the user can confirm cosecant anytime. And that's basically good. Now, what is reconfigurable? Let's imagine I log in with an email, I'll look into. I'll sign up for my real email. None of this fun. Okay. I sign up. Now, this was previously signed in and I want to change my email. So what if I want to change my email? What should I do? I go to edit user, I have my email, I have possible. So what if I tried to change my email? Make it changed at and update. Now current password cannot be blank. So I put in the current possible and you update your crown. Successful, but we need to verify your new e-mail address. So I tried to change my email address. You see, I'm logged into the old email address and I get this. Welcome. Changed Confirm your change. So I open this link and you see I'm logged in as that new email. If I refresh the previous link, I'm logged in with the new email. So this Fe, using true confirmable, I can change my email and confirm my new email. And these are the basically main points of using confirmable in an application. Now, I'm going to comment this line out because we are not going to allow any unconfirmed access to the application. Otherwise, you'll be really getting L-dopa, real spending emails. And you don't need that. You want only real people with real emails using your application. So we are going to use confirmable, but we're not going to let any people who did not confirm the email access the application. And once again, Here's the workflow. I press sign up, I put in some kind of email. Cross sign up. Welcome. You have signed up successfully. Okay. I did not restart the server. So I restart the server for the changes in device albedo change to take place and I signed up. Okay. And I get this. You need to sign in or sign up before continuing on scan. So I put in the email and password and you get this. You have to confirm your email address before continuing. So Let's say I want to confirm dense received confirmation instructions. I will send them once again. I'll go to the logs, confirmed my account and it was confirmed. And now I can log in. So success. And that's basically it for this lecture. 17. 03 05 users index and user show pages: Okay, so I've committed the changes for device confirmable, and let's start the server. And once again, I am trying to sign up. I put in some kind of random email and I cannot send in until I confirm my password. So I will try and confirm the possible. I go back to the lungs. Here it is. Your address has been confirmed and eigen have to log in. So what if we automatically logged the user in a given firm's his email address. And we also have this in this confirmable documentation. So we can create a conformations controller. Let's do that. We will go to our app controllers, new file confirmations controller, and have a look at the scaled. So conformations controller that inherits from device. And we have this after information path for resource. Resource is user signed in user. And here we are going to have the path will have roped off. Okay? And let's go back and we need to initialize this controller and this action in our routes. So they'll go to routes.rb. There's our config. Lets find our config, config routes.rb. And here they're going to say device for users. And the conformations shuns controller is going to get the information from our conformations controller. Okay, so let's see if it works. I'll restart the server. Now. I will try to create a new account sign up. Okay. I go and confirm the account and you see I'm automatically signed in, so I did not have to put the password in once again. So this way it's going to work nicely. Okay, they worked quite a lot of them confirmable. And now let's actually make a page on which frequency all our users. And the moment we have a users table, even our schema we can see we have just one table users, but we have no option to see all the users in our application. And the current user can only access kits, account settings, but he cannot see his email, whether he is confirmed and so on. So they are going to add some kind of views. And for this, we're going to create a new controller, is going to be called users controller dot RB. And in a similar way, how static pages controller inherits from applications controller. They are going to have users. Controller that inherits from ApplicationController. And in this controller we're going to have a few pages. One page is going to be a death index. In the shovel list, all the users. So at eusers equals user not o. And the second page is going to be deaf show. And on this page we will see a unique user. So we will have add user equals user dot find, and we're going to find the user by the parameters. So basically we will have a user's page on which we will see all the users. And use a page where we will be able to find the user by the id. So such oral bring us to the good, to the user, but I did valve and such a page should bring us to all the users. Now will have user find by params ID. Okay, so you have edited our controller, and now we need to edit our roots. So they are going to our roots. And they're going to say that they are going to have resources users. And they're going to have just two actions, index and show. Only. Index and Show. And nobody integrate these views. Actually, we can already see if these pages are accessible. If you tried to go to users in a C uses controller index is missing a template. So we just miss our views. So let's go to views. And views, we are going to create a new folder Users. And here we will have a page called index.html.erb. Erb, it's empty now, submissions have an empty page. And here it will say all users, for example. So here we will have a list of all the users. And on a page like users slash one, but we'll have the personal page of the user that ID. So the first user that was created in the database to create a new file, show dot HTML dot ERB. And he will have an personal page of a user. Now let's customize this. So we have created a new controller, uses controller. We've added it to our roots, resources uses only Index and Show. And we've created a folder with the our views users that has Index and Show. And let's say it will do it in such a way. We will have partial named user dot, HTML dot IRB. And in this partial we will have equals user ID and all the other personal information of the user that they want to have. To be not ERB, but oh, yeah, actually scrubbed user dot HTML dot ERB. Here we have a user ID, for example. And let's make this partial available both in index and in show. So in show, we will say. Equals render Users slash user. Let's save this barracks. Let's go to the User Page, the pages of the user ID. And you see undefined local variable named user. So they have to say that user is at user. And here we see the ID of the user on how spatial VR now. So we can get more information, we can get than we can get user_data. And whether the user has confirmed true or false. Let's put this into different lines. That's at some breaks. Okay. So user ID to that email is student confirmed, true? Let's add some more here. Id email, then, confirm conformation. And here we have some basic details about the user. Let's make this text bold here and here. O k bolt Not in that HTML format. It should be like this in braces. So bold for ID, bold for email, and bold for confirmation. And looks slightly better. Now we can remove this just text called user. And if you go to the page of USA Today, see his ID, Email and confirmation. And if we go to user x2, okay, we have a list of all our users. So they can go to our index and iterate through all the users. At users. We already said in our users control that at users are So users, each user. So we're going to iterate through all the users. And then they're going to have an end statement. And they're going to render the same template, the same user, template, Users slash user, alkane. Let's see if this works. Now, undefined method user. So it will say user is user. And here we have the list of all the users. Now let's add some kind of breaks. Okay, and this way we can have some kind of basic list of all the users. So they are of course not ordered, neutral, ordered foster have user ID to them. I depend. So let's also add some kind of basic order. So horrible at older, traded at ascend them. Let us see how it works. And this way we have the oldest credit users first. Now, if they okay, I'll go back if you want this audit to be different. So if a bonding used credit users on top, we would make it in descending order. And we can also make it so that when the press, the user ID, for example, will be able to automatically view his personal page. So k will have help link user ID at user path for this user. Okay, and then the press the idea of the user and the go to his personal page. So this way we can have basic, basic index view and show view for our users. And notice I didn't, right? The views, different views for rendering the user data for index and for show, I am just using van same partial for both Index and Show. And this way it can in some cases, just make do the possibility of writing your code and Helen reusable templates. Now, let's go back. Here. I'm a personal page of a user and I have no way to go back to all the users. So I will go to show. And here under this I will add an additional link, so link to all users. And the path is going to be users buff. And they'll add some kind of additional break here. So here we have on each personal page of the user and link to see all the users. And we can also add our users to our navigation. So let's go to our layouts header. And here we have a link to our root path. And they're going to cope with this and have a link to our users. Now here we are going to have Font Awesome User's, I know that such an icon exists. Here will get at the name users. And here we are going to also add users. Okay? And you see, we have our users open, not to have our homepage open. We go to a specific user page. So this Fe, obligation is becoming more and more lively. And that's it for this lecture. 18. 03 06 devise trackable: Okay, so we have added the user's index and users show. They can see which uses both confirmed and the fans for naught. And we can say list of old uses and go to a personal page of USA. And now we're going to add one more devise option. It is called trackable. So by adding Devise checkable, there going to be able to register some data about the users, how many times they signed in, and then the time than they sent in with the current sign-in. That prevents data about the previous sign in and the IP addresses of the current end of the last sign in. So let's try to add the, this device trackable to our application. They're going van scan to use a dot RB, and they have already added confirming goal. We can also add trackable. So i'm adam, trackable. I'll actually make these in a New Lion. And let's go back to the documentation. So we've added device trackable now they're going to run emigration at trackable to devise. Okay, now we've created a new empty migration. And here they are going to add this content. So okay, and we will run the migration rake or actual rails db migrate. Rails db migrate. Ok, now let's start the server and do well, nothing has visually changed, but this data is already saved in the database. And let's actually display this, this new column that we have just added. So let's go to our user bombshell. And here we will also add some new lines. So that will display this data about the user. Will display the user sign in count currents and in, at Lausanne, in add and so on. Okay, I will do it like this. I will add the some bulk details for all of them not to type one by one user. Sign-in count. Now how I did it, I pressed out and by person out. In this particular environment, I can select a few lines at the same time. So I have user sign-in count, and so on. And let's see how it looks. Ok. And we have zeros at the moment. And let's sign out and sign advanced scan with a user. And OK, did we create the the registered information? Yes. Videos you see for this fun user, the first user signed in after the edit, this trackable, they have this data saved. Now let's also make it look better. So not to retype all the stacks they'll do. The SPEI will add Rails method called human eyes. So again, I'll take all of them and the bulk action. I'll turn this into a string and John dot, huma, nice. And close. And let's then add the bold. Yeah, I could have done it previously. I'll make all these bold. Oh, okay. And let's save it, folks. Okay, so you see I've added sign-in count currents and add and so on. And I will just put von under another L at the breaks. And I will add. So users sign in count here, sign-in at current signing at here, last sign in. Current sign-in IP and Lausanne in IP. This molecule, the job. So this way we have more data about all the users, heavy civil data about the current user. And we see the current same in time, the last time, the occurrence and in IP and last sign-in IP. So this is basically all that this trackable method gives us. Now we can go to the device initializer and see if trackable can provide us with anything else. And it looks like not. So basically that's it. You see, an trackable was easy and straightforward. And this way we can have more information, more personal information about our users. That's it. Thank you. 19. 03 07 create fake users with seeds: Okay, so we've gone through the main, the most important use cases of device for author an authentication for login in. And there are of course, other devise methods and other things. We can use it for the rest device from the alterable, but we'll cover it later on than there is device then routable but and lockable. But we're not going to cover these because these are functions that are really rarely used. So one alternative we will do now is we will go to our file in dB called seeds.rb, and heavier, the possibility to create some users into our application by default. So here we can kind of create the sample test data for our application. And for example, we can create the few users. So we can type something like user dot crate. And we will need three things. We'll need an email. They'll need a boss fold and a possible conformation. And in email we can say something like admin at the vertebra, At Bus fault can be the same. Puzzle, confirmation can be the same. Then they are going to create from a user cold student at, say impossible and password confirmation and will need to most likely you'll want to have them confirmed by default. So from device confirmable, they're going to take this command, user update all confirmed at date-time now. And that's basically it. So let's say we'll, we'll delete all the data from our database. Rails and TB control the beam trade db migrate. This way we delete our database, we recreate the database and random migrations. And now we don't have anything in the database. And if I also type rails db seed, then the application will run this file and try to create the users and update them with the confirmation time as time now. So let's try to start the server. And you see I have to look in once again because I deleted the database and some the server, so that session was destroyed. So I log in and you see we have just two users and both of them are confirmed. The van that is logged in now has this data from trackable demanded, never logged in, also has sign-in counter 0 and doesn't have anything about his IP and his son in time. So this way we can populate our application with the fake test data using seeds.rb. Of course, you can use it in production methods or be focused Blake and real data. And that's it. 20. 03 08 redirect user to specific page after sign in: And just one more thing that we are going to do right now with devise. So here, let's say the log in as a user and verb is redirected to the root path. And what do you want to get rid right to some specific page, for example, to use a personal page. So it would redirect the user ID. So let's go to our application controller. And here we will add one more action is going to be looking like this. After sign in path for resource vol, the only resource that we have at the moment is user. And the path is going to be usable for this results. So for this user, basically here we have the user and the user, and it's going to lead us to the user path. Let's see if folks. So I look in and I'm automatically redirected to my personal page, I log in as another user and unlocked. I am proud to that user's page. And actually here in the nav bar, we can also add an additional link to my profile. So let's go to our use of use. Can we have our header and here that they have if currentUser will have this current and we'll have a link to the user profile. So my profile FA user. And it'll have user off for current user. And here again so that this link is active. If it is the current page. We'll also add user path, current user. And here you see we have this link to my profile. And this way we can go to our own page. So by Adam, this command of the Senate, but for a source user path in our application controller, we can sign the user in to a specific page in our application, and that's it. Thank you. 21. 03 09 users can be deleted: Okay, so here we have a list of all our users into application. And what if we want to delete a user? Now let's add this functional to the application right away. So I am going to our users controller. Here we have our uses controller and they're going to add an additional method, delete. So it's going to be deaf. Delete. And, and again, we'll need to find the current user, the use of the throne to delete the user. So we'll pass in the params and they're going to say user dot destroy. So it is going to be usable destroy. And they're going to redirect to the users directly, to users. And they're going to say a notice, user was successful destroyed. Okay, So they are done with the controller. Now we'll need to add this action to our roots. Let's go to our config. Slash. Roots. And Kim have resources uses only index show. And it's also going to be destroying. So not, I don't have three actions in our users controller, index show and destroying. Actual not delete, but destroyer. Liked us. Okay, so we have, our Destroy method in Algiers is controller. They have available in our routes. Now let's add this link to destroy a user in our view. Let's go to our views. We are going to users. Here we have our user postural, and here we'll have an additional link, so equals linked to user method delete data, confirm, I assure. Okay, now let's see if this works. I will refresh. Oh, and actually we need to add the availability link to delete this. And we'll add it on a separate line. Will also have a break here. Okay, let's try deleting a user. So I will delete this user with the ID six X at Delete. I sure. Okay. And you see he was deleted. Now we can also display how many uses way have heavy, have just all users. And we will add the quantity or users. So it will say equals at users dot size. Now we will add it into Ruby braces like this. So that it displays. We have five users or uses five. I will do it and all the user. And you see now the unsuccessful delete another user. And like this way, edit the functionality to do it a user, we want all uses controller and edit and destroy action. We made this available in our routes and they added a link to our user partial. So when the user presses delete in his browser, v plus the method delete user into our roots. And from our roots we are redirected to uses controller. This action is performed, and that's it. Thank you. 22. 03 10 devise lockable: Okay, so now we can delete users and let's have a look at device function. It is devised lockable. So it basically gives us the opportunity and the possibility to look a user's account in different scenarios. That most common scenario is, for example, if a user has too many failed attempts to lock in, this can be useful than somebody's trying to brute force. So to try different combinations to enter using somebody else's possible. For example, if somebody typed in the past vote incorrectly more than five times, then the account will be locked and you will have to unlock it via a link in an email that will be sent to your email address. All the account can be unlocked in some period of time. So here they can add the different subbands as maximum attempts. Before a user account is locked. Then I'll automatically unlock the user account in some period of time and they can advance if it is the last attempt to login. Well, basically let's try to add this lockable to users. So first of all, they're going to use an RB and they're going to add lockable. So they're going to our use RB. And here after trackable, we will add lockable. Next we're going to add this migration. Stop in the server control l based on this migration code. And they're going to go to db, migrate at lockable to devise. And they're going to add the oldest content inside, like this. And what do we have here? So there hadn't failed attempts column to users than locked at time. And at these only if unlock strategy is email or both. Well, usually the unlock strategy is either e-mail or in some period of time. So we're going to add this. Okay, they're going to run rails db migrate. And we've done the migration. And now we can go to our device are being, so we're going to go to config initializers, devise our beam. And if you scroll down, you will see Configuration for lockable. So what do we have here? By default, the user account will be looked after a few failed attempts to log in. So conflict log strategy, there'll be a failed at ambits than defined, which will be used when a locking and unlocking an account is going to be email. Then defining this strategy will be used to unlock and account email time after some time. Then both o num. Well, they're going to use both either email or time. So either you will need to confirm with your email that you want to a look to your account or you will have to wait for some time. So configure maximum attempts, Let's make it not vented, bought four, for example. Then automatically unlock in. Let it be one hour. And we are going to give the users a volume that it is last attempt to login. Let's make it three attempts. Then, reset bus followed by email. Oh, actually it is already recoverable. So that's not what we are looking at. And let's try to log in. I will start the server and tried to look into the wrong email with a rondo. Must fold. I'm signing out, I'm pressing log in. And here I will type in an email and invalid email, a possible one attempt, second attempt. And you see it says you have been more attempt before your account is blocked. So I will type a wrong password once again. And it says your account is locked. So I can look look into this account. That's it. Now, let me log in with another account and see how it looks from inside. I will go to C, It's a B and C vote emails and possibles behalf. Okay. I have a look in as this user. So I logged in and actually I'm going to display that a user account is locked. So I will go to our user partial is if you users, user. And they're going to add the, another link user dot locked at user_data looked at. And you see they use that is locked, has a date, time van, he was locked. The other uses that had access to the application don't have this datetime. So again, let me look another account. I'm signing out. I'm login in rhombus fold Vaughn, ron, possible tomb. You have annoy tamped rhombus footprint. And now I will just try to input the right possible. But you see your account is locked. So the account is locked. What should I do? I will need to go to dilute receive unlock instructions. Here I will type in my email and you will receive unlock instructions in a few minutes. And if look into our logs, let's see the end of them. Here. At the end, there was an email sent to the device, mailer. Hello. Email. Your account has been locked due to an XSS if number of unsuccessful attempts, click the link below to unlock your account. So if I click on this link, then your account has been unlocked. Unlocked successfully. Please sign in to continue. So I'm putting in the email and password. And like this, I managed to sign in successfully. So this way we can easily add this additional layer of security to our Ruby on Rails applications. And that's it. 23. 03 11 users can be banned and unbanned: Okay, so now we have added device lockable to our users know though. And if the user has more than three failed attempts to log in, his account will be locked. And she'll be able to unlock his account either based on time, all based on the receiving an unlock link on his email. Not what if we tried to use the device lockable functionality differently. For example, we will use it not to lock an account if there are too many wrong password attempts. But basically the admins will be able to ban accounts, so Lock account access. And for this we would change the way lockable works. So at the moment we have the log strategy based on failed attempts and they're going to make it know and visual handle login by ourselves. So we are going to handle login about by ourselves and going to change the lock strategy. Though, num, then unlock keys. While this will not be used. We don't need it at all, then unlock strategy is also going to be known because we are going to handle it on ourselves. So it's going to be non o. And this also doesn't play any role anymore than unlock in doesn't play any role anymore. And last attempt volume, we are not going to use it. Ok. So we are going to handle locking and unlocking on our own. And basically in the each user profile, they're going to add a button to ban auto unbound the user. So how are we going to add this bottom bow foster, going to go to our roots and create a route or the controller in which we are going to do the bending and unbending. Let's go to config roots and HIV have resources, users and inside resources uses that we're going to make doom than member do. And in this member do, they're going to add an action called patch ban. So they're going to have a path to ban user. Now, what does number do stand for? Let's see, let's start our server. Yes, it is started. And let's go to our rules. So let's search for bang. And here you see we have created the new path called band user path. And by passing this member do block inside the resources uses the same that we are going to have id. So users than user ID, then bang. If it didn't pass number, do if they wanted just a collection that we would just have users sludge band, but haven't been specific user based on his specific ID. So if we're going to do this based on the ID, we pass this patch inside a member action. Ok. So we have created a rook Ben, user path. And let's add this root and this link to our view. So let's go to our reuse. We go to app, not nodal skews users, user and have a goal to have a new link. So equals link. Bam, done, you'll have the band user path than at user, than the method is going to be batch. And the clothes, the braces. Okay, now let's see if it works. So you see we have this new link, I press ban. And the action band cannot be found in users controller. So they're going to add this action band to our users controller. To go to controllers, uses controller. And hence we will add this action death and bam. Now we are passing the user ID, as we said in this member do action. So they need to have the user ID. Well, nobody, She was a bad man. And how do we actually ban on ban a user? If you go into the documentation of device lockable, then we considered there is this check access locked, that would pass either true or false, then they have this action to unlock access or to block access. So they're going to say user dot loc access, just as it says right here. And they're going to redirect to that user. And notice user was bound. Just user bank or user successful abandoned. Now let's try to resend the message and the goddess measure that user was bound. Not Look, I bought myself but I didn't cloak out, I wasn't locked out of the application. This is strange though. It is not strange because whenever you do changes in an initializer unit to restart the server, let's try to restart the server Rails us. Now, I will try to see, okay, interesting. I banned this. Okay, K I bend this account and login from this account. Yeah, that's funny. So that's why I didn't look out. But let's try to bend myself. I'm going to bend myself. This account, I press bam. You see, I was locked out. Your account was logged and there is no link to try to try to unlock your account. Okay. So I will log back in now, l sign up. Sign up. Oh, okay. I will look in yeah, I'm not invaded and other account. And I see that this user has looked at, So he was bound. This use doesn't have looked at. So he wasn't band, but the button just states ban. So we can only bend a user who cannot Unbound a user. So they're going to make this action to either bound or unbound a user. And we are going to say like this, if the axis is locked, then on ban, otherwise ban. So if I'm at user dot, access locked. And we will have user dot and log axis elsewhere are going to have user log access. And we'll say user ban status updated. Now let's see if it works. So here we have this user and I will trans ban and locked at disappeared. Now press banned months again and looked at, appeared one small. So we can either ban or unbanked the user. Now we can even customize this message, not just uses them status updated, but user access locked. And we'll say true or false. So at user got access locked, question mark. So we will say either locked or unlocked. Let's see. User access locked, false. User access locked, true. Okay, now we're going to change the span and on banner labeled. So for this, we're going to actually create a helper. They're going to our helpers and kinda going to create a helper called users help RB. No, we open the file and it's going to be named module users. How bad? And, and in this module we are going to have something like this. Def bam status for the user. Now n statement. And we will say if user access locked than we will put the text on ban or else we're going to put the text in them. And, and we are going to incorporate this band status into our link. So having held this link, and here they're going to say not just the Stax band, but band status for the user. So we're going to display what his band or unbound. And here we have this unbound or ban. So Vox nice and looks nice. We have dynamic name of this link. We can either ban on bank account and the moment on the logged in user can will ban all and been an account that's logical so that it can ban and user accounts really in our application, looks nice. And how did they do it once again? And to devise dot RB and change the configuration for lockable. If you said that we're going to use our own lock strategy and unlock strategy. Next in our rules, we created that path, the path that we are using in this link to ban the user and the metal is patch. And in the users control. And we created this action to either unlock, unlock, access and in uses helper, we made this dynamic ban and unbound status from Islam. And that's it. Now I'm going to save the changes. So control seem to stop the server control owl. I'll git status. Here are all the files that have changed now get at all git commit m. Users can be bound and unbound type git push. And now I'm going to push to Heroku. So git push heroku, Maine. And that's it. So thank you. 24. 04 01 gem omniauth google oauth2 social log in with google: Okay, so with adult basic authentication to our application, and now they're going to add the authentication with social accounts so that you'll be able to look in, for example, the Google or GitHub or Twitter of Facebook or whatever other account. So let's do it. Now for this. First, we'll start with Google and we will need the gem OmniAuth Google Auth don't. Okay, I'm googling this jam. He has this chum. And I'm going to add the gem to our Gemfile. Now you see they are connecting from time to time. It happens sometimes you need to your password once again, sometimes you don't need anything. Ok. Now they're going further when to go to the console. Developers Google con and the great our application for Google API. So I'm logged in here. Now I am going to create a new project, is going to be called RubyGems boot camp. Create. Okay, it's been created. Now, I will navigate to this project. I can do it like this. Okay, next, I'm going to this. Maybe enable a PEI Kids No, it's uncoupled. I need now. And going to war with constant screen because it's the first ten minute two. So it's going to be external. We're going to let anybody look in. Then apt name, you can give your app name. I will name a true Ruby. Gems boot camp uses support, email my email. Then you can add some kind of logo and mondrian type any login now than the application domain. For now it's going to be just this domain that I am using for AWS. You can just add localhost, for example. Then I'm not going to add a privacy policy in terms of service link from the beginning and next authorized domain. So it's going to be Amazon, and contact information. My email once again. And let's see if it works. So we have editing or outcome to screen, constant screen. Now we need to add some scopes. So we will need the user email, some kind of personal info. And let's say OpenID, those like the African update, Save and Continue. Dust users do not need any summary. Okay, let's go back to Dutch pole. So they're doing all the spoke so that Google gives us API keys, which we can use to log in using Google. So we created an old concept screen and nova can create credentials. You're going to be an API key. Actually now not an API key. And we'll do it this fun. It's going to be out client ID, application type of application. Name once again, Ruby gems boot camp. And having it to have our authorized or rules. So here's going to be the order of our application. And authorized redirect URL is going to be, let's see. It's going to be something like slush. So slash users out Google OAuth2 Callback. Now it's just the way it has to be. But notice here they're going to users out heavy, put Google OAuth two Kohlberg, and for example, then it will be used in GitHub. And the same for GitHub, we are going to get hub callback. Okay, we are creating these credentials. And here we have our secret credentials. So we can add them to devise dot RB. Let's go to config. Initializers, devise our being, and we will find omni, our symbol. So they're going to configure OmniAuth, not for GitHub now, but for now the provider is called the Google OAuth two like this. So provider is google of t2. And here are our kids, our client ID, and our client secret. Like this. Okay, next, what do we do? Lets say OK here. And let's go back to the notation. Okay, next we need to go to user dot are being so app models user RB, we will say only outer ball, so the user can be lumped in with OmniAuth. And we will say only out providers, Google OAuth2. So they're going to permit the user to log in with Google. Okay. Next we need to go to our roots and add a new controller. Users OmniAuth callbacks. Let's go to controller's actually to our roots. And here previously for device we've added controllers, conformations, confirmations. We will just add this. Here. Go Mom. Omniauth call-backs will be in uses OmniAuth callbacks. And actually we can use that can move our confirmations to users slash conformations. So we'll go here and in our controllers, they're going to create a new folder called users. We will first of all move our conformations controller into users. And we are going to create a new file called OmniAuth callbacks controller. Inside app controllers, users. On the callbacks controller. And at this user's OmniAuth callbacks controller. Now we have our conformations controller moved into users conformations controller. And here they actually need to also add users in this confirmations controller. So what have we done? We have just moved the confirmations controller into the folder users in our routes and in our controllers. And we have created a new controller. So in roots we say OmniAuth callbacks leads to uses OmniAuth callbacks. And here we have the strategic plug into the Google. Okay, let's so let's see if it works. Before we do anything else. Privilege Rail server once again. Ok, I didn't run bundle and run bundle install on the jumps. And now as dots Rail server. Okay, and you'll see by default we already have this button signing in with Google of Tom. I press OK, I can look in, I'll try, let's say this email address. Okay, and undefined method from OmniAuth o k. Now maybe we need to add this segment to this method to use a dot RB. Let's try. Okay, and I will clean it up a bit. So data equals access token, info on comment section below. If you want users to be created if they don't exist, yes, we want users to be created if they don't exist yet. So they're uncommenting this section. Okay, now this is just plain texts. We don't need it. Had to have four unless user create a user. Now we don't have a name. We just had email and possible. Ok. And this method looks simple enough. We've removed the complexity and now it must broke out in our application. And I've restarted the server. So sign in with Google. I select an account. And it says successfully authenticated from Google account. But actually we're not logged in. Now that's interesting. Let's see what the problem is. So let's look in an existing user. Here we have three users. The user was created, but he was not confirmed. And that's why he couldn't log in to this method in user RB. They're just going to say that the user will be automatically confirmed. So here we will add user confirmed at time now. Okay, let's try to log in with Google once again, signing that Google and the same account. And it felt ok. Let's go back. Let's sign in with Google from another account. And it felt so now when we sign in the social media account, they're automatically confirming our account at the same time. And basically we can already logged in at Google. So the basic functionality is added. And that's it for this lecture. Thank you. And just, let's summarize once again, what did they do? So in Gem file, the edit the genome. Then in device RB, the edit, this conflict OmniAuth and gave you put in the API keys, the ID, and the secret that Google provided us. So to get them from Google van to Google, APIs created an application, created an OmniAuth content screen, and set up the credentials. And here the goddess OAuth, two client IDs. And here we get the credentials, then vent user RB and added on the automobile to device. And I did this method. They say that compound F time now. And the either find a user that exists with the Google Data, Google email, all the create a new user. Then nth roots, the added more Controller we added uses OmniAuth callbacks controller. And in app controllers users be added OmniAuth callbacks controller. And we then change until here. So that's it. 25. 04 02 gem omniauth github social log in with github: Okay, so it was quite easy for us to add social log into the Google using the Google often ANOVA going to do something similar with GitHub. So Gem only our GitHub has the gem. And they're going to install this chum survey to our gem file right here. And now we run bundle. Okay? And what do we need to do to get GitHub API keys? So we will go to and get hub, our account. That's my account. You can follow me if you like. And go to settings. So click settings. Now you go to developer status or our apps. And here are going to create a new, old app. I will name this one room being jumps bootcamp and lead a homepage oral and an authorization callback URL. So homepage URL is going to be this fun without users. And in authorization Kohlberg rule, they are going to have something similar to what the head in Google, let's say the older that they put in Google. I shall dishonest fight. Too hard to remember. Voted to put that c. So users out Google OAuth2 Callback, but I'm going to put cookies hub uses out GitHub callback, okay, and register application. So it was much easier. And here we have our client ID and novel get a client secret. So let's go to devise RB value. We have initializers, devise or B. And here you have already set up Google. And now we're going to set up GitHub. Not, we will not meet the public repos only user data. Now we have our app ID. Here's the app ID. And we'll get a Cloud Client Secret. Ok, here is the secret key Argus. Now, no spaces. Okay? And they actually don't really have to have this additional scope user here. So the condition doesn't says that when you have the scope user. Okay? But two, it is possible. Yeah, I've actually leave the scope user. Okay. Now we are going to our user dot RB and they're going to add also get hop like this. And let's try login in Rails server. I'm logging out. You see we have this button inside that GitHub. Now, I don't actually need any organisation access, just authorize. And you see, I get this unknown action, the action GitHub couldn't be found in uses OmniAuth callbacks controller vice that they're going to our OmniAuth callbacks controller. And here relevancy, all of an action, it's called Google OAuth2. Now one thing that we can do is just copy this action and name and your action gold and get hub. And just to place the world Google with GitHub. Let's see if this works. I refresh. I tried to look in, glance again and you see, I managed to log in using my GitHub account. But it doesn't really look nice. Reusing the same code just for the sake of the name and the action. So we're going to do something about this. So here's what we're going to do. We're going to do delete one of these two actions and crepe, couple of smaller actions. They're going to create deaf for Google of tomb. And, and therefore get hub. And this one is going to be named handle. Ours. And have a little have kind and Habitable, say Dev Google Auth, delete to handle, handle out. So one actually leads to another action. And it is going to be called Google. And here we are going to have handled out get hub. So for now we are redirecting to the callback to login with Google or GitHub. The redirect to handle our kind and the kindness at a Google or GitHub. And here we'll say kind is client. Okay, so this should kind of make us not have to use the same code files. And let's try to log in. So I'm trying to log in the Google. It folks. I'm trying to log in GitHub. And it also works. So perfect. The really easily after creating been provided for social look in, managed to create the social organism. One more provider. We just added the jam for those provider, then added their credentials in device. And then the provided in OmniAuth user and slightly updated our OmniAuth Colbert's controller to make it more dynamic. So that's it. That's how we add social login with GitHub. And don't forget to go to the GitHub website where you can get the API keys. 26. 04 03 gem omniauth twitter social log in with twitter: Okay, so now we can look into the google, that GitHub, and we're also going to add Twitter log-in. Now, at the moment I'm signed in into the Twitter developer portal. And to be able to send into the Twitter developer portal unit to have a Twitter account and you need to fill in some kind of form. Now filling in that form required some time and then I had to get a to get their approval. So this might not work for you from the very start. You need maybe to have some time for your Twitter developer account to be approved. But once it is approved, you can have access to the Twitter developer portal. And now I have the dashboard. I have apps. So I'll go to projects and apps, and I will create a new app. I'll name it the Ruby gems boot camp. And so fast books like I already have an API key and a secret key. Let's see if it lets us Voc. Let's go to jam OmniAuth, gem, OmniAuth Twitter to our gem file. Now they're wrong. Bundle. Then they're going to our user dot RB. And they're Adam, Twitter. Then we are going to devise our initializer for device and have it will add Twitter. And within the API key and API secret here is the API key. I go bid right here. And we have the API secret game I pasted here. Okay? And that might be it. So let's try to look in. I'll type rails server. We have this new link to sign in with Twitter. Okay, for one authorization required. Interesting. So possibly treated him. Give us authorization yet. So let's see, App Permissions. Not only o, OK, what do we need? Three legged, OAuth is disabled, so we need to possibly enable this enable request email address from users. Oh yes, come here, we can final callback balls. So here is the Goldbach guru. You see the habit users of Twitter. And then we have our website, URL. Organization or name is optional terms of service. Our required I'll just add the root path privacy policy also the root path. And let's see if this callback URL is settleable. Tonight. Let's go to GitHub and check our settings. Here we have our settings and develop a set of apps. Rubygems, bootcamp. He ever have uses GitHub goldberg, So in them and they also need to have slush callback. Okay, and possibly this is all that funny. So save, so all is enabled. Let's try once again, I refresh. And I get this log in screen with Twitter. So authorize app and unknown action quicker. So Googled OmniAuth callbacks controller. And here we will add and you action named Victor. Handle OFF twitter. Okay, I refresh Twitter. And it felt, so it was really easy. Those at op log in with Twitter. And that's basically it. Thank you. 27. 04 04 gem omniauth facebook social log in with facebook: Okay, so we have added login via the email, Google that the GitHub, Twitter. And now lastly we are going to add locking the Facebook. So here is a Jump Jam OmniAuth Facebook, they're adding to our gem file and join bundle. Then they're going to go to the Facebook developers platform. I have it open as developers dot in another tab. And here I have Facebook for developers. And you can see the apps that I have open. So I'm going to create a new app, build connected experiences like Facebook, log in, that looks cool. Now, how are we going to name it will name it Ruby gems bootcamp. Just like this. Ruby gems MOOC camp. And create up. Again, I am not a robot. Submit. And we've created an app. Now, what are we going to need it? They'll need Facebook log in. Let's set it up this phone. Now it's taken quite some time to load for some reason. Let's Facebook. Yeah, that's really long. I think it's not load and let's try to go too sudden or some other tabs to see if it works. Okay, sudden folks and Quickstart doesn't fell. Ok. Let's go to settings. So clients of login? Yes. Yes. And forced HTTP DPS. Now if CS by default, we cannot change it. Cause or authentication. No valid ultra direct rules. So here we are going to have an Auto like this, but with the Facebook. So slash diffuses out Facebook callback login from devices. Now, just in case let b, del authorized Kohlberg, we are not using this now. And redirect URI, URI to check. I guess will not use this one either for now. Let's save our changes. And this one doesn't folk. Okay, it was identified as malicious or abusive. So they're not going to be able to use Facebook in development, to look in with the login only in production, hopefully. So we will do it with our production version of the application. Actually, we didn't push heroku for quite a while. So they'll type git, push heroku master, git push heroku domain. And you can take some time for us to push to Heroku. And then we'll use the production oral door. Tried to log into Facebook. What is our production? Oral? Let's try to remember. Let's go to our dashboard at If you have to have our Ruby gems bootcamp. And here's the, let's see if this pool is permitted. He, I just copied the URL and I'm going to Facebook. And we will add slash users slash, slash, Face, Book slash goal back. Okay? And then we'll do it the first one, unfortunately, and save our changes. Okay. It was saved. Now, do we need anything else? I don't know. Okay. The setters in development, we will set it as in production. What do we need to do that we need to, okay, here we have the app ID and nap secret that will add them here in device. So here we will have config on Facebook. We will add this Facebook ID here, Facebook app secret here. Okay, and it'll randomized possible. So my boss fold. And here we have App Secret. I will copy it and paste it here. Ok, going back. And what do we need, privacy pose or terms of service. And they will also be just the root of the application icon that will also add von EPA domains. Again, that production domain category, Let's say education. Apps purpose to access data from yourself or your own business or clients, I will say clients. And to possibly that's it. Let's save our changes and try to move this from development to production, okay. And valid policy through actual created a privacy policy, I guess privacy policy. Seal this ongoing jokes. No, it does not. Ok, let's go to our application and in the meantime, we will push it to production and some convention. Now, most likely we just need to run the migrations. Heroku run rake db migrate because we've created a user stable and some additional features to users like lockable. So we need to run the migrations to update our database. So much work to get Facebook version. Though, that's Facebook. Ok, so now they're connecting to Heroku and run the command rails db migrate and you see some aggressions were on the creative users table. And we added confirmable and added trackable. Now let's go here. And we can actually open the page. So let's try once again. Save changes. And looks like, looks like something you got saved. Now, I will try to move from development to production. Update privates, boats rule. Let's try privacy slash privacy policy. And we still don't have access. Again. Once again, what do we need? Valid privacy policy, all n data deletion information. And they did this in the basic sediments. So right here, okay, possibly just Facebook wants to real access to our privacy policy, but it is not available. So let's go back and they actually have a page with privacy policy. Let's open it in development Rail server. So slash privacy policy mapping to send him to see it. I'll sign into GitHub and go to slash privacy policy. So it is available but only for signed in users will have to make it available for any user signed in or not. So we are going to go to our controller's static pages controller and make it so that users can access the landing page and privacy policy without being registered. So we're going to skip, skip this before action authenticate user for this particular controller. So we will add skip before action authenticate user. And we can add it either to some specific page or for the whole controller. For example, we want to edit only for privacy policies. So we would add only privacy policy like this. Mosfet will add both Lenin page and privacy policy. So now the user doesn't have to be logged in to civil and, and page or the privacy policy. Here. Now we will add some kind of basic privacy policy. Now I'll go to another website of mine, casino. I will go with the privacy policy from here and add this to the privacy policy. So I will go to views that the glaciers privacy policy. And I will just edit it slightly and let's have a look at it. Looks fine. I'll just make it look at lists slightly better. So this will be as a header privacy policy. And they'll add some breaks. Okay, let's actually make this not break spot paragraphs. Let's see if it changes anything. It's slightly dolls. I think it's enough for Facebook. So here we have a privacy policy level. Commit, our privacy policy Control C, Control L, git status. Now I want to commit only this privacy policy file. And static pages controller changes and git status. You see, we are going to come in on a couple of files. You then type to get at all the only edit files and git commit master and make privacy policies available. Ok, now let's type in git push and will push to Heroku, git push heroku, Maine. And they'll wait until it gets pushed. Okay, so I've pushed to heroku. Lets go back to Facebook and see if they manage to get the privacy policy approved. And still not. That's not nice. Boat and valid privacy policy. And the date relation information. Okay, date relation information. I guess we'll do the same. Let's see with folks. Ok. Switch Mode. Looks like it is live. Now, we're going to go and finalize the sentence for Facebook called me out to our gem file. Now we will add it in our beam. The Adam Facebook in device on be ended Facebook. Here, go ad for Facebook. Handle Facebook. And it looks like that's good. Let's start the server. And they tried to log in. Kevin held the signing with Facebook. And we expect to get an error because we cannot log in from our development environment. Okay, and now let's push Heruko. So git status, you get, you get committed, master, sign in with Facebook and git push, novel push to Heroku and see if it works. And git push heroku, master, Heroku, Maine. Okay, and once again we have pushed to Heroku. We can open our Heroku application and we will see the buffalo sign-in, but Facebook, Let's wait for it to reload and now it's been compiled. Okay, sign in with Facebook and we can continue. Okay, and something went wrong. What could have gone wrong this time? That's interesting. Now, let's see the logs, Heroku, logs tail. Okay. We will deploy. Then we tried to sign in. Maybe something goes wrong with the old callbacks controller. No, I guess let's try it once again. It says invalid credentials. Let's try once again. And this time it felt strange. Anyway, and this time the managed to log in with Facebook, namely that for just some glitch. So looks fine. You see it took quite a long time to get all the verifications ready for Facebook and they had already deployed application to Heroku couple of times they had to add valid privacy policy, but in dance and managed to also add social login and whether Facebook. So now we have all these natural offensive but links the login social accounts. And that's it. Thank you. 28. 04 05 display user data from social log in: Now, when a user logs in with the social account, we can save some additional information about him. For example, if we go into that a conditional or melt Google, often we have this outer hash. So it has all the information they receive from the social media account. Then the user is being signed in. We get the provider is basically the name of the social strategy that is used to log in. They get the UID. It is the unique id of the user in this social provider. Than we get information, the name of the user, email, firstName, lastName, we get the avatar. They have some kind of oral to his profile. Then what else do they have? They have credentials and so on. But most interesting tins are the unique ID from the source of social media provider, the name, and the image. So let's try to display them in our application. For this, we're going to add a few additional fields to our user table. So let's type rails, generate migration, add. So at only out fields to users. And now we have a new migration. And they're going to say Add Column. The table Users named provider. And the type is going to be string. So they're going to add the provider of the social media provides them the UID. So you IV. Then we're going to add the name, image and the roles. Maybe. Let's try a sudden, we'll just name and image. Okay, let's try to run the migration, rails db migrate. So if we go to schema, not those reload and see that the have provide the user id, name and image. And we're going to save them when a user is being locked into the social media account. So for this figure into our user or bimodal, and here you see even we create a user. We get email because email post-World. It is automatically generated by device. And if you're going to add some additional stuff, we will say user dot UID equals accessToken dot UID. Than user dot velocity, the health provider equals x slogan dot provider and user name and image. So it will also have user name. And image. Because excess Token dot UID. And here we'll also call user dot save. So these changes are persisted. But again, you see that name and image are nested inside info. So we will have to say access token dot info, dot name, dot info, dot image. And let's see if this works. Now, I'm not putting it in the create method. So it is updated for both new uses and old users. Let's try to start our server and see if this fields are saved. So I will sign into that GitHub. And okay, it says successfully authenticated, but I cannot look in. Interesting. Let's save I, I'll try to log in with another account. I go to users. Okay. This is really interesting. I tried lumped in with a user account with an email that was banned. So I can successful log in and get hope. But it doesn't log me in into their application. You see, I am locked. But the GitHub authentication works correctly. So it's a successful authenticated bought. It doesn't look us in the L. We can look at this issue in details a bit later. So now I will unlock my account. Let me unlock it. Now, I will look into GitHub is just the fastest way. And I will also display that feels that they have saved from social login. In our users partial, I will go to views user. And here I will add some additional fields. They're going to be 1234, is going to be.provider. It's going to be UID, is going to be name and image. And you see they were saved. They have the provider, the UID name and image, but the image is displayed just as a link. Let's try to follow this link. Let's try to open it. What Phillip give us. So I get this image now to display it as an image, we can try to add an image tag. And here we have this image. Of course, it's nice to resize it. Let's go to the image tag dogs and see the basic options of changing the size of an image. Image tag. And we can say size right after volts. Let's try. Okay, let's make it bigger. Let's make it 15 or 50 pixels. And here we have this image. So given go to users. Okay, new location provided because there is no image for some kinds of users. So we'll say E4. If user dot, image, dot present. Then we'll display the image tag and statement like this. And here we have the list of all the users and the ones that have images have an image. Here we have the information that I log in with GitHub. Here's my GitHub joy. He has my github name. If I look into the same email about, let's say with Twitter. Here, I'm logging in. You see, I have another image, I have another UID, and while the same name. So basically like this, we can extract information from our social media accounts and save them in our application. And if you do, we added a migration with these fields. And they added these fields in user RB in the method where the either great and you user o log in with an existing user. And that's it for this lesson. Thank you. 29. 04 06 Social login in production: Okay, so I've pushed our application to the production environment and the application, the latest changes is available at this order. I tried to go to users and I cannot because I need to sign in. So I will try to send invalid social account. Let's try Google. And you say, I got this error, this redirect, you or I does not match the bonds authorized. So we didn't add this URL, this one to our API vitalist. Let's go to credentials. So I've got this at open the credentials, then here I go to edit. And here you see we have our development environment. Your eye available. So they are also going to add the band for production. I'm going to copy this link just without users sign in and edit here and here. But the redirect is going to be slash users out Google, OAuth2, Kohlberg, like this. So the press Save. And it should work. Now, let's try it once again. Our, they'll lock in. I go to sign into Google. I select an account. And IT folks, I will select another account. And it also works. Now let's try another social media account. Let's try Facebook. Facebook folks. Now let's try to return and we get an error. Okay, let's go to our Twitter developer sediments, have our projects and apps. I go to standalone apps here I have RubyGems bootcamp, and let's see. Authentication sentence called the corals are going to have only our development environment available. So let's edit this. And here actually we would need to add our production rule. Now, this is not very comfortable because here we can add only one callback URL. Oh, no, it's my mistake. And we can add more. Yeah, that's fine. So they're going to add the URL for our production environment here. And we will have slush users out with a callback and the press Save. Now let's try to look into the Twitter once again. It will go back. They'll go to log in with Twitter. And it works managed told in via Twitter in production. What is left? That is just Github left. So we tried to sign in and it actually saying this in into the development environment. So we tried to send in production, but it sends us in the development environment. Now let's really funding, buys it. So because in the, our GitHub settings, let's go to our GitHub settings. Here we have this authorization called Becquerel. So then we learn from any UDL we tried to send integral GitHub. It will redirect us to this authorized station called the coral. Now, for GitHub, we would like to create a separate application with our production homepage, auto and authorization callback coral. So we'll go back to develop a sentence and new of AP level name it, Ruby gems bootcamp production. And if we are going to add once again a home screen and the authorization callback URL. It's going to be slash users slash git hub. Let's actually see how it is that the first app, I'll go back to settings, develop a sentence of apps, RubyGems, bootcamp, and slash, users out GitHub callback. Okay. As users out GitHub codec. And I'll press register application. So here we have our new application areas, our client ID, and we'll need to have a client secret key. Okay? So you see for GitHub we are going to have to separate the applications. To separate API applications, one for development and one for production. Because we cannot add multiple redirect URIs. And to make it work, we'll go back to our application and go to our initializers device, our being. And we do have our API keys. So they're going to add a separate API keys for GitHub. So this is what we have for development. And they're going to have separate fund for production. So it's going to be configured on your GitHub. Next, habit, RubyGems put CAN production. Here's our client ID and regenerate a new client secret. I will copied and pasted here. Okay? And we should say that if the Rails environment is development and we use the first key, and if production we use the second key. So we will say something like if rails and of development, then they have this else-if rails and is production then will have this other link and an end statement. Okay, let us try to see what the folks in development at or restart the server. Because we changed that something in initializer and to make it evoke officials restart the server. I will go to preview. And I will try to look in with GitHub on scan, sending it with GitHub. It works. And now we will push out changes to production and see if you managed to lock in the production successfully and not sure direct to the development environment. So we'll save the changes and git status at all to get comment, muster or good commit Maine. And we will say GitHub API for production. Git push, and git push heroku master. Now I'll pause the video, or actually git push heroku main dot Master. I will pause the video and then the pusher to Heroku. We will continue. Ok. So we have pushed the application to Heroku into couple of minutes. Now you can refresh and try to look in GitHub. It's still refraction. Ok. So sign in with GitHub. And I press authorize and success and managed to successful authenticate with GitHub introduction. So in this lesson, we have verified and that social login works for all the social media providers in our production application. And that's it. Thank you. 30. 04 07 credentials and encryption: Now what we are looking at right here is a real security threat. By here, I have my API keys for four different social media platforms exposed so that anybody can basically use them who has access to the code? If I go to this repository on GitHub or is it RubyGems bootcamp? I open the file device dot RB. And anybody will be able to see my API keys and also use them or misuse them. Now, you're using a Becky's of different social media accounts or there is a different quota of how many times you can use them. For example, there can be a limit of 10 thousand logins per day and somebody can misuse your look in trust holes, or there can be other types of misusing your API keys. So you shouldn't let them stay. Just standing like this. You should hide them. Or for example, if you're using an API keys for AWS, if somebody misuses your API keys, you will get built quite a lot. So don't hide our Guy Kiss. And to use such information more correctly, they're going to use Ruby on Rails six credentials. Now here in my blog post, I have a short article on how to use them and they're going to go through it now. So at the moment in our application, have our API keys exposed and they're going to hide them, they're going to mask them actually. And here, if the goto application conflict, they're going to generate a credentials via mail file. So to do this, we're going to type a little VMM Rails credentials edit. Or if you're doing it locally, you can just add Rails credentials at it. So let's do it. I press Control L. I type in this command. And here you see I have a new credentials YML file generated, and a master key generated. Now when you just create a new Rails app, you already have a credentials by no, created by default. So I have this, this credentials YML file and must occur. Let's have a look at them. If I just open credentials via mail, then it is an encrypted file. And this must be key is kind of the possible that is used to open this file. When you type rails credentials, edit your Rails application takes your most key and decrypt your credentials by now and opens it in Vim like this. So this is how this Falcon look. Now, what do we have here? As an example, we have AWS, the ID, and the secret key. So we are going to move our API keys from device dot RB into this file. But now, let's go one scan about see how this file dogs. I will exit this file. I will press escape than this sign. Wq. Enter. What if I say added the master key, I will type something else on top. I will try to open. And you see, I cannot open this file because basically the most Becky doesn't match. If I delete the master key and try to edit the file, then you seam and you must occasion rated, but this must, the key is going to be new. It doesn't know, it isn't the right password for this credentials via mouth file. So if you do it, it almost a musty key, then you'll never be able to open this credentials by yml file. And it will be good to keep this mostly key somewhere locally on your computer because it doesn't get committed to GitHub, to GitHub repository automatically, of course, for security. And so now I'm going to delete this credentials Venmo file that was created by default and delete the master key and regenerate them months again by typing editor vim Rails credentials edit. Here I have this file. And let's try adding some credentials here. So in device we have, let's say return. Inside of bitter will have the ID, this ID, and we'll have secret. And I will cope with the secret. Okay, now I will exit. I press Escape. Then the sign WQ to exit with Satan. And i press enter. And I will try to go to the Rails console and access this Twitter ID or secret. So to do this, I will go to type rails application credentials. Think Rails application credentials dig a little bit, Victor. What if I just typed fitter? You see we get both the ID and the secret. If I'd have Twitter and ID, again, this ID. So to devise a B, they can go and replace these two real API keys that Rails application credentials, big Victor, ID, and return dot secret. Like this. Let's see if it folks in the server. I will go exit rail server. And I will try to log in with Twitter. Log in Twitter. And you've seen it works correctly. So in my device R B, I don't have the credentials anymore. I have them in the credentials by now file. And when this command, I find that Twitter ID and the victor secret. But what if we have two different API keys for development and production like the hub in Github. Well, we'll do it slightly differently. So make like this. We will have. To go back to our credentials file, we'll edit this file. And for a good home, we will have two environments, development and production. And we are going to have the ID and the secret for each of them. So for production, we'll have this ID. And the secret. And for development will have this ID and this secret. Okay? So I press escape this sign, WQ, enter. Okay? Now we need to dig to these credentials together with the environment variable. How can we do it? Well, let's go to our console, rails console Control L and C. So here I have a short guide to how to do it. We can just add Rails environment to sin. What is this image just type Rails environment. They get development. But we need the key to look like, thereby low amount. So that's to make it so they should add to sing. You see? So we will get rails application credentials than the gut Rails two sim. And we have Neil, because first we put GitHub repo to keep, you see, we get the GitHub ID and secret for development. But to actually be more correct, if we go back to Rails credentials edit, and put and put the development and production as first-level. And GitHub will best second level. So we will put get hop, ID and secret. And here it will push production and GitHub ID and secret. Because possibly later in the application if it will be used in development and production lot. Ok. And this will be removed. So they have development, GitHub ID and secret production. Github ID and secret and Twitter is the same for development and production. Okay, and they exit this file. And let's go back to the console and try to find the credentials. So just type rails application credentials and we'll see all the credentials for the development environment. You see we have a GitHub ID and secret. Now we will additionally get home. And you see the idea in secret for GitHub. And if a plus additionally ID, Kevin have their ID. So they're going to take this and edit here. So config dot OmniAuth, get hub. And here we'll have Rails application credentials and of two sim ID and secret. And that can totally remove this line. To remove a line I press Control D in Cloud9. So let's see if this works. Let's exit and start the server. Okay, now I will try to log in in development fifth GitHub. And IT folks. Now, as your homework, you should do the same. You should make their credentials secret for Google and for Facebook. So you should move this API keys into their credentials file, and I'm going to do it on my own. You'll be able to send the results after you finish this lesson and look at the final source code or this lesson. So that's it, basically advantage through using the credentials file, the master key file generated and credentials more than their credentials from device to the credentials file. And I also recommend you to go through that short article on my blog. Everything is also explained. So thank you. Goodbye. 31. 04 08 Make credentials work in production (heroku): And here's one more thing that I need to add. So we have updated our credentials in our development environment. And though I just tried to push to Heroku and I got the problem that precompile our assets failed. Let's have a look further and get this nominated era under the find method. Emptiness for middle-class in device or be it line 277. So let's open this device or the device RB line to southern sudden, let's see. Yeah, and basically our Heruko production application cannot read the credentials. So via iCloud because we didn't provide the master key to Heroku. So but we have our app config here, we have our credentials and did enter pass in this master key to Heroku. So to do so, we need to pass in a command like this, either Heracles conflicts that Rails master key and almost akin or this command that would kind of migrate the contract master key. So migrated ski into Heroku. So either you can type many of your key here or you can just migrate from your application directory. Config must occur. So what I did here, I just typed Heroku conflicts that Rails must be kin. And they added the trails must akin to our Heruko application. And I pushed to Heroku and everything worked. Now let's once again have a look at Rousseau, Heruko, dashboard, Let's have a look at this particular application and go and down here it is, Ruby champs bootcamp. And go into settings and incidents. I have this reveal config variables. And here we have this Rails master key. So now it is identical built. This must adopt key that I have here, 819809. So basically by typing in this command, this command group convict cetera, leaky by kind of Bantu dashboard Heruko to this application than to convict varietals. Pressed, add, edit the trail master key. So it's kind of a quick command for not doing it in the dashboard, but doing it in the command line. And that's how you migrate your credentials and make them go OK, introduction. So that's it. Thank you. 32. 05 01 Create and edit User roles: Okay, so at the moment, anybody can ban a user or delete a user and somebody who is locked. And this is definitely not correct, vigilant but simpler. Anybody ban on Ben or delete the USA, we should make it so that only some specific users can access these links and actions. So for example, admins, they can make it so that admins can ban and on band and delete users and other kinds of users cannot these functions. So we would like to add an admin role to the user. But what if there are more roles? What if there are admins, teachers, students? So now they're going to make functionality for ad-Din roles to users and selecting the ban on many roles for user just like this. They're going to make it so that we can edit roles for user making an admin at Tisha student or any other combination of roles, the user will be able to have banjo or be able to have many roles. Now, again, here I've got a nice blog post based on which we are going to do it and have all the sample code that you'll be able to use or any of your organ Rails applications. So first of all, they're going to add a Rolls field to the user. Now, there's going to be just one field in which we are going to keep the information about all the user roles. So they're going to type rails generate migration at roles the user. Now I'm going to stop the server control l. Let us see if there are any changes. No, they're wrong. Let's type rails generate migration and draws to user. Okay, now let's go to db, migrate agile user. And here they are going to add this content. So change. So too the table Users, they're going to add a column named roles. It is going to be of the type JSON being, it's not going to be null and by default it's going to be this slab races for JSON. Okay? Now let's run rails db migrate. Okay, so next we're going to add the concern where they are going to describe the information on how to use this roles don't generally it is something that can be packaged into a jam in the future. If you turn this integer, it would be also cool. So now we're going to go to our modals. They're going to models. And in our concerns they're going to add a new file and we'll name it. Rho. Rho double dot are being well drawable for like having roles. And in this concern, they are going to paste this content and have a look at the quantities. Basically, they're going to set a list of roles. It'll be admin, teacher and student. You can add and in roles that you like in the future. So it can be client or whatever. But for now we will have admin, teacher and student. And the oldest code is kind of the magic for turning it into such a form. They can be that they are saved as a hash with either true or false. So Admin, true, teacher, true, false student, true. And here they're going to have a couple of validations. So they're going to have adaptation that a user has to have at least one row and there has to be atleast one admin in the application. Again. Now we've added this module, rollerball, and we say that they're going to use row label for our user Nodal. So in our user model they're going to include this row-level. Basically by saying employ Jolla bowl, we inherit averaging that is present in this module, rollerball. Otherwise, we could just take all this gold and based it here. But if you don't want to clog our user model, that discount, that will just say include drawable in our user notable. And here we will have a oldest. So role-based, the logic in this roller will concern. Ok, well, now we are going to add this functionality for editing the user roles. So let's start our server, Rail server. And we're going to add a link to edit the user roles. Now it seems the server installing, Yes, it is running. So in our user versus our view, our views in our user vagrant ad and you link, it is going to be equals link to it, rolls and the path is going to be the regular user edit path. Actually, we need to add the spot to our rules. Here we have resources users. They're going to add the buffed door at it and to update. Ok. So we are going to have the door and it user auth at user. Okay, let's see if this part is available. Now, I need to close the column. Ok, now they have this link to edit trolls. But if I press the action, edit couldn't be found in the user's controller. So we are going to our controllers, uses controller. And here they're going to add the action, edit, add and edit Wilson into BIS, the user. So user, user find params ID. Let's refresh. Now it is missing a template. So we need to go to the US. And in our use of use, we will add template for adequate dot HTML dot ERB. Now I will open and have a blank page. When that navigates to users, says lash, the user ID slash ended. Okay, so now we need to add a form. Well, here also I have saved form. Basically it's irregular form for user. It's a regular form that give it having any Ruby on Rails application than the regular error messages. And here it will list all the user roles that are available in this in this rollerball concern. So realist, admin teacher, student right here. And they give a checkbox to say either true or false for each of the roles. And the scout and see how it looks. There are going to edit. And here it is, we have the option to dig admin, teacher or student. Let's try to submit. And the actual update couldn't be found in users controller. So we will add the action of date def update. And okay, the action update could not be found, knowledge to be found. Okay, and we need to pass the user. Again, the actual update cannot be found. Let's go to users. Let's try to add a trolls update. And val. Nothing happens because everything we do here is just fun to user. Solving it to add the logic for updating the user. So we will just again copied from here, we will say that user update that user params. And if userData drag to the user, either run the edit to the errors. And importantly, they're going to add this user params. So in user brands, we're going to permit the user roles. So by doing this, they say that the in our form we can edit user roles. We will just copy this and add it here. And use and move our user params to a private method right here. So k We have an edit action and an update action. If we pass user update, then we take our user params that are allowed and we update the user roles. And the director of the user that usable, successful, updated, otherwise render editor. Okay, let's see if it folks. I press submit. And it says usable, successful, updated. Let's add the roles and you see the admin role was saved. Now let's add one more row and press submit. And you seem both roles for persistent. Now I will try to take all the roles of a, and it says, a user must have at least one roll and there should be atleast one admin. They get this errors from our row-level concern. Here, you have the stability. Nations must have an admin and must have a role. So lose good. Now we can edit User Roles. Let's also display the user roles in the user profile. So here in the User Page, swivel displayed the roles. Now here in this roller ball dot RB and also past. And method called active roles. So here we will see all the active roles of a user. So let's go to our user Pashto and display the user roles. Now dash or the duke. No, let's do it again. On the very bottom. I'll just go to someone and have a will have roles and user dot active roles. And you see we get admin and student. Now I will editorials. Let's make it on the element. And you see, we get admin. Now, you see we have these roles not in a very readable format. So they're going to make them more readable. They'll go to our user page and heavy we'll add join the coma. So they will be separated by a comma. And no such fun science. Let's see what folks I save. And here we have just roles, admin. Now I will add the tomato roles, roles, admin, digit student. So looks fine. Now we can add roles to users. Let's see another user. The kid doesn't have any roles. I'll press Edit trolls, thus making just a student. And he's a student. So looks nice. Just now we've added the functionality to add or remove user roles. But let's play some marvelous. What if we go to just the user and show not just active roles, but user dot, dot roles. What will it give us? You've seen it passes the whole JSON hash. We have admin falls, student, true deja falls. And here we are person, only, the active roles. So the roles that set to draw, let's edit the roles at an admin and VC, he's an element and the student that has admin show student true, teacher false. And also we can add roles in our console. Let's switch to the server off Rails C, run the rails console and type user dot first. And let's see, user code doesn't have any roles. So let's try to update his roles. Let's say user first dot update, Admin, true. And let's type again user first and VC, he was given roles admin true. So by just dive in user first update Admin true, we sat him to admin. We can also set him to teacher. So now he is both an admin and a teacher. And let's make him not an admin anymore. Let's make it user first update admin. False. Now once again, we'll use the first NVC admin, false digital. So this way we can take rolls away or give roles to users via the console. And that's it. Now. Again, this fight complex functionality, but it is still much easier than all the code available in any gem for providing roles to users. And this way we have just one field in which we can have an unlimited quantitative different roles for a user. So in my opinion, this is the easiest way to add roles functionality to Aragon Rails application in the 2020 bomb. And again, what did we do here? We've added a migration to the user's table that they added roles field than we've added this roller ball nodal. Our concerns in our modals concerns are available and we've included it in our user nodal. Then in our user view, added the link to edit the user off and to display the active roles in the routes with vital listed edit and update actions. In the controller. We've added the actions for editing and updating and have added the user parents that are allowed. So the user roles I allowed and Vivre updated the edit form. And that's basically it. Now, Let's have a look once again at this edit trolls view. Okay, I will stop the server. And we can just make it look and been better. So we can say like editing roles for the user and the link to cancel. Let's go to the form and heavy we'll say editing roles for at user. Okay, I need to pass this in Ruby code. And it enrolls for equals at user and will pass Now again, then we just buzz at user. We are getting just this user relation. Not to get this relation, we can just add something to user B, like toString. So Daf two, S and Kevin will pass email, Harold BUS email. So that I can just call the user. So the call at user, the gut and controls fall and forget the email or the user. Now let's put it into header or let's make it. For example. I didn't roles for this user. And we'll also have a link to cancel, link to cancel, delete to the user pump link and user. User. So we have this text editor enrolls for the user, and we have the roles and have the submit button and a button to cancel. So looks fine. And now I'm just going to remove the unneeded code volume of this at user roles. And I will come to the changes and that's it. So again, Everton is really well described in this book post and you can just go and paste the code from here without any virus. And feel free to ask questions. 33. 05 02 assign default role to user after creation: Okay, so now I'm not logged into the application. I will press log in and have a look in the actual I will create a new account. I'll sign up. Let it be this e-mail sign-up. And I've tried to send up I got a message, vehicles mission Lincoln summed. Okay. I will confirm my account. Are gonna go down here. I have the logs. I will open this link. I've confirmed my account and log in. And you say I don't have any roles by default. So they'll make it so that when a user creates an account, he will get some kind of role by default. So let's go to our, we can actually do it either in user_data RB or in our rollerball concern about, let's try doing because they use a dot RB. So we will create a callback after great. And of the credit we're going to assign a default role. So after great doom and, and, and what we're gonna do is assign default row is just the explanation. And we are going to do something like self dot update student rule. Okay, so let's see if it folks now we are going to create a new account. Now, I see that something is the loading. Let us see if our Silverberg is here. The server Doesburg, but the console doesn't. So I will refresh the page, maybe have something rounded my internet. Okay, let's reload. Let's see what the changes are. Now the changes are not saved. I shouldn't have crushed reload. Okay, I will type the concern one scan. So after save, do after crate doom. And, and they're going to assign default role and self dot uptake student from okay, saved. Now I'm going to create a new account. I'm going to sign up well, take let's say this email address. Now I will confirm. And you see by default I was giving the student show. So this way we can use callbacks that actually a lot of different callbacks that are most common ones are after crate, after save, after update, after destroy. And the way they are going to assign default roles for users. Now, let's wrap up. Let's check git status, git add comment, Maine. And the comment is going to be assigned default role to user after creation. And that's about it. Thank you. 34. 05 03 Authorization only admin user can edit user roles: Okay, so now I'm logged in as a user. I go to my profile, I see that I have the role student, but I still can edit trolls. I still can band let and been myself. Yeah, that was fun. Okay. So I'm logged in as some kind of user. I can edit my roles, I can ban, I can delete the user, and it's kind of not correct. So they're going to make it so that only admin users can delete, ban and edit roles of different users. And they are going to do it in our controller. So here we have our users controller and Kevin going to add an authorization layer. So we will say that only admins will be able to access the edit, update, and destroy actions. Okay, so to do this, they're going to write a before action. So it's going to be before action. And we will say require admin. And the admin will be only for these actions, only for edit, update. Dan, Ben, and destroy. Okay? And we have to write this before actions, so we'll go down and here in private fear going to state deaf Require Admin and is going to be unless the condition is going to be a current user admin. So if the current user is not admin, they're going to redirect to the root of a notice or with an alert. You're not authorized rised to perform this action. Okay. Let's see if it folks so I will refresh. I'll try to press and I'll, I'll try to edit trolls. And you see, you are not authorized to perform this action by because I had the role teacher, I tried to delete. Again, not authorized to perform this action. Now we can make roles for different users. We can make it either for admin of student of tissue we can add unless current user admin or for example, current user_data teacher. So in this case we are requiring either admin or teacher. So I'll try to edit trolls. I'll add myself as a skill and you see I can do it because here I allow both admins and for teachers. So this is the easiest way you can implement the authorization into your Ruby on Rails app. You can write separate callbacks for admins requires students require teacher, require admin or teacher, or, and so on. And that's basically it. Now, I will comment this line out. Just, I've lived here for reference, and here they're going to live just unless current user admin. So here be quickly made it so that only admin users can edit trolls, ban, and delete other users. Now, let's make the links invisible for users that it cannot perform these actions. So they're going to go to our user partial and have these links. So they're going to put them into an if statement, if current admin. And then they're going to see these links. Now we have to close it with an and statement. And let's see. So now only admin can see these links. And let's actually look in as an element that we have an admin. Yeah, this account is an admin. I'll press log in, log in with GitHub. And thus this is the right account. Yes, I'm an admin and I see there's buttons to either trolls, to Ben and to do it a user. So that's basically the easiest way to implement role-based authorization in Ruby on Rails. Thank you. 35. 06 01 responsive tables with bootstrap: Now, I guess it's time for some styling. So I'm looking at the page and we have six users and some very comfortable to navigate through all the users. Imagine you have 6 thousand users and you'll have to go down and look at each of them to make it easier to navigate via just going to move all this data, first of all, into a table. So let's go to our users index. And here, what do we have? The list all the users and render the user partial so that the have the view of the user login the same as the user looks in the list of users. So now they're going to add a table. And while this is a basic table, so we have add table hadn't fiber have their email but have some mental other data. And table body. And inside of the table body already we are going to add this listing of users. Well is the simple way to do that any scuffled. Let's see how it looks. Let's go down. Yeah, so here we have a list of all users. And we can add this user data that have in the US at my shell into this table. So what do we want to see in the table? First of all, yes, let's have the ID. So we will add the user ID. And they are going to add a link to use a show. So you'll have link to just copy this link. Okay, I'm copying this link and paste in here. And I think if we can remove the list of all the users for now, the one that we have with the rendering of partials like this, we're just going to replace it at the table. So here is our table. We have that user IDs. If you press an IDP, navigate to the User Page, sort of had the idea to have the email. What else do we want to see? We want to see if the user is confirmed. So we'll add confirmed. And we are going to say equals user dot confirmed. Yeah, basically we are just moving all this data into a table. Okay? This, if the user is confirmed, next, we're not going to add that information from trackable. We're not going to add the sign-in count currents and in, we're going to add the information to see if the user is logged or not. Actually, we don't need to see that date. We can just add the, the way we did in our example. Controller. Let's alter uses controller. And here we have user_data access locked. So we'll show true or false, but not just the time. So here we will add a table header. The question will be banned. And in the table description, the D here equals user dot access locked. That will run the either true or false. So band, true or false. Looks fine. Then what are the information that we want to see them to see the other information of all the social look in possibly the username if it is present, let's add the username, table header, name. And here we will add Okay? And you can also add the image. So they're just coping all this code. And in that table data, we're going to add this block to render this image if it is present. And here we're going to add the boat image. And like this, we can display the image of the user. Now we can make it also smaller. Let's make it, let's say 20 pixels by 20 pixels for example. Yeah, just for to be that if there is an image, you will be able to see that there is an image. Now let's add the roles. So we're going to add roles. And here we will have user dot additive roles join by a coma. Yeah, I'll just copy the whole line. Now going back to the d. So now they're also displaying user roles. It looks like I have username pi sine removing it. Okay, here have the user roles. And after the poets we're going to have the actions. So they're going to have this block. If currentUser admin, then there are going to be at least three links. Again, table data. Inside they're going to have these links and clothes and table data. Okay, so this looks more. Can we have a table with users? Let's make this all uses formed to be big. Like H2 for example. All users. Let's me just users. And OK, here we have a list of our users, VCB equal to six users. The IDs of the users. Email addresses confirmed, bound, the name of the user, image, roles, and even navigate to a specific user. We will see more information about him and the same navigational links and the actual links if the admin user, now for example, I will log in as I will just take away access, access rights from this user. I'll go to Edit trolls, remove admin. And I'm going to this page and you see I don't have these links. Now, I will log in as an admin. Once again, I'm going to log in. I'll log in as another user. And here I can say these links. Okay, now let's make the table luke. Also better. If I go to bootstrap and go to docs and go to tables, then we see a lot of stuff that we can add for making a table look better. So for example, we can add table, cloth table and have you got some Bootstrap styling automatically edit for the stable. Now what else can they add? And we can make it table-striped. So table, table-striped than they're going to have. What else can we add? Table hover so that we can Homer and see the line highlighted. Table, however, you sent out get highlighted. And while we can also make it bordered not we are not going to do try to Bay. Yes, let's make it a small table. Table as m. Okay. What else can the ad should also be a close like table responsive young. So they're going to also put this table into a table responsive clause. Let's see how this would work. Let's copy this responsive table and paste it here. Now let's refresh. Here we have this responsive table. Let's see how it will look in BioVU. Now, I'm using Firefox. I press right-click and inspect element. Now here I have this button to responsive design node. And let us see. Now this doesn't seem to be really responsive. You see? I move the table and the whole application moves with it. So they'll try to put it into a table responsive div. So let's try to do it like this. Let's add div, class table responsive and close this div. So we are having the whole table inside the div. And let's see how it looks. Here. The half, okay? And you see the table is moving, only the table and we get this navigator that this table is moving. So like this, we made our table also responsive. Now I move in it and that navigation stays intact. So looks cool. Now what did I do? I added the whole table into a div with the class table responsive. Ok, I'm proven moving this second table that I've just added and looks called. Now I'm going back to the full screen view. And here we have a nice table with all the users and a few actions that can be done on the user's. Now we can also add some kind of nice talent for these buttons. Let's search for something like buttons. And we can add some styling for these buttons. So we can add some kind of clause like class, button, button, smoke, button, bone-in. You see as m grows, as m should be the smallest bottom. Now, Ben is also going to be a button, but it's going to have another color. What color would you like? Lets see what colors are available by default. Let it be red, so it's going to be danger. And for deleting, it's also going to be danger. Okay, so looks good. You have a few buttons to add. Chose to bound the lead user. I'll try to ban another user. Okay, he was banned. It was unbound. Going back to all the users. And let's also add this button styling on the User Page. So I go to a user and then we'll also have these as buttons. So here in the US are partial. I'm just going to add another clause everywhere. And here it's going to be a button phonon and hear danger. Solar disk. I added a few Bootstrap classes to our application for glucose. Kind of pattern. Going to edit shoals. Okay, so what we've done here, we've created the table where we have a list of all the users. We have done it using the Bootstrap classes, and we've added a few nice looking buttons called mail. The buttons look nicer. So that's it. Thank you. 36. 06 02 Disappearing flash messages with toastr: Okay, so this is how messages look in obligation at the moment. Basically the van to our layouts and fabricated and pass shell that we have. This if node is present and if a look present, forget either Backgrounds access or background danger and they're taxed. But what if we wanted to make this look more beautiful and power make them disappear? And so to do this, we can simply add the library called the toaster. So here's library, you can go through it. And basically we're going to add such kind of disappearing messages to our application. So this can be installed into our application just as Bootstrap Font Awesome, via a young package. They're going to type John at Tosca. And next we're going to add those in our application ab.js. So they're going to our JavaScript's backs application JS. And here somewhere, well, on the Font Awesome, for example, vagrant, add this toaster. Now next, though, again, you can see this information here on this toaster GitHub page, but they're doing for our young and not into installing it via Jim. Okay, so next in our stylesheets application SCSS, we're going to import Tosca. Let's go to our stylesheets application. Scl says and here the important Austin and do, what else should we do? B are going to change the way our flash messages look. So now we have them like this and we are going to replace it with this code that folks could toaster. Now we can try, haven't both at the same time. Let's see how it works. So again, I will try to unbound this user. Okay, I need to start the server, Rails server. Refresh. And now it's taken us a while because we are compelling new yarn packages that we have added. And you get this message, you see user access locked false. So this is the default view and you see it, this is already a disappearing message. Now I on ban the user. I can pass this message and it also disappears. I can press a few buttons. And you see here is this message. So looks fine and display we can easily make messages that will be changing in the sidebar. And though they will look more beautiful than what we have now. So I'm just going to remove the old code that we had for messages. And they're just going to live. And it's those the j s. Now I'm going to try to log in and sign an inverted GitHub. And you have got this message successfully authenticated from GitHub account. So looks nice. And that's basically it. Thank you. 37. 06 03 footer at the end of page: Okay, so here we have our application and ruler often vote in most web applications, you will want to have a filter on the end of your page. So how can we accomplish it? Well, we can go to our obligation HTML and to try to add something on the yield. So here we have yield, and it will add some kind of content here. And it will be right under this yield. Now you see it is inside the container. I can also move it out of the container. Or I can even try to omit out of the body. And it is also here. How can we make this conduct always be on the very bottom of the page, no matter how big the page is, not after the content on the end of the page. Well, here's again a small tip that I've got going to cope with this CSS code. And we're going to paste it inside of assets stylesheets. And now by default to have application dot CSS, they're going to rename it to application SCSS. And here on the bottom they're going to post this code. And again, now we've got a head, a body, and we are integrating a new footer gloss. So we're going to add and we're going to add folder content right here. Now go refresh. And you see that for the content is always on the very end of the page, on the bottom of the page, it is dynamic no matter how big our page is. So looks much better, in my opinion. Now, you can make the folder like this and customize it. Anyway, you own, for example, you can have a link to the, let's say privacy policy. You have to have our privacy policy. Let's add a link to it in the footer. So we will do add, maybe also contain across to the footer. So Folder, class container. And we can also add small breaks so that there is some space. And we can also add some kind of special color like dark backgrounds. So background dock to the footer. Now doesn't look really nice if we can make the footer background full length, let's make it like this. Footer gloss Background dog. Okay, and after this they're going to have a div with the class container. And inside this div, I don't have the footer content. Okay? Now we can also add the FQ breaks like this, for example. Oh, what if I tried to direct graph on the bottom and on top of the footer content. Well, just like this. Like this. Okay. And we can change the color of the text. You said the background is dark and that's because also black. So we have a background. Talk and text can be light, for example. Okay? And if you add a link to the privacy, both will have. Because link rioters scene. Let's see. And it's going to be privacy. Always seen above. This is the correct path. Yeah, the BOD is correct. And you see, they're always going to have this link to the privacy policy. On the bottom of our page. Looks fine in my opinion. Now of course you can make this full divider. We can add the additional row. Okay? We can add the footer content row or maybe break with a paragraph and you see we can make it as five would like, and looks already quite fine. So that's it for this lesson. We've just added the some tiny CSS. And here we've added a new footer into our application, HTML, into our main layout for the application and the ruler, this is the easiest solution. I found the whole internet for making SDK photo that is always on the end of the page. So that's it. Thank you. 38. 06 04 styling for true false values: Okay, so as you see in our application, we have if you boolean values that can be either true or false. And to make them more readable, let's make it so that all the true values are green and red values are, I mean, all the false values are red. So we can write a new helper to make it look more beautiful likeness. So let's go to our application helpers. And an application helper. They're going to add a new, a new method that'll be cold. Therefore, Boolean label. And we're going to possible in label and value. So this means that if in our views, users index the bus, something like So instead of user confirmed full bus Boolean label and inside we will have user confirmed. Then we should have that contents. That'll be inside of this method. And let's say it will be just Yes. Let's see if it folks. Let's refresh. And here you see it's yes for everything. But we don't need to have a just yes. We want to have about the value and the value to be but some kind of color. What if we just have the value? Again, we have true or false. But if we want it to be a conditional, goto tried to something like case value. And if the value is true, so van van true, then they're going to have one kind of information and Van false, they're going to have something else. So we have this case and we need to close the case that an end statement. So then true, we can have something like yes, yes, yes. Ok. My mistake here. Let's try. Yes. Yes. Yes. Or just something like this. And then falls. It will be No, no, no. Okay. Refresh. And you see here this just everywhere and hear about we don't have any accounts that are not confirmed. Let's add this Boolean label to our user access logs also. So do you see how that false also looks? Okay, so see, now we've added some custom text based on the value. And now we are going to also add some kind of styling, styling. So for this we are going to add something like a content tag. So content, type and type span data will pass in the value. And they're going to add a clause. So the classical beam, close bench, bench, success. Let's see if this works. Okay, so we have true, we have a badge. That's us true and that is the success of bootstrap color. So that is green. And for false told are the same, but the same danger. And simply like this, we make our application more color-coded and look nicer. So all the true, all the Boolean values that we have here are wrapped in our Boolean label helper method. And it looks much better. Now we can do the same if they open a user page here, do have any true or false? Yes, perhaps with a confirmation. So we'll go to our user postural. And here in the confirmed, AT confirmed, we are going to also add Boolean label user confirmed. And looks really nice in my opinion. So what we did, we added at new helper that in which we pass the value. And if the value is true, then we have the value wrapped into a badge, success and band the value is false, forget the value wrapped into a badge, danger. So that's it. Thank you. 39. 06 05 styling user views: Okay, so I'm looking at the list of users and if I go to Edit trolls, i c, Now this isn't entrapped into a nice cold like the other views. So they're going to wrap the edit and actually also show of the user into couple of calls. So let's go to editor. And the same as we did with device. Let's open our device. The rapid all into calleds. So let's wrap our use of view into cards. Also. Lets go to users edit. And we're going to wrap it all into calls. How did we do it with the device? They had a god header, a god buddy. Here's the car body and a called footer. So they're going to put this editing rolls into the code header. Then they're going to put the form into the body like this. And I will just update the indentation. And they're going to put this link to cancel into the code footer. Okay, now let's refresh and looks nicer. Now we are going to cancel. And now we see by looking at the user page, there go into also rapidly into a god. So let's open the users show low. Ok. And we are going to wrap this into a cod. So we're going to have there, we're actually not going to have a cod header. We're just going to have called dominion to close the div. Then they're going to have gloss God body for the partial called muddy close this div. And they're going to have God footer for the link to all the users. Let's see how it looks. Yeah, looks nice and book The called footer doesn't seem to be working. Let's see, a vine. Okay, I put it called body, called footer. Yeah, it looks nice. And actually previously we used this user partial HMO, the index and the show US. But now we are not using the user partial for their index here using a table instead. So we can totally removed the code from the user partial and move to the user show. But there's a problem. Here. I've said that user equals at user. So in the soul view, the login for the user, but in the partial will have just user. So if v, let's say go bit SCO and pasted here instead of the partial. Now I'll update the orientation. So I pasted this code instead of the PowerShell, then it's not working because we have an undefined variable user. They have the variable at user. So they are going to have to update user two at user program. Just like this. So at user image tag alkyd user_data image than user active roles. And they use a path at user, at user, delete at user, and I guess that's it. Let's refresh and see if it's Falcon. Okay, Ben status must also have a user and it's working. So I can ban or on bundy user. Looks nice. So we've added called partials for our And that view for user and for our users show. Now, let's go to our homepage. A homepage doesn't look really nice either. So here I have just some sample data and fall. It is fruit for you to edit the home page and make it look like you wanted for your real-world application. You'd go into static pages. Here, have the London page and privacy policy. So I invite you to the homepage and turn it into homepage or the project of your trains. And actually one more thing, if I sign out, you say I signed out and I have a link to users. And you see I have to look into Syllabus link to users. So I'm going to make this link invalid, invisible if they're not logged in. So I'm going to go to our views layouts header. And let's find this link. Link two uses spot and we are going to make it available only if there is a current user, just as we did here. So if currentUser, then they're going to have the link to users path like this. And we refresh. And looks good. 40. 06 06 3 ways to change background color for the app: Okay, so as you see, I have slightly updated our landing page. And next thing, what if we tried to change the background color for our application? Now it's finite. And what if we make it another color? Well, there are two ways. The first way would be to go to our app, assets, stylesheets application as CSS. And here we would add something like body background. And the background would be, for example, yes, green. So it's green and then make it blue. And it's blue. Now we can use something like a color picker and select any color like so. And it doesn't have to be just blue, red. You can add the hex color. So for example, it's like the scholar. And I'll put this cover here. And here it is. And the second way would be for us to go to our views, layouts, application HTML. And here we'll add style to our body. So for example, something like this, background-color, powdered blue. And we don't see it because they're a CSS file, overrides our HTML file. So I will remove this from our SESS file. And you see we have the color that facade in our body. Now, we can also add the it as Bootstrap style so we can have some like background. So we would have gloss, Background, dog, or background denture. Just like this. So here are three ways to actually add the our body background. Vo1 is in the SESS file data to be bothered with a cloth and another would be modeled with a style. So that's it. Thank you. 41. 07 01 gem devise invitable create and invite users to the app: Okay, so now they going to add some functionality to be able to invite users to our application. Meaning there will be a formed by we can fill in an image of a user and he will get an invitation email. So to do this, we're going to use the jump device in writable here, have the homepage of this gem open, and now let's go and read the reasoning. So going down, we have Jim device invertible. Let's add it to our jump file. Here's our Gemfile and an add-in device invite double. Now I'll stop the server that's typing git status to check if they have any uncommitted changes yet, added something to the gem file. So quandl. Now next we're typing rails generate devise invertible installed. So when I type this, you see something that was inserted into device dot RB and credit and new file device and writeable by ML. So the translation. Now let's have a look at what was added to devise dot RB. So they're going to config initializers, devise dot RB, and let's search for invertible. So configuration for invertible was inserted in the device RB. And we are going to look later on on how this all works. So next we're going to rails generate, devise and vital for our user model. So what? Inviting our users. So rails generate, devise and vital user. Okay, let's have a look at this migration that was generated. So we are going down to db migrate. You have this migration and heavy seen invitation token invitation traded at cent, at meant was accepted than the invitation limit, than by whom they buy what kind of identity the user was invited. So divided by a user or client or whatever. Well, for our case it's going to be usually user, my invitation count, the token and the ID of the user that the sand the invitation. Okay, so let's type rails db migrate. Ok, we've added this. Let's go and see, okay, we need to add in vital to our device in our user model. So they are going to use our app modals user RB. And here I didn't invite bubble. Now I'll remove this line. So we've already added lockable. We're not going to turn out to bool. We have added trackable and on the routable. So the only one that we haven't added the add is time routable. Bow tie notable is basically the session expires after a period of time. So for example, if a user span smuggling demands in the application will be automatically logged out, it is useful for an application like a banker application. So if your sand invert alone than you, they'll be signed out so that somebody else doesn't access to your account. Okay, let's go back to the recommendation. And what do we have here? We have rails generate, devise, and writeable views. Let's try to generate these views. I'm going to the console. Rails generate, devise and vital views. And we've added, what have we added? Let's go to our views device heavy have edit invitations and we have added and although heuristic new invitation view. And here's the edit invitation view. In the new invitation view, we can input an e-mail and send the invitation. So let's see how it really looks. Let's start our server, Rails server, and have looked at these views that are generated. Okay, the server is running, let's see the routes that were generated for these cues. So they have new invitation for a user. Let's go here and let's look for new user invitation path. You see this, you use the invitation particles generated by this device invertible. So let's create a link to this new user invitation path. Let's edit, for example, at this link in our and now I will look into the application. Yeah, so we'll add this link and our users index page. Or we can edit the here in the header. So let's go to our header layout, Hadar. And here we will add the link. So if currentUser equals link to invite user, and the path is going to be when you use an invitation path. Now it is going to also be having this same classes. So gloss, now blink and active. If current page. Can you use invitation off. Let's refresh. Okay, has some kind of error. I then close the braces. Okay, and here we have this link to invite user. So we go here and have this form. You can send an invitation. Let me try to submit. Email can be blank. Let me try to invite the current user that is signed in. And the email has already been taken. So I'll invite another user. And an invitation email has been sent to this user. So let's have a look at the console. And here is the email. Hello, via tomorrow, someone has invited you to this app link. You can accept it through the link below, has the link below, and that text's invitation. If you don't want to accept the invitation, please ignore this email. Okay. So let me press accept invitation. Now, I will first log out of this account and now I will accept the invitation. I press Open. And here you see we go to this user's invitation, accept. And here we have the invitation token that was sent in the email. So I can set my passport and if a login. And here you see the regulated to users in the patient's edit view. You have to have a device invitations added. So we are directed to this view, but added this view, I'll type some kind of text on top. And you see this text is visible. Okay? So I can type a possible I set my possible and your password vault successfully. Sat. You are now signed in. So I was invited and I managed to login as the newly invited user after confirming my account. And I'm I confirmed automatically? Yes, I'm confirmed automatically through device invertible. Oh, okay. So let's go back to these views and also make them loop fruity. So let's go to New. And they're going to add all this God clauses. So they're going to, somebody here have bought of the scope so that we don't have to copy it each time. Okay. I'm going to devise invitations. And I'm going to move this to the cod header. And the form is going to be in the cold body and know called photon. Okay, here's the updated send invitation view. And let's again send the notation though. This user will go to the console as set the invitation. Okay, I got this arrow that you're already signed in, but my sign out. And once again, try to sum this invitation open. And let's see. And nothing happened. And what was that email again? I have this email Samba. I'll try to log in. Ok. So I'll try to look into the email. Now. I'll go to lock in and have it have to go to the interests of confirmation instructions. Yeah. It's all because I tried to log in while being locked. I tried to send the invitation about being logged in. Okay. I shouldn't have done that. Now I'll try one scan. I'll try to invite another user. I'm inviting this user. Now, I will look out and I will accept the invitation. Let's see. Okay, I need the presence assembly invitation. And here is this view. So they are also going to edit the skew for added so called header, god, body and closing the depths. So the skew also looks a bit better. So I'm going to set a possible and I'm logged in. Now let's try to invite a user and represent the invitation valid, been logged in once again. So here's the email. I send the invitation, I'm going to the console. Let's see here as an invitation open. And yet we see if we get this error you already signed in. Well, it's logical val been signed in as one user use and able to accept an invitation as another user. So that's it. That's the basic installation of device and vacuole. We've added this link to invite user and the van and email address is filled in. The user gets an email that taken as an invitation and create a possible, and in the meantime, his account is created. So let's create one more account. And you've seen the account was created but it's not confirmed. So the user has to still confirmed via the email, invitation email. And that's it for the basic installation. Again, what did they do? They added device and vital to the gem file. We edit the configuration for inevitable in device or being in USA, beaver also added in writable than degenerated the device inviolable, new and edit fuse. And in our head of v and a link to invite a user. So that's it. Thank you. 42. 07 02 devise invitable docs and views going deeper: Okay, so we have installed device and viable, we can invite user. And now let's look deeper into the documentation for devising writable. Let's open our config initializers, devise RB. And here we have the configuration for invertible. So what options we have? Invite for a period of time. So an invitation can be expire trouble or not expire trouble. If we say invite, for example, two weeks, then after two weeks the invitation will be inactive. Now they're not going to at this invite for growth of time taken to make it so that temptations while they'll always be, can. Then number of invitations uses concerned? Well, for examples, so that you don't want to sound like a 1000 invitations for different uses, you can add an invitations limit. We're not going to add this either. Then the key to be used to check existing users when sending an invitation. While they are not going to add this either. But basically, we can check if a user with a specific username or email already exists. Then validate on invite, then ensures that invited record is valid. By default, it's true and valid in this true housetop. The invitation won't be sent if this chuck fails, default is false. Now, OK, we'll leave it false. Mutation if user within that status is invited again, yes, of course, we will be able to resend invitations than the class name of the modal that is inviting other users felt really have uses inviting other users, not for example, admins or not clients inviting other users. For example, if you have to devise modals, lung is user and lung is admin, then you would want to have possibly invited by hostname admin, and then foreign key for the invite and nodal invited by ID. So the idea of the use of that invites other user, okay? Than invitations count. Again, it's counting how many invitations or use a son. Then auto login after the user some state invite. So by default it's true, well, they'll go and deliver it true? So when a user accepts her invitation, sets a possible, you'll be automatically logged in. And that's basically it. So now we can add the actual sum, invite verbal information to our uses a table. Let's see what we can add from invertible. Let's go to our migration and what fills the gap. So let's try to display this fields in our users index. Now begun to close a few things that we're not using. Okay, so we have used as index. And what do we want to display invitation token NOW than the time when the invitation was created by the can do it if the bond invitation sent at Monash station accepted at in the patient limit. Okay, let's see by whom a usable invited. So let's add the something like invited by ID, invited by. And if a usable is invited, and then it will display the ID of the user who invited this user equals user dot invited by ID. And if the user was invited, we set the ID of the user who invited this user. Then we can go to device in writable and see some of that recommendation. What else does it offer us? So we can do a custom action in our console like user_data invite. Let's try this. Let's go to the console control C control l, rails console. We have tried to invite a user and His name will be joan though. Okay? And you see he was invited. The user was created anthropocentric. This invitation. Let's have a look at this user, John Doe in our user's table. You see like this, we can invite users using our console. User_data exclamation mark that email and we can provide anything else, but we don't have to. And again, you see, it was given a default role of Student. Now, is there anything else that might be interested in here? Ok, not much more in the gem file. In the gym. With me, we can go to rebuttal info and system or information about devising vital. So there are some methods that we can use becomes a set invitation. Let's see. You can check if the user was created by invite With a boolean. That's interesting. Let's add a field to see if the user was created by invite o k. So we will say user dot grade that invite question mark. And the seed true or false. So obviously chooses was created by invite and which ones were not. And actually see, we have created by ID and we have the ID. We can just make it not to the ID. Just using invited by. And we said the email of the user who invited this other user. Now let's add this one label daughters true or false to see if there was, was created by an invite that will add Boolean label for user credit and buy invite like this. And he had the say this intimate information. Ok, and we see this invariant by is in the place of actions. So we will, we will move, it, will say actions here and we will move this patient stuff. Let's see, work now, okay, now we need to replace the invitations and actions with that places. Ok, so here we have the information about invitations. We see if the user was created by invite. So what else can fiddle? Let's see. Let's go here. And valid invitation. While we can see that the invitation is valid, if it is accepted, let's check if the invitation is accepted. So here we will add Boolean label invitation accepted. Ok. And let's make it just look a bit more understandable. Maybe remove user invited by. And here we will add created by invite. And we will add invitation accepted question. And we'll put this two into two different table lions. Okay, and let's see. So vc of the usable scraped by invite, VC if the invitation was accepted and looks quite nice. So we've added some additional information to our users table to see how the user was created. And that's it. Thank you. 43. 07 03 button to Resend confirmation instructions to unconfirmed users: Okay, so now we can create users by inviting them to the application. They can editorial that can ban uses. We can delete users. And what if we wanted to resend the confirmation manually? So for example, the admin would have a bottom to resend the confirmation if the user did not accept the confirmation. So for example, confirmed falls and here would have a button, resent confirmation vowel. Let's add this functionality. So if you look into the documentation for device confirmable, and we see that there is a command called recent confirmation instructions. And it would return the confirmation token and it would regenerate the token bureau that was expired. So let's add a link to resend the confirmation instructions. Let's add this action to our users controller. So we've looked at death resent, conformation instructions than they would have defined the user. And we would say at user_data received confirmation instructions. Ok. Then let's make this available in our rules. Let's go to routes.rb. And here we are going to patch not only ban, but also received confirmation instructions. So Patch or send confirmation instructions. Okay, and we will add the link in our views. So here we have our users index. And we would say if the user is not confirmed. So here we could add some logic. Unless user confirmed level have linked to resend the confirmation instructions. So unless user adopt confirmed. Now I will put an end statement. And here we will have a link tool equals link to resend the confirmation instructions. And we are going to add a route. So roots, let's see the road that was created. Resend information constructions, user buff, coma or send confirmation instructions, use a path and the method is going to beam, patch. And when to close this. Okay, let's go to our users view. And here we get an error. No wrote measures actually present information instructions. Yes, we need to actually know the user. So user. Okay? And here we have thrilling through some conformation instructions. Now let's try present them. I press the link and did something happen? Let's see. Yeah. So the conformation instructions resent what we then get a notification about this. So let's go to our roots and it will add something like Redirect tool at user. Notice, confirmation instructions, VR. Russ sang. Now let's see if it folks. Okay, so confirmation instructions, vote resent. Looks nice. But two, what if we add some additional logic just in case? So let's imagine we don't at this validation in our views and we have this resonant eat confirmation instructions for all the users. Well, it's kind of wrong. So I just, I guess resend confirmation instructions. All tried to resend the confirmation instructions to a user that is already confirmed. So I press this user and actually nothing happens. And that's correct because variation be able to send the information instructions to use that already confirmed. What we can also add this validation to our controller. So we would add something like unless at user, now, unless at user_data confirmed, then they're going to have these actions. Else. They're going to redirect to the user with an alert. User already confirmed. And and now let's see if it folks, I will go here. I will try to present information instructions to a use that is already confirmed and they get the message that the user is already confirmed. So looks nice. And that's how we added this link to resend conformation instructions to uses the pond. Not confirmed yet. And that's good. Thank you. 44. 07 04 button to Resend invitation to unconfirmed users: Okay, let's try to register in the application as a new user, I will go to sign up and do some kind of email. I signed up, but I'm not going to confirm my account. I am going to just log in as an existing user. So I have locked in and let's see the US that I've just created. Email at email, dot email. And here we have this redundant information instructions available. And what if we at about the not only the recent confirmation instructions, but to resend invitation and will be able to resend the, an invitation onto the uses that evoke rated might invite. And actually, we should logically be able to resend the confirmation instructions the users that von not created by invite. So these are two kind of different strategies for registration. Presenting information should be available only uses that were not created by invite, and vice versa presented invitations should be available on APA uses that for createdBy by invite. So now we're going to add these validations and the bottom. Now, first of all, we are going to go to our users controller and add a method to resend invitation, resent invitation. And here in device invited, we have this method that put resending the patient token and send invitation again. So just use a dot invite. Here we take the user and we would say user dot invite. And we would say invitation vaults, recent. And otherwise, we would say that the user has already been confirmed and we needed some kind of validation. So in what cases can we resend the invitation though? If the user was graded by invite and if he did not confirm his account. So we would say if at USA dot graded by invite and at user dot invitation accepted false. And if the user has not been confirmed yet, at user confirmed. False. Not false. Let's see if this works. In the meantime, let's go to our roots. Can config routes and Advil no method to resend invitation. And it will go to our views. And somewhere here, next door, invitation accepted. They are going to have a link to rescind the invitation. So badly you have invitation accepted care. They're going to have a button or a link to resent invitation. I'm just going to copy that other link. So we'll have linked to resend invitation, resend invitation, user method patch. Okay, and we have about understanding invitation for everybody. So they're going to make it only visible in the cases that they're listed above. If user was created by invite, if invitations are false and if use a confirmed false. So we'll add these validations. If user createdBy invite, and so on. Now an end statement. And let's see, okay. So there is no such method as created by impact. Whether question OK. Let's see. Let's say the available options created by invite Boolean, OK, this should exist. Okay? Yeah, it exists just I pass at user, I shouldn't pass at USA, who should just pass user? And that was my mistake. And we don't have this in the station accepted. We would try to make it like this. Invitation accepted false and user confirmed false. Let's see. Okay, a syntax error while rendering the template. Let's try without these validations. Yeah, without validation and folks. So there must be a problem that my validation. So if the usable scraped Biden Bite, it must be visible. Then if the user did not accept the invitation. And if the user is not confirmed. Yeah, I just made a mistake with the syntax. So if user invitation set it equals false, and if you've confirmed it calls false, okay, let's see. Yeah. So now we have this intention accepted available only for users that for createdBy invite, and that v-nought confirmed. And that did not have that information. So only in the right cases we'll see resent invitation. Now, I'll press for sand invitation. And undefined method in the nation accepted. Okay, because I have the same mistake in the controller. Let's go to the controller and heavy have invitation accepted. Question mark equals false. And here we have user confirmed question mark equals false. Ok. And invitation was reassigned, let's see. Okay, indeed an email voice sand. So we've added a method to resent invitations and the seed only in the right cases, novice should also silicon resent conformation instructions only if the user was not confirmed and he, if he was not created by invite. So opposite logics. Let's go to our users controller. And here we are going to add the additional logic. So we'll say if user confirmed gives false and user dot graded by invite is false. Okay? And we'll add the same logic to our views. So if user confirmed equals false and user adopt, graded by invite equals false. Now let's see, and we see this button tours and a confirmation instructions only in the right place. So information instructions for ascent. And here representing the notation, notation phosphorus. And so we've improved our logic for or send confirmation instructions and the added logic for resending invitations, the uses that credit by invite, but that did not accept that invitation. And that's it. Thank you. 45. 07 05 Authorization for resend confirmation instructions: Okay, so we have added two new buttons to resend the confirmation instructions. And there send an invitation and we need to add some authorization for them. So what kind of users can perform these actions? Though? I would say that only admins and be able to resend confirmation instructions. Because imagine you have an application that from a 100 users and Arab developed descending, aerobic diverse and conformation instructions. We don't need that. And for resending invitation, there would also be some logic lactose. Let's work on resending confirmation instructions. So this will be only for admin and it's really easy to implement. I'll just go to the user's controller. And here in Require Admin, we're also just going to add this method to present information instructions. And now I'm logged in as an admin. I will look out. I will log in as a non admin user. I'll try to received confirmation instructions and you see I cannot. Now i will also move this link to the actions. So I'll sign out, sign back in as an admin, go to users, and let's go to use this index. I will remove this link from here and move it to the actions like this. And we can also denote it in some kind of bottom if we would like to honor. So something like this class button, button, secondary, for example, and have her Button to recent confirmation instructions in their actions. Pollack. Ok. And basically that's it for this video. So we just added some authorization for syn conformation instructions. And next we're going to do some authorization logic for sending an invitation and the flow is going to be different. So thank you. 46. 07 06 Authorization for resend invitation: Okay, and now we're going to add the authorization for sending an invitation. Now can resend an invitation. I would say either an admin or a user that actually invited another user. So for example, this user would be able to rescind the invitation to this user. Now you see, in this case we don't have an invited by, right here. Goes the created this particular user via our console. So that's why there is no invited by. Okay, so let's add this authorization. Let's go to our users controller. And here I actually have to add a new before action. If B before action Require Admin all invited and will be only for resend invitation. And let's create this method. Def Require Admin O invited. And he will say, I have the admin all user dot invited by equals current user. Now let's check if this would work. So he ever sang either the admin or the invited. So the user dot invited by equals the current user. And let's see if it works in our views. First of all, let's start the server now. And let's have a look at our users. Let's try to send an invitation. Well, it folks, because our current user is an admin, what if I tried to sign out and log in as a user that is not an admin. I go to users, try to resend an invitation. Ok? I get this undefined local variable or method user. Yeah, it shouldn't be at user o, O, K. Let's see, undefined method invited by four Nil class. So we didn't manage to get this at user. Let's go back and see what the problem can be. So invited by funnel class. Now, it looks like if I don't have this user defined. So we are using this before action before actually going into our method to recent invitation. So we don't have this at user. So I'm going to have to add at user to this, require admin or invited like this. And let's see. So I'm trying to invite, I cannot, I'm trying to invite another user. I cannot. I will look in as the user that actually invited these users. Now I'm signed in Outlook in okay, can't look in. I'll try to press for what could be possible that I will reset my password. Now, I'm going to users, I'll try to rescind the invitation here. It was resent. I'll try to send the invitation here and I'm not authorized. So it works correctly. That authorization validation evokes correctly. And now they're just going to make it the links visible only to the users that can actually perform this action. So I'm going to go into our index view and we're going to add this kind of validation in the index view. So they're going to have two layers of validation. Go show this link. The First Lady is going to be unless current user admin or user invited by equals current user. And second layer of validation is what we added previously. Now I refresh and I, and something's wrong. So I see invitation onto the use to which I shouldn't be able to present the invitation. So it shouldn't be not unless bought. If yeah, that's minus steak. Ok. Now try to send invitation and it's well, can. Now I'll try to login as an admin once again. So we're going out than login in Github users. And here I see this link to resend the confirmation instructions. All of them because I'm an admin. So I'll just move these links into the actions right here. Separately from if current user is admin because here there is an additional second validation. And that's it. We've added the custom validation for inviting for sending an invitation for all the other actions we had Require Admin and haven't had require either admin or inviting. And importantly, the head to add the user equals user find by params ID in this Require Admin or inverter because the before action is called Before the start. This metadata. So that's it. And thank you. 47. 08 01 gem invisible captcha no bot sign ups: Now, vans running an application in production, you can expect a lot of BAD sign ups. So you'll have a lot of users and that actually until users that never confirmed by emails. And they'll be just spending your database. And to decrease the quantity of sign-ups, you usually can use recapture. Now, there was Google recapture, you must know it. So this recaptured to press a button and approved cannot abort. And there are two options in Ruby On Rails. The first option is to install Google recapture, and the second actually easier option, in my opinion, is to install the gem named invisible recapture. So it is a free alternative to Google recapture, and it's totally Ruby on Rails. So let's try to install this jam and see how it works. So have a good this jama invisible recapture. I'm going to add it to our gem file. I'm stubborn server. Here's our gem file and not the run bundle. And next last thing. So Van, Do we want to use this invisible or capture? Wow, we won't use it. Funds. We are registering a new user. So I am trying to sign up. And at this point I will have this invisible recapture take place. So how do we install it? Well, first of all, we're going to understand that this is our device controller and it is devised registrations controller. So they're going to edit our device registrations controller. And for this, we would need to add a new controller to have a device registrations. Now that have device conformations, they have OmniAuth callbacks controller and we are going to default controller device registrations. And all they can do it by stopping the server and run the command. Rails generate, devise controllers, uses conformations and registrations. Yeah, and what falls down? So this registrations controller was created. And what our vesicles some many Old setup to add, set, to add this controller in our routes. So let's go to our config routes. And here we are going to say registrations. Users slash registrations open into the coma here. Like this. So I have three device controllers that we have edited, confirmations, OmniAuth callbacks and registrations. Okay. And watched through the du here. They're going to add for action. So here are examples of before actions, and they are going to add a before action to use invisible or capture. So here again in the blog, I have a short article Hinden and how to do it correctly. And in this registrations controller, we are going to add this kind of before action, invisible capture only create. Ok. And two, next, we're just going to add this invisible capture tag in our form, in our view. In views, device registrations, New. And here Next, Device error messages. We're going to add this invisible recapture. Now how can we check if it works? Let's start our server. Let's try to sign up and go to sign up. And you see Thoreau that was too quick. Please resubmit. This time revoked. Now, I am trying to sign in and basically it folks, but when I press sign up, and this is already the action done by invisible recaption controller. So sort of that was too quick. Please resubmit. This is one of the errors provided by this controller. So here we can see this error message actually taken place in the written me. And this is the easiest way to install this gem. So van, the general detecting suspicious activity, it will be given some kind of a Arrows and kind of phonons, and it will not lead users sign up both accounts. Actually, not used, but just WhatsApp, both accounts to sign up. So once again, how does this jump Vogue and how did we install? We added it to the jump file than we've added that registrations controller in users registrations. Roller listed this registrations controller in our routes. And we've added this invisible capture in our form. And the hardest developing, basically a very direct me of this gem. It says that this is a field that is invisible to real users and they'll be left empty by real users, but most likely it will be filled by span box. So it's a simple principle on how this invisible workup. She jumped rocks, and that's it. Thank you. 48. 08 02 sending emails in production with Amazon SES: Okay, so here I have our application, open introduction on Heroku charities. And what if I tried to log in and oh my I forgot my possible. So let's go to press for what your possible. I will add my email address and crust sand mirrors at possible instructions and I got an error. What kind of error is this? Let's go back and press Control L. Now, Heroku logs, fail to see that logs of Heroku and see what exactly the problem. Let's see. Okay, here it is. Action view template error, missing hosts to link two. So missing host link_to is basically don't ask dot v do not have sending emails introduction configured yet. So we need TO basically say how they're going to send emails and through what provider. So we'll do this. We'll go to our config. Lets go to config. And we have our environments. And here we have dove and production and task for software development. The have Action, Mailer, default, oral options, sat for the house that we have in development. You might have it as localhost like this. And in production we also need to configure fan-in emails. Now, they're going to send emails using Amazon S3. So to configure standing, not Amazon S3, but Amazon says amazon simple email service. So they're going to configure it in our Amazon account. I've looked into AWS and I'm going to services. And here in services, I'm going down to, let's see, to customer engagement and customer engagement. I see the simple email service. So I've logged in. And basically this is the interface for configuring, sending and receiving emails. Now here, I've already added my domain, but you don't have to do it. Tried to vey Then I vote. Also verified an email address that I have for this domain. You don't have to do it right now. Iota. Right now what we need to do is go to SMTP settings. And in SMTP sessions, they're going to create my SMTP credentials. So scraped my SMTP credentials. Now you leave this as it is and press grade. And here it created and SMTP username and SMTP possible. So there's a kind of API keys that they're going to use to send emails using the AWS. Now need to add these API keys somewhere. So actually on my blog, I have a short memo on sending emails in production. So we are going to go BIM in this code into our reduction dot-dot-dot and go through it. So. Here we have config, Action Mailer default options, and have a goal to have the host. So the, basically the website of our application is going to be RubyGems bootcamp, Here I'm adding this host. Then Action Mailer performed delivers, true, raised deliver errors, true labor method, SMTP. And Kara, our action mailer SMTP set and saw the settings for Amazon for sending emails using Amazon. Now here I have this address, email SMTP, use central been Amazon, AWS com vetted. I get this. I am going here and let me save this SMTP username and possible in the meantime. So I'm going to copy this SMTP username and paste it here. And the passport I'm also coping and based on it here. Now, I'm going to press clothes. So I've already saved the credentials, non closing them. And I will go to that services. I'm going to once again, though, because the main gave human simple email service. And somewhere here, I should have yes, the server name. So I need to cope with the server name. And this is where I'm getting this address. So Gobi, this server name here. So when you just look into Amazon simple email service, you go to SMTP settings and you have this seven Name. It is about you copy and paste here, and that's it. So basically we just great API keys in Amazon simple email service. They add this code that we need for sending emails in production. We updated our production oral. And at this address, you might have it not essential but the US East one or US vast fun. You add your username so they're like client ID and client secret. And that's it. Let's see if this Folks, I am going to open a new terminal. B, RubyGems bootcamp, git status, git, add all git commit, monster sending emails in production with Amazon. Simple email service, press git push. And we will push to Heroku. So git push heroku main. And now I'll pause the video and come back from the manage to finally push to Heroku. Okay, so I have finished pushing to Heroku as usual to couple of minutes. And let's go back. Okay, have this error page and I will just refresh the page. So I will resend the request. I press resend. And let's see if it folks, I got this. You'll receive an email with instructions on how to reset your password in a few minutes. And do. I'm going to my Gmail inbox and you see right now 11091109, I get this reset password instructions. So I'll go to change my fold. Okay? Okay. Change my password and success. I managed to walk in. And if I go to the simple email service management console, I'll go to a sentence statistics. And it's loading, okay, and it'll look in once again. Okay. Let's go back. I don't know what the says. Okay. They're going to services. Yes, here we have already recently visited simple email servers sending statistics and have this two messages sent. One message I sent previously before this lecture, and one message was sent just now. So by default you have 50 thousand the emails per month. And that's basically it, definitely enough for any of your needs. And that's basically it. So by just going into production, are being added these lines and add in our API keys generated by simple email service. We managed to configure sending emails in production. And currently I really recommend using Amazon simple email service for sending emails because server previously myself, I used a service called Send grid for around six years and well, it became harder to use it and the quotas for sending emails less than 10 thousand per month. And on simple email service, it's actually faster to configure and they're a bigger quotas. So I really recommend it. And here in the blog poster of eighth of February 2021, you'll be able to also see the spot and the links of the lines that you need to add to your production RB to configure sending emails in production. And that's it. Thank you. 49. 08 03 gem exception notification receive emails if errors in production: Ok, so previously we had such an error in production. They are sorry, but something went wrong. And how do we track errors in production? So let's imagine that we've got a real application and users are using it. And at some point they have some kind of era. Well, now we're going to install the gem exception notification so that you'll be able to get emails whenever a user encounters an error, a code-based era in production. So let's try to install the gem and see how it works. You have to have this gem exception notification. And I'm going to add this to our gem file. Now they are going to use only in production. So we are going to say group reduction, Dong jam exception notification. And now I stop the server type bundle. And we see that the jumbles loaded. Now we need to add this line to production dot RB. So they're going to production dot RB. And here we are going to add these lines. So Rails application, middleware, exception notification, email. Now they're going to deliver this email. Now we don't need to at this commented line than email products, okay, send the address. It's just from which you're going to receive error messages. So let's say up arrow. Hello at the core,, or you can put your address here. And exceptions recipients is the email address to visual areas are going to be delivered so your email address. Okay, we've configured it and now let's see how this jumbled Voc in real life. So let's type git status. Let's load this jump to Heruko ME first. Okay, once can get out, they'll save our changes, get Comment, master, gem, exception, an old defecation for Ketchum, arrows in production. Okay? And let's actually create a real arrow so it can't be stopped. Our production environment, we get some kind of arrow. Let's first create this era in development. So here on the London page you'll have some kind of mistake. Let's go to views. Here we have layouts, coaxial, ecstatic pages, landing page, and let's add some kind of mistake. So let's have something like that's just an unclosed gold or whatever. So they're going to have the error undefined local variable method, something. Yeah, let's have session around. So Dustin infection notification, that add-ins rubric vote so and the side door display something that doesn't exist. So Van v, OK. Now application in production, we will have such a screen that something went wrong. And we expect to get an email, whether the information that the devil such an error. Ok, let's commit these changes on Git status. Git, add all git commit, Maine, Dustin, arrows in production. And now I'll push to Heroku and see if I have this era and see if I receive an email, git push heroku master. So now I'll pause. O shall not bergamot, but about Heroku domain, I will pause the video and come back from their push to Heroku. Okay, So we have pushed to Heroku, and let's navigate to our Heroku app. And we have this error. Now, if they go to some kind of other page, like users sign in, we don't have this error because we are not on the homepage. But when they go to the homepage, they've got this era. And let's go to our email. And a1 C V received an email from exception notification. Okay. And heavy, SIR, at era, I will open it and I see the era state-based London page and define local variable or method exception notification. So it is on static pages controller action London page. And it is on line 36. So we go to line 36 and charities. So this way, we'll be able to receive and track all the errors real users have in production and see ways to mitigate these arrows. And that's it. Thank you. 50. 08 04 rename app from ruby gems bootcamp to superauth: Okay, so now via mainly finished on working on our application. And lastly, we're going to rename the application. So at the moment we have no name here, they just have their own brand. And here we have the address RubyGems bootcamp, Heroku app. And we'll just give it a better name. So let's go to the console and care. They're going to type Heruko renamed super, super authentication, super authorization, whatever. Now if we look at our dashboard, we can also see this application here, RubyGems bootcamp. So I will type Heruko renamed super old, and I see that it was renamed. So the application will be available at this new link. I will open this new link. And here's the same application. I go to the old link and it's not available anymore in Heroku dashboard. I'm also going to refresh. And here I see this application super old. So looks nice. Now let's rename the application in other places in our app. So let's go file by file. Let's go to config. And in conflict, we have application.rb. Here we will rename it to super. Next we are going to go to our development are being, maybe here we have the name of the application. No, it looks like they do not. They are going to production dot RB. And here it is going to be super alt dot Then send the address can also be him. Super off arrow, select No, for which application we have this error. Now I believe that address also Heroku at And let's go to our initializers, devise RB. And here we also must have that name somewhere. I'm going up here. Okay. Have have have the smell asunder. Yeah, I'm going to live it the same, but you can also change it based on your application name. And let's now go to our views and go to app views, layouts and an application HTML, we have this name of the application. So I'm going to update it to super owls. And I refresh here. And oh, actually, I'm doing in the development, in the environment, so I see no changes. I'm going to refresh the page here. Now I need to start the server. And here I see the world superpower. Now I'm going to also add it in the header right here. So I'm going to application to the header actually. And here I will add develops, you buy out. Okay? I can make it from a small lateral. Doesn't matter much. And I will just change the favicon. I'll go to Font, Awesome icons. And let's find an icon. Something, maybe that authentication, maybe look in whatever. So for example, it can make its sign in old or maybe a lock. User lock. Let it be so FAA user lock. Okay. And it looks like that's it. So I've renamed application in the header, in the navbar, I have renamed application. In the application HTML got HMO. I've renamed it if needed in device and development RB in application or being right here. And in production dot RB for sending emails from the new Heruko address. And that's it. Now we have a better name for our application. Thank you. Yes. And coming back to this topic, actually some places we'd not to name, so we did not rename their database and development, test and production. But you should be careful with this because if you rename that database in production, then you can have some issues with the bushing to Heroku and also not rename our repository on GitHub. So if I go to GitHub because siegel, Yeah, I have this RubyGems bootcamp and I'm also going to rename it to super hours. So I would go to sudden. And here, yeah, here on the top I can rename the application. And that's it. Thank you. 51. 09 01 user name can be edited: Okay, and what if we want to add some additional functionality like letting users added the personal data, for example, their name. So a user would be able to go to an edit form and edit his name. Now, the moment that edit form is been used for editing roles, now I'm not authorized the poem's action from this account. Okay, let's yeah, let's actually add an admin role to the current account. I'm going to come so Rails console, user_data first dot update, Admin, true, exit Rail server. Ok, so now I can navigate the editorials and yes, you say I'm going to use a slush fund slash edit and I can edit trolls. Now the easiest way to let us edit a user's name would be to go to this form. Let's go to this form. I'm going to use the edit form. And here would also add the a field for editing the user name. So it will be f dot text field. And in this text field, I guess we would have a name, let's say with folks. Yes, and have the username. Now we see it is on the same line, so we should add some kind of break here. Yeah, so we can edit the username and visual, maybe also at a label. So it's b, f label, I guess I've topped the label name. So here we have a tiny form for editing the user's name. Let's try to edit it. I will just make it Yaro and press submit. And what changes? Name did not change, but didn't name change. Because if I go to the console, you have an unpermitted perimeter name in the update action. So what kind of unpermitted perimeter is it? Well, here, whenever we press update for as the update action, we update according to the user parameters and in the user params, now we have only the roles. We are allowed to update all of the user roles, not the name. So we can also bite list the username. And try once again. So I go to Edit trolls. I'll make it just Yaro submit. And now I managed to edit the user's name. Looks fine. Now let's look into the social account once again. So I will begin with this email address with my GitHub account. I'm going to look in signing the bill GitHub. I signed in and you see my name was updated once again from GitHub. So each time I look at it with the GitHub, it overrides My name. And we don't want to do it. We want to make it so that the if the name over there exists, then we don't override the associate account for the social login. So to make it so we will go to our controller's users OmniAuth callbacks controller. And here we have this action user dot from OmniAuth where actually the user data is updated. So this user dot from OmniAuth is in the users know though. So both modals user RB and have a say. So username equals the social provider dot name. And we'll make it so that unless username is present, then we will pool that name from the social provider. So we will say unless user Doppler named present, then they're going to update the name. And we have, and let's see if this works. I will change the name once again. So it'll be Yaro two. Now, I will look out and once again look into the social provider. And you see the name was not updated. But if I log in from another account and then name should be o from the social provider. So here it is both from the social provider and this way we can add it the user name. But at the moment on the admin can edit the username. And next we're going to work on it, the functionality so that the user can edit his own name, but not able to edit its roles. And only the admin of able to edit the roles. So that's it. Thank you. 52. 09 02 strong params only admin can edit roles, any user can edit names: Now in this form, the edit trolls like an actual written, not only editorials, can also add the, for example, the name. So let's just rename this edit trolls to just edit. So we're going to be able to edit the user profile. Let's go to the index page and I'm going to rename editorials to edit. And the same in the show page. So now we just have to edit the user name and the roles. And at the moment, only the admin can edit the name and the roles. But what if we want to make it so that a user himself can edit ONE name. So let's add this functionality. Now I will log in as simple user, log in as the simple user. That is not an admin. And he will be able to edit his own name, only name, not not Charles. So I go to Edit and yelled, authorized a performance action. Now they have to make this edit page available for non admin users. So I'm going to die uses controller. And here we have a required element for edit and update. So they're not going to require admin for edit and update. And let's refresh and open this edit page. Okay, now I can go to the edit page of myself and of another user. Let me try to edit the CRO to, I'll make it yellow three, I'm going to edit an admin user I managed. And I can also add it myself. So I can edit the name and I can edit the roles. I can make myself and Admin. Now. I've just destroyed their authorization functionality. And so any user can edit the roles and names of any other user. And this is definitely at security devastation, a real devastating security problem. So they're going to make it so that the users will not be able to edit trolls, but there will be only able to edit the name for the beginning. Now, I found a perfect solution on Stack Overflow. So here is a way to condition a li, a different user params. So for example, make it so that only the admins will be able to edit the user roles, but anybody will be able to edit the username. Let's make it so for the beginning. So you have I going to say least allowed params. And the allowed params fanout will be just the name. And conditionally, they're going to add the user roles to allow params if the current user is an admin. So for those Stack Overflow, say here, least allowed params plus equals rho or user roles. So list allowed brands plus equals. And here they are going to add the User roles that the condition if current user dot admin. And here in parentheses require user, they're going to say List allowed params like this. So basically we are going to make the name editable by anybody who is not an admin. And user_roles only will be updated if the current user is an admin. Now let's try and see if it's barracks. So the current user is an admin. Let's make him not an admin. Not an admin anymore. Ok. And now I'll try to make him a student. And you see, I didn't manage to make him a student. I'll try to make him an element and the student, and I didn't manage by. Because I go here and I see unpermitted parameters. Admin, teacher and student induces controller 15 update. So non admin user cannot update that user perimeters, that our user roles. You cannot update the user to be admin, teacher, or student. Okay, it looks nice. Let's try and log of. Let's try and edit the name. Will be able to edit the name. Yes, I managed to edit the name. I'll try to edit the name of another user. Let's make it fall. And it works. I'll try to edit the other users roles. And no, I cannot add a dollar uses roles. Now, I will log in as an admin of answer cattle and tried to edit our users roles. So I will try to make myself also a teacher. And it felt so with this update to some parameters for making it so that anybody can edit it uses name but only an admin, edit the users roles. And actually let's also displayed in our edit views. So here, these three buttons will be visible only to admin users. Civil go to Edit. And here we will say if current user is an admin. If current user admin, then they are going to display a form to edit the user roles. Okay, now via an admin, we can see this form. We go to another user. We can also sit as form, that's login as an admin user. I go to Edit and I have no way of actually seem modern store, update the user roles. And even if I did, I wouldn't be able to update them because we've updated our strong params. So at the moment, any user can update any user's name. But on the admins can edit other users roles. And that's it for this lesson. 53. 09 03 strong params authorization user can edit his own profile: Okay, so now anybody can edit a user's name and an admin can edit users roles. But what if we want to make it so that only the owner, so only the user himself can edit his name and the admin can edit the, anybody else's roles. So you will be able to edit only your name. And nobody else will be able to edit your name. But admin can edit anybody's roles, though. It'll just update this list of allowed params, startling. So we will say least allowed brands, blas and kept. We will have the name if the current user is that user that is been edited and by default, level be nothing. So if it's not an admin and it's not the owner of the struggled. None there will be no allowed params. So let's see what the folks now have our server running. Yes. And let's see and look in as an admin. And I will try to edit the, my name. Let's make it grow seven. And it works. Now I will edit my roles, I will add the role teacher, it folks. I'll go to another user and added his name. I'll make it seven. And you see I could not update his name because I said that only the owner of the record can update the name. So we can add an additional validation. Either owner or admin can edit the name. Let's try once again. Let's make it seven. And it works. So this way we can add the additional validation for strong parameters just as we like. And we can say that some fields can be added by one kind of user sample can be added by another kind of user. Now let's log in as the other user, logan in. So I can try to edit my name. Let's make it eight. It works. Can I added another user's name? I'll go to press eight. No, it does not fail. But I still see the form to edit and other user, though I cannot actual edit edit m. So now we'll remove the possibility to add it to the bottom or to go to the page of editing and other user. If you cannot actually do it, let's go to our users controller and add the additional validation. So either admin or record owner will be able to edit and update. Before action. Require Admin. All owner only for edit and update. And let's add this before action. So in our private params here it will be require admin or owner again via, say, use a find by params ID. And though then they're going to redirect in some condition. And let's write the condition. So if it is the admin or if it is the record owner, then we'll be able to go to the edit update. So unless now, unless current user_data admin or at user o, current user equals at user. So the user that it's been edited. So unless current user is admin or current user equals at user. Now let's see if it folks. So it is for edit and update. I will go to edit my page. I can't do it. I can update it. Let's make it nine. I go to another users edit page and you are not authorized to perform this action. So works. You have added one more before action that helps us with our authorization for edit and update actions so I can edit my page. I cannot add it another user's page. If I'm a regular user, but an admin can edit the roles and the name of any user. So That's it. Thank you. 54. 10 01 user can not ban himself: Okay, so now I'm logged in. There are no band uses and what if I tried to ban this user? Yeah, you're not authorized to perform this action because let's see why. Let's go to our users controller. I cannot bend this user because I'm not an admin. So I cannot use it because I'm not an admin either. Log in as an admin. Go to home. I press bam, okay, I bend this user. And what if I banned myself? Yeah, it's actually possible to ban yourself. And in my opinion, it's not correct. So at the moment there are no admin users that are not banned in applications. So applications kind of program. So let's make it told that an admin user cannot ban himself. Toast. Let's unbent ourselves. Let's go to the console, rails console. Let's find US adult first. And it's this user on. And let's change the band status. So I will say your various, Our band user_data unlock access. So user first unlock access. Ok, I will try to log in now exit rails server. I'm logged in. So I'm not banned. And now I will add some additional validation. So I will say if that user is current user, then they're going to get an error. So if a user is current user re-direct to user alert, you cannot ban yourself. Not banned yourself. Otherwise. They're going to have that regular logic. So it's just an additional layer of defense for our application so that the user doesn't Bell himself. You see, you cannot ban yourself, but I can ban or on ban another user. So looks nice. That's it. Thank you.