Concierge
view release on metacpan or search on metacpan
role => 'admin',
});
my $login = $concierge->login_user({
user_id => 'alice',
password => 'secret123',
});
my $user = $login->{user}; # Concierge::Desk::User object
say $user->moniker; # "Alice"
say $user->session_id; # random hex token
```
## How It Works
### Desks
A *desk* is a directory containing the configuration and data files for all
three components. You create one with `Concierge::Desk::Setup`, then open it at
runtime with `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('./desk', {
users_backend => 'database',
sessions_backend => 'sqlite',
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 | Session | User record | Auth |
|---|---|---|---|---|
| Visitor | `admit_visitor()` | No | No | No |
| Guest | `checkin_guest()` | Yes | No | No |
| Logged-in | `login_user()` | 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.
## Component Capabilities
### Authentication â Concierge::Auth
- **Argon2id** 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 (`checkPwd`, `setPwd`, `resetPwd`, `deleteID`, etc.)
for LDAP, OAuth, or other schemes
### Sessions â Concierge::Sessions
- **Multiple backends**: SQLite (recommended), flat-file, or in-memory text
- 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
Standard fields include:
| Field | Notes |
|---|---|
| `user_id` | Required, unique identifier |
| `moniker` | Required, display name |
| `email`, `phone` | Contact fields |
| `access_level` | e.g. `admin`, `staff`, `member` |
| `user_status` | e.g. `OK`, `suspended` |
| `term_ends` | Membership/subscription expiry |
| `last_login_date` | Auto-updated on login |
Applications extend this with `app_fields` at setup time:
```perl
Concierge::Desk::Setup->build_desk('./desk', {
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`.
## Consistent Return Values
All Concierge methods return a hashref:
```perl
# Success
{ success => 1, message => '...', ... }
# Failure
( run in 0.539 second using v1.01-cache-2.11-cpan-22024b96cdf )