# Grav Login Plugin The **login plugin** for [Grav](http://github.com/getgrav/grav) adds login, basic ACL, and session wide messages to Grav. It is designed to provide a way to secure front-end and admin content throughout Grav. # Installation The **login** plugin actually requires the help of the **email** and **form** plugins. The **email** plugin is needed to ensure that you can recover a password via email if required. The **form** plugin is used to generate the forms required. These are available via GPM, and because the plugin has dependencies you just need to proceed and install the login plugin, and agree when prompted to install the others: ``` $ bin/gpm install login ``` # Changes in version 3.2 New events: * `onUserLoginAuthorized` Allows plugins to include their own logic when user gets authorized (usually after 2FA challenge). # Changes in version 3.1 New events: * `onUserActivated` Allows plugins to hook into user activation, when user has clicked on confirmation email. # Changes in version 2.6 * User registration is now disabled by default. If you were relying on it being activated, you need to manually enable it in your `user/config/plugins/login.yaml`: ``` user_registration: enabled: true ``` * `login_after_registration` has also been changed to a default value of `false` for security purposes. # Changes in version 2.5 Added new `$grav['login']->login()` and `$grav['login']->logout()` functions for you to use. They use following events which can be hooked by plugins: * `onUserLoginAuthenticate` Allows plugins to include their own authentication methods. * `onUserLoginAuthorize` Allows plugins to block user from being logged in. * `onUserLoginFailure` Allows plugins to include their own logic when user authentication failed. * `onUserLogin` Allows plugins to include their own logic when user logs in. * `onUserLogout` Allows plugins to include their own logic when user logs out. * `onUserLoginRegisterData` Allows plugins to include their own data to be added to the user object during registration. * `onUserLoginRegistered` Allows plugins to hook into user registration just before the redirect. All the events use `UserLoginEvent` with some useful methods to see what is going on. New Plugin options have been added for: * `dynamic_page_visibility` - Integrate access into page visibility so things can be shown or hidden in the menu # Changes in version 2.0 * OAuth has been separated to its own plugin, needs to be installed separately and configured. The users account filename format has changed too, to fix an issue that involved people with the same name on a service. * The `redirect` option has been changed to `redirect_after_login`. * The Remember Me session minimum length is now 1 week. * Removed the option to login from oauth without creating the corresponding user file under `user/accounts/`. # Messages Output There is not a guaranteed way to display system messages including those added by the Login plugin, so in order to see messages you will need to make sure your theme has a method to output the messages. This is done by adding a simple Twig include, and the best place to do this to ensure it's visible in all your pages, is to add it to the `partials/base.html.twig` (or whatever your base Twig template is called): ```twig {% block messages %} {% include 'partials/messages.html.twig' ignore missing %} {% endblock %} ``` A good location is probably to add this right above where your content is going to be output. # Creating Users You can either use the built-in CLI capabilities, or you create a user manually by creating a new YAML file in your `user/accounts` folder. # CLI Usage The simplest way to create a new user is to simply run the `bin/plugin login new-user` command. This will take you through a few questions to gather information with which to create your user. You can also use inline arguments to avoid the interactive questions. ### Commands | Command | Arguments | Explination | |---------------|--------------------------------------|----------------------------| |`new-user`||Creates a new user (creates file in `user/accounts/`) || [ -u, --user=USER ] | The username. | || [ -p, --password=PASSWORD ] | The password. Ensure the password respects Grav's password policy. **Note that this option is not recommended because the password will be visible by users listing the processes.** | || [ -e, --email=EMAIL ] | The user email address. | || [ -P, --permissions=PERMISSIONS ] | The user permissions. It can be either `a` for Admin access only, `s` for Site access only and `b` for both Admin and Site access. | || [ -N, --fullname=FULLNAME ] | The user full name | || [ -t, --title=TITLE ] | The title of the user. Usually used as a subtext. Example: Admin, Collaborator, Developer | || [ -s, --state=STATE ] | The state of the account. Either `enabled` (default) or `disabled` | ||| |`change-pass`||Changes password of the specified user (User file must exist) || [ -u, --user=USER ] | The username. | || [ -p, --password=PASSWORD ] | The new password. Ensure the password respects Grav's password policy. **Note that this option is not recommended because the password will be visible by users listing the processes.** | ### CLI Example ``` > bin/plugin login new-user -u joeuser -p 8c9sRCeBExAiwk -e joeuser@grav.org -P b -N "Joe User" -t "Site Administrator" Creating new user Success! User joeuser created. ``` ### Interactive Example ``` > bin/plugin login new-user Creating new user Enter a username: joeuser Enter a password: 8c9sRCeBExAiwk Enter an email: joeuser@grav.org Please choose a set of permissions: [a] admin access [s] site access [b] admin and site access > b Enter a fullname: Joe User Enter a title: Site Administrator Please choose the state for the account: [enabled ] Enabled [disabled] Disabled > enabled Success! User joeuser created. ``` ### Manual User Creation Here is example user defined in `user/accounts/admin.yaml`: ``` password: password email: youremail@mail.com fullname: Johnny Appleseed title: Site Administrator access: admin: login: true super: true ``` >> Note: the username is based on the name of the YAML file. # Default Configuration ```yaml enabled: true # Enable the plugin built_in_css: true # Use built-in CSS redirect_to_login: false # If you try to access a page you don't have access to, should you redirect to login route redirect_after_login: true # Path to redirect to after a successful login redirect_after_logout: true # Path to redirect to after a successful logout route: '/login' # Specific route for Login page (default is '/login') route_after_login: # Route to go to after login if enabled route_after_logout: # Route to logout to if enabled route_activate: '/activate_user' # Route for the user activation process route_forgot: '/forgot_password' # Route for the forgot password process route_reset: '/reset_password' # Route for the reset password process route_profile: '/user_profile' # Route for the user profile page route_register: '/user_register' # Route for the user registration page route_unauthorized: '/user_unauthorized' # Route for a page to display if user is unauthorized twofa_enabled: false # Two factor authentication enabled dynamic_page_visibility: false # Integrate access into page visibility so things can be shown or hidden in the menu parent_acl: false # Look to parent `access` rules for access requirements protect_protected_page_media: false # Take `access` rules into account when directly accessing a page's media site_host: # Optionally used in password reset and activation emails, to avoid "password poisoning attacks", this should be the URL of your site including the protocol. e.g. https://foo.com rememberme: enabled: true # Enable 'remember me' functionality timeout: 604800 # Timeout in seconds. Defaults to 1 week name: grav-rememberme # Name prefix of the session cookie max_pw_resets_count: 2 # Number of password resets in a specific time frame (0 = unlimited) max_pw_resets_interval: 60 # Time in minutes to track password resets max_login_count: 5 # Number of failed login attempts in a specific time frame (0 = unlimited) max_login_interval: 10 # Time in minutes to track login attempts ipv6_subnet_size: 64 # Size of IPv6 block to track login attempts user_registration: enabled: false # Enable User Registration Process fields: # List of fields to validate and store during user registration - 'username' # This should match up with your registration form definition - 'password' - 'email' - 'fullname' - 'title' - 'level' - 'twofa_enabled' default_values: # Any default values for fields you would like to set level: Newbie # Here the 'level' field will be pre-populated with 'Newbie' text access: # Default access to set for users created during registration site: login: 'true' redirect_after_registration: '' # Route to redirect to after registration redirect_after_activation: '' # Route to redirect to after activation options: validate_password1_and_password2: true # Ensure that password1 and password2 match during registration (allows you to have just 1 pw field or 2) set_user_disabled: false # Set this `true` if you want a user to activate their account via email login_after_registration: false # Automatically login after registration send_activation_email: false # Send an email that requires a special link to be clicked in order to activate the account manually_enable: false # When using activation email, don't enable until an admin does it manually send_notification_email: false # Send an email to the site administrator to indicate a user has registered send_welcome_email: false # Send a welcome email to the user (probably should not be used with `send_activation_email` ``` # Usage You can add ACL to any page by typing something like below into the page header: ``` access: site.login: true admin.login: true ``` Users who have any of the listed ACL roles enabled will have access to the page. Others will be forwarded to login screen. Because the admin user contains an `admin.login: true` reference he will be able to login to the secured page because that is one of the conditions defined in the page header. You are free to create any specific set of ACL rules you like. Your user account must simply contain those same rules if you wish the user to have access. ## Create Private Areas Enabling the setting "Use parent access rules" (`parent_acl` in login.yaml) allows you to create private areas where you set the access level on the parent page, and all the subpages inherit that requirement. # Login Page >> Note: the **frontend site** and **admin plugin** use different sessions so you need to explicitly provide a login on the frontend. The login plugin can **automatically generate** a login page for you when you try to access a page that your user (or guest account) does not have access to. Alternatively, you can also provide a specific login route if you wish to forward users to a specific login page. To do this you need to create a copy of the `login.yaml` from the plugin in your `user/config/plugins` folder and provide a specific route (or just edit the plugin settings in the admin plugin). ``` route: /user-login ``` You would then need to provide a suitable login form, probably based on the one that is provided with the plugin. ## Redirection after Login By default Grav will redirect to the prior page visited before entering the login process. Any page is fair game unless you manually set: ``` login_redirect_here: false ``` In the page's header. If you set this value to `false`, this page will not be a valid redirect page, and the page visited prior to this page will be considered. You can override this default behavior by forcing a standard location by specifying an explicit option in your Login configuration YAML: ``` redirect_after_login: '/profile' ``` This will always take you to the `/profile` route after a successful login. # Logout The login plugin comes with a simple Twig partial to provide a logout link (`login-status.html.twig`). You will need to include it in your theme however. An example of this can be found in the Antimatter theme's `partials/navigation.html.twig` file: ``` {% if config.plugins.login.enabled and grav.user.username %}