Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

User Management Bundle Laravel Package

kunstmaan/user-management-bundle

Symfony bundle for user management in Kunstmaan applications, offering reusable user entities, registration, authentication integration, profile editing, password reset, and admin screens to help teams add and manage users with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is not a standalone user system — it is the admin UI layer of the Kunstmaan CMS stack. It gives you screens at /{_locale}/admin/settings/ for users, groups and roles, and it delegates the actual security model to FOSUserBundle + Symfony's firewall. If you are not already running kunstmaan/bundles-cms (Symfony 2.x era), there is very little here to leverage.

Prerequisites

  • Symfony 2.3–2.8 (the last release tag is from April 2014; there is no Symfony 3/4/5 support)
  • friendsofsymfony/user-bundle (~1.3 / ~2.0)
  • kunstmaan/admin-bundle, kunstmaan/admin-list-bundle, kunstmaan/node-bundle (the settings screens are gated on node/admin routing and menus)
  • A working firewall and Doctrine ORM setup

Install and wire up

composer require kunstmaan/user-management-bundle
// app/AppKernel.php
new Kunstmaan\UserManagementBundle\KunstmaanUserManagementBundle(),
new FOS\UserBundle\FOSUserBundle(),
# app/config/config.yml
fos_user:
    db_driver: orm
    firewall_name: main
    user_class: Kunstmaan\UserManagementBundle\Entity\User
    group:
        group_class: Kunstmaan\UserManagementBundle\Entity\Group
# app/config/routing.yml
fos_user_security: { resource: "@FOSUserBundle/Resources/config/routing/security.xml" }
kunstmaan_user_management: { resource: "@KunstmaanUserManagementBundle/Resources/config/routing.yml" }

Then run doctrine:schema:update --force (the bundle ships no migrations — the entity schema is your responsibility) and assets:install --symlink web.

Where to look first

  1. Entity/ — User, Group, Role. User and Group extend the FOSUserBundle models; Role is a plain entity that only exists to populate the "assignable roles" list.
  2. AdminList/ — UserAdminListConfigurator, GroupAdminListConfigurator, RoleAdminListConfigurator. This is where every column, filter and bulk action lives.
  3. Form/ — UserAdminType, GroupAdminType, RoleAdminType. Your extension point for extra profile fields.
  4. Controller/ — UserController, GroupController, RoleController. Standard index/add/edit/delete CRUD.
  5. Resources/config/services.yml — the service IDs you will override. Read this file before guessing names.

First use case

Bootstrap a super admin from the CLI (you cannot log into the UI to create the first one):

app/console fos:user:create admin [email protected] mypassword --super-admin
app/console cache:clear

Log in at /en/admin, go to Settings → Users, edit the user, assign a group and roles, save. Then verify that a second, non-super-admin user is denied access to the settings routes.

Implementation Patterns

Extend the entities, do not edit vendor. The normal day-to-day job is adding fields (phone, locale, avatar, lastLoginIp). Extend Kunstmaan\UserManagementBundle\Entity\User and repoint fos_user.user_class. Important: the base bundle's mapped properties are declared on the parent class, so copy the full mapping into your subclass rather than relying on annotation inheritance — this is the same dance FOSUserBundle documents for its own model.

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Kunstmaan\UserManagementBundle\Entity\User as BaseUser;

/**
 * @ORM\Entity
 * @ORM\Table(name="app_user")
 */
class User extends BaseUser
{
    // re-declare inherited columns here, plus your own:
    /** @ORM\Column(type="string", nullable=true) */
    protected $phone;
}

Override the admin list configurators to add columns, filters and exports. Subclass the Kunstmaan configurator, adjust it in the constructor (addColumn, addFilter, addAction, addBulkAction), and re-point the service ID (they follow the kunstmaan_user_management.admin_list.configurator.* convention — confirm exact IDs in Resources/config/services.yml).

class UserAdminListConfigurator extends BaseUserAdminListConfigurator
{
    public function buildFilters()
    {
        parent::buildFilters();
        $this->addFilter(new StringFilter('phone', 'Phone'));
    }
}
kunstmaan_user_management.admin_list.configurator.user:
    class: AppBundle\AdminList\UserAdminListConfigurator
    # keep the parent's constructor arguments

Override the forms the same way — extend UserAdminType and add your fields. Keep the base plainPassword handling intact; if you ever rewrite it, only call setPassword() when the submitted plain password is non-empty, otherwise every profile edit silently invalidates the user's password.

Treat Role as a dropdown, and security.yml as the truth. The bundle stores role rows in the database purely so editors can tick them in the UI. Hierarchy, isGranted() behaviour and voter logic still live in security.yml. Seed the Role table from a fixture or migration so the list matches your hierarchy, and remember there is no automatic two-way sync — adding a role in security.yml does not make it selectable until someone inserts a row.

# app/config/security.yml — this, not the DB, decides inheritance
security:
    role_hierarchy:
        ROLE_ADMIN: [ROLE_USER]
        ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_USER, ROLE_ALLOWED_TO_SWITCH]

Groups are the permission unit for content. In the CMS, Kunstmaan\NodeBundle stores per-node permissions against groups; the user admin screen is where you put people into those groups. The daily workflow is: create group → give it roles → grant it node permissions editor-side → add users to the group. Changing a user's groups is the fastest way to grant/revoke page access, and unlike role edits it takes effect immediately (no re-login needed for node permission checks in most Kunstmaan setups, but role changes do require a fresh login token).

Control the "disabled" axis explicitly. Your User has enabled, locked and expiresAt. The FOSUser UserChecker rejects enabled = false and locked = true; expiresAt is checked by the AccountStatusException path. Pick one convention for "deactivate this person" and stick to it in your own tooling, because the admin form exposes a subset of these and support tickets get confusing when one flag is set and another is not.

Use the CLI for ops rather than hand-editing the DB. The bundle is UI-only; password resets, promotions and provisioning belong in fos:user:* commands or your own console command:

app/console fos:user:change-password jane
app/console fos:user:promote jane ROLE_ADMIN
app/console fos:user:demote jane ROLE_ADMIN

Override templates and translations under app/Resources/KunstmaanUserManagementBundle/views/ and app/Resources/translations/. The settings templates are thin — most cosmetic changes (column ordering, button labels) are easier there than in the configurator.

Gotchas and Tips

  • This package is effectively dead. 4 stars, 0 dependents, last tagged release 2014-04-22, and the whole Kunstmaan CMS stack it belongs to is on the same trajectory. Do not adopt it for new work; treat this assessment as maintenance guidance for an existing Symfony 2 application.
  • Composer is the first wall. The bundle's composer.json constraints will conflict with any modern Symfony, and it pulls in an old FOSUserBundle. Expect to pin symfony/symfony to 2.x and PHP to 5.5/7.0-era versions. If you're on PHP 7.1+ you'll hit deprecations and possibly hard failures on each()/mcrypt usage in the wider stack.
  • No migrations ship with the bundle. doctrine:schema:update is the default path, which means no downgrade and no reviewable diff. Generate a real migration from the schema diff before you ship, especially if you're extending the entity.
  • Roles vs. hierarchy drift is the #1 support issue. A role that exists in the Role table but not in security.yml can be assigned and will do nothing. Add a fixture that creates both, and add an admin-list column showing the role name so reviewers can spot typos.
  • ROLE_SUPER_ADMIN is not magic unless you configure it. Symfony expands roles only through role_hierarchy; if super admins need to pass isGranted('ROLE_ADMIN') checks, declare it explicitly. Kunstmaan's settings screens check the super-admin role, which is why the first user must be created with --super-admin.
  • Do not expose this UI to non-admins. The routes live under /admin/settings/; make sure access_control covers the prefix and that the admin menu doesn't render the entry for lower roles. The settings area can change group membership, which is effectively a permission-escalation surface.
  • Service overrides must preserve constructor arguments. When you swap in a subclassed configurator or form type, copy the parent's arguments verbatim. A missing EntityManager or Router argument fails at container compile time with a cryptic InvalidArgumentException, not at request time.
  • Deleting a user is rarely clean. Nodes, translations and media created by that user may hold foreign keys or createdBy references. Check the CMS's ownership columns before enabling a bulk delete action, and consider the "lock the account" workflow instead.
  • Admin-list bundle quirks are inherited. Column ordering follows call order, filters with the same name silently overwrite, and bulk actions need a registered route plus a handler service. Debug by dumping the configurator's getColumns()/getFilters() rather than guessing.
  • Password encoder changes break everyone at once. fos_user.encoder is global; if you migrate the encoder algorithm, all existing hashes become unverifiable unless you implement an encoder-aware upgrade-on-login path. Plan this as a project, not a config tweak.
  • Cache and assets. Config, service and routing changes need cache:clear; the bundle's icons/JS need assets:install --symlink web or the settings pages render unstyled and the JS bulk actions won't wire up.
  • Extension points, in order of preference: (1) subclass configurators/forms/services, (2) override Twig templates, (3) decorate the controller via a route with the same path imported after the bundle, (4) fork the bundle — only if you have accepted that you now own it.
  • Migration path if you get out: move to symfony/security-bundle + make:user (Symfony 5+) or a maintained admin CRUD (EasyAdmin, SonataAdmin). Export users, groups and role assignments first; password hashes are portable if you keep the same encoder, which removes the biggest migration pain.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource