How to Add and Remove Users in Grav CMS | OpsBlu Docs

How to Add and Remove Users in Grav CMS

Step-by-step guide to Grav user management. Create accounts via Admin Panel, CLI commands, or direct YAML editing.

Comprehensive guide to managing user accounts in Grav CMS through the Admin Panel, command line, and direct file manipulation.

Adding Users via Admin Panel

Method 1: Create User in Admin

  1. Navigate to Users

    • Log into Grav Admin at /admin
    • Click Accounts in sidebar
  2. Add New User

    • Click + Add button
    • Fill in user details:
      • Username - Required, unique identifier
      • Email Address - Required
      • Password - Set secure password
      • Full Name - Optional display name
      • Title - Optional job title/role
    • Select Access Levels:
      • Admin Login - Allow admin access
      • Admin Super - Full admin privileges
      • Site Login - Frontend login access
  3. Assign Permissions

    • Check specific permissions:
      • Admin Panel access
      • Page management
      • Plugin management
      • Theme management
      • User management
    • Click Save

Method 2: User Registration (Frontend)

Enable frontend user registration:

# user/config/plugins/login.yaml
enabled: true
built_in_css: true
route: /login
redirect_after_login: /
parent_acl: false

# Enable user registration
user_registration:
  enabled: true
  fields: ['username', 'password', 'email', 'fullname', 'title', 'level']
  default_values:
    level: Registered
  access:
    site:
      login: true
  redirect_after_registration: '/welcome'
  options:
    validate_password1_and_password2: true
    set_user_disabled: false
    login_after_registration: true

Registration form appears at /login with registration tab.

Adding Users via CLI

Create User with Grav CLI

# Interactive user creation
bin/plugin login newuser

# Follow prompts:
# - Enter username
# - Enter password
# - Enter email
# - Enter fullname
# - Enter title
# - Enter permissions

Script for Bulk User Creation

#!/bin/bash
# create-users.sh

# Create multiple users from CSV
while IFS=, read -r username email fullname
do
    bin/plugin login newuser \
        --user="$username" \
        --password="ChangeMe123" \
        --email="$email" \
        --fullname="$fullname" \
        --permissions="site.login" \
        --state="enabled"
done < users.csv
# users.csv
john_doe,john@example.com,John Doe
jane_smith,jane@example.com,Jane Smith
bob_johnson,bob@example.com,Bob Johnson

Adding Users Manually (YAML Files)

Create User Account File

# user/accounts/johndoe.yaml

state: enabled
email: johndoe@example.com
fullname: John Doe
title: Content Editor
access:
  admin:
    login: true
    super: false
  site:
    login: true
hashed_password: $2y$10$XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Generate Password Hash

# Generate bcrypt password hash
php -r "echo password_hash('YourPassword', PASSWORD_BCRYPT);"

# Or use Grav CLI
bin/plugin login newuser --user=temp --password=YourPassword
# Copy hash from user/accounts/temp.yaml
# Delete temp user

Set User Permissions

# user/accounts/johndoe.yaml

access:
  admin:
    login: true    # Can access /admin
    super: false   # Not a super admin
    pages: true    # Can manage pages
    plugins: false # Cannot manage plugins
    themes: false  # Cannot manage themes
    users: false   # Cannot manage users
  site:
    login: true    # Can login to frontend

User Groups

Create User Group

# user/accounts/groups.yaml

editors:
  readableName: Content Editors
  description: Users who can edit content
  icon: fa-pencil
  access:
    admin:
      login: true
      pages: true
    site:
      login: true

Assign User to Group

# user/accounts/johndoe.yaml

groups:
  - editors

# Inherits group permissions plus individual access settings
access:
  admin:
    login: true
  site:
    login: true

Adding Admin Users

Create Super Admin

# Via CLI - creates admin with full permissions
bin/plugin login newuser \
    --user=admin \
    --password=SecurePassword123! \
    --email=admin@example.com \
    --permissions=admin.super \
    --fullname="Super Administrator"
# user/accounts/admin.yaml

state: enabled
email: admin@example.com
fullname: Super Administrator
title: System Administrator
access:
  admin:
    login: true
    super: true  # Full admin access
  site:
    login: true
hashed_password: $2y$10$...

Create Limited Admin

# user/accounts/editor.yaml

state: enabled
email: editor@example.com
fullname: Content Editor
access:
  admin:
    login: true
    super: false
    pages: true      # Can edit pages
    plugins: false   # Cannot install plugins
    themes: false    # Cannot change themes
    users: false     # Cannot manage users
    config: false    # Cannot change config
  site:
    login: true
hashed_password: $2y$10$...

Editing Users

Via Admin Panel

  1. Go to Accounts
  2. Click on user to edit
  3. Modify details:
    • Email
    • Full name
    • Title
    • Password (if changing)
    • Permissions
    • Groups
  4. Click Save

Via YAML Files

# Edit user account file
nano user/accounts/johndoe.yaml

# Make changes, save file

# Clear cache
bin/grav clear-cache

Reset User Password

# Via CLI
bin/plugin login newuser --user=johndoe --password=NewPassword123

# Or edit YAML file with new hash
# user/accounts/johndoe.yaml
hashed_password: $2y$10$NEW_HASH_HERE

Removing Users

Via Admin Panel

  1. Navigate to Accounts

    • Go to /admin
    • Click Accounts
  2. Delete User

    • Click user to delete
    • Click Delete button
    • Confirm deletion
    • User account file removed

Via CLI

# Delete user account file
rm user/accounts/username.yaml

# Clear cache
bin/grav clear-cache

Bulk User Deletion

#!/bin/bash
# delete-users.sh

# Delete multiple users
users=("user1" "user2" "user3")

for user in "${users[@]}"
do
    if [ -f "user/accounts/${user}.yaml" ]; then
        rm "user/accounts/${user}.yaml"
        echo "Deleted: $user"
    else
        echo "Not found: $user"
    fi
done

# Clear cache
bin/grav clear-cache

Disabling Users (Soft Delete)

Instead of deleting, disable user accounts:

# user/accounts/johndoe.yaml

state: disabled  # Changed from 'enabled'

# User cannot login but account preserved
# Can re-enable by changing back to 'enabled'
# Via CLI - disable user
# Edit YAML file to set state: disabled
nano user/accounts/johndoe.yaml

User Account Backup

Backup All Users

# Backup user accounts directory
tar -czf users-backup-$(date +%Y%m%d).tar.gz user/accounts/

# Or copy to backup location
cp -r user/accounts/ /path/to/backup/accounts-$(date +%Y%m%d)/

Restore Users

# Restore from backup
tar -xzf users-backup-20240115.tar.gz -C user/

# Or copy back
cp -r /path/to/backup/accounts-20240115/* user/accounts/

Custom User Fields

Add Custom Fields to User Accounts

# user/accounts/johndoe.yaml

state: enabled
email: johndoe@example.com
fullname: John Doe

# Custom fields
department: Marketing
phone: '+1-555-0123'
bio: 'Experienced content creator...'
social:
  twitter: '@johndoe'
  linkedin: 'johndoe'
preferences:
  newsletter: true
  notifications: true

Access Custom Fields in Templates

{# Display current user custom fields #}

{% if grav.user.authenticated %}
<div class="user-profile">
    <h2>{{ grav.user.fullname }}</h2>
    <p>Department: {{ grav.user.department }}</p>
    <p>Phone: {{ grav.user.phone }}</p>
    <p>Bio: {{ grav.user.bio }}</p>
</div>
{% endif %}

Bulk User Import

Import from CSV

<?php
// scripts/import-users.php

require_once __DIR__ . '/../vendor/autoload.php';

use Grav\Common\Grav;
use Grav\Common\User\User;

$grav = Grav::instance();
$grav->setup();

$csvFile = 'users.csv';
$handle = fopen($csvFile, 'r');
$header = fgetcsv($handle);

while (($row = fgetcsv($handle)) !== false) {
    $data = array_combine($header, $row);

    $username = $data['username'];
    $user = User::load($username);

    $user->set('email', $data['email']);
    $user->set('fullname', $data['fullname']);
    $user->set('state', 'enabled');
    $user->set('access', [
        'site' => ['login' => true]
    ]);

    // Set password
    $user->set('password', $data['password']);

    $user->save();
    echo "Created user: $username\n";
}

fclose($handle);
# users.csv
username,email,fullname,password
johndoe,john@example.com,John Doe,Password123
janedoe,jane@example.com,Jane Doe,Password456

Security Best Practices

1. Strong Password Policy

# user/config/plugins/login.yaml
strong_password:
  enabled: true
  minimum_length: 12
  require_uppercase: true
  require_lowercase: true
  require_numbers: true
  require_special_chars: true

2. Limit Failed Login Attempts

# user/config/plugins/login.yaml
max_login_count: 5
max_pw_resets_count: 3
max_pw_resets_interval: 2  # hours

3. Two-Factor Authentication

# Install 2FA plugin
bin/gpm install login-2fa
# user/config/plugins/login-2fa.yaml
enabled: true
secret_length: 32

4. Regular User Audits

# List all users
ls -la user/accounts/

# Check for inactive users
# Review user permissions regularly
# Remove unused accounts

Troubleshooting

Cannot Create User

Issue: User creation fails.

Checks:

  1. Permissions on user/accounts/ directory
    chmod 755 user/accounts/
    
  2. Unique username and email
  3. Valid email format
  4. Password meets requirements

User Cannot Login

Issue: User account exists but cannot login.

Checks:

  1. User state is enabled:
    state: enabled
    
  2. Password hash is correct
  3. Permissions include site.login or admin.login:
    access:
      site:
        login: true
    
  4. Login plugin enabled
  5. Clear cache

Lost Admin Access

Recovery:

# Create new admin via CLI
bin/plugin login newuser \
    --user=recovery \
    --password=TempPassword123! \
    --email=recovery@example.com \
    --permissions=admin.super

# Login with new admin
# Reset original admin password
# Delete recovery account

Next Steps

Resources