Concierge

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

  extends to anything an added component manages.

## How It Works

### Desks

A *desk* is a directory containing the configuration and data files for the
three identity-core components -- and, if you've added any, for those too.
You create one with `Concierge::Desk::Setup`, then open it at
runtime with `Concierge->open_desk()`. Opening a desk instantiates all components from
the saved configuration and runs session cleanup automatically.

```perl
# One-time setup (run once, not on every request)
use Concierge::Desk::Setup;
Concierge::Desk::Setup::build_desk({
    base_dir => './desk',
    auth     => { backend => 'pwd' },
    sessions => { backend => 'database' },
    users    => {
        backend    => 'database',
        app_fields => ['department', 'theme'],
    },
});

# Every request
use Concierge;
my $result    = Concierge->open_desk('./desk');
my $concierge = $result->{concierge};
```

### User Participation Levels

Concierge provides three graduated levels, each returning a
`Concierge::Desk::User` object with methods appropriate to that level:

| Level | Method | User key | Session | User record | Auth |
|---|---|---|---|---|---|
| Visitor | `admit_visitor()` | Yes | No | No | No |
| Guest | `checkin_guest()` | Yes | Yes | No | No |
| Logged-in | `login_user()` | Yes | Yes | Yes | Yes |

A guest can be promoted to a logged-in user with `login_guest()`, which
transfers any session data (shopping cart, preferences, etc.) to the new
authenticated session.

Between requests, users are restored by `user_key` (typically stored in a
cookie): `restore_user($user_key)` rehydrates the correct object type with
the right data and backend access.

## Components

Concierge ships with a complete identity core out of the box, and the same
component pattern that powers it extends to anything else your
application needs to manage.

### Identity Core (built in)

#### Authentication — Concierge::Auth

- **Argon2** password hashing and verification; no plaintext credentials
  written to disk
- Random value generators: hex IDs, alphanumeric tokens, UUIDs (v4),
  word-passphrases from a system dictionary
- Designed for substitution: swap in any replacement that implements the
  same method contract (`enroll`, `authenticate`, `is_id_known`,
  `change_credentials`, `revoke`) for LDAP, OAuth, or other schemes

#### Sessions — Concierge::Sessions

- **Multiple backends**: SQLite (recommended) or flat-file
- Every session lives in memory first; data is only written to whichever
  backend is configured when `->save()` is called. Some sessions never call
  `save()` at all and exist purely for in-process continuity.
- Sessions carry arbitrary key/value data (shopping carts, wizard state,
  preferences, etc.)
- Configurable timeout per session; expired sessions cleaned up automatically
  on `open_desk()`
- **Single-session-per-user** enforced at login: a new session replaces any
  prior session for that user
- Full lifecycle: create, get, update data, save, delete, cleanup

#### User Records — Concierge::Users

- **Multiple backends**: SQLite, YAML, CSV/TSV
- **Configurable field schema**: built-in standard fields plus
  application-defined fields added at setup time

See the Concierge::Users README (Field Customization) for the full list of
standard fields.

Applications extend this with `app_fields` at setup time:

```perl
Concierge::Desk::Setup::build_desk({
    base_dir => './desk',
    auth     => { backend => 'pwd' },
    sessions => { backend => 'database' },
    users    => {
        backend    => 'database',
        app_fields => [
            { field_name => 'department', type => 'text' },
            { field_name => 'plan',       type => 'enum',
              options => ['free', 'pro', 'enterprise'] },
        ],
    },
});
```

Field definitions can also override built-in defaults (labels, null values,
required flags, etc.) via `field_overrides`.

All or selected standard fields may also be omitted entirely, except for the
required fields and automatic date fields.

### Extensibility (bring your own)

Each identity core component can itself be replaced with a conforming
alternative -- any drop-in that implements the same method contract (see
`EXTENSIBILITY` in `perldoc Concierge`) works in place of the built-in
Auth, Sessions, or Users component.

Beyond the identity core, a desk can carry any number of additional
components -- Organizations, Assets, Guides, Catalog, or anything else
your application manages the same way. A component only needs to satisfy
the duck-typed contract in `Concierge::Desk::Component` (a `new`/`setup`
constructor lifecycle and the `{ success => ..., message => ... }` return



( run in 0.845 second using v1.01-cache-2.11-cpan-0fb53d1c279 )