Skip to content

Commit 585a62c

Browse files
committed
Fix up docs.
1 parent e466543 commit 585a62c

File tree

6 files changed

+428
-10
lines changed

6 files changed

+428
-10
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ Finally, load the plugin:
139139
bin/cake plugin load TinyAuth
140140
```
141141

142-
**Note:** The AuthUser component and helper can work standalone with any dependencies.
142+
**Note:** The AuthUser component and helper can work standalone without requiring the official plugins. They work with any authentication solution that sets an identity in the request.
143143

144144
## Docs
145145
For setup and usage see [Docs](/docs).

docs/AuthUser.md

Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
# AuthUser Component and Helper
2+
3+
The AuthUser component and helper provide convenient methods for working with the currently authenticated user in your controllers and views.
4+
5+
**Key Feature:** These work **standalone** and do not require the official Authentication or Authorization plugins. They work with any authentication solution that sets an identity in the request attributes.
6+
7+
## AuthUser Component
8+
9+
The component provides easy access to the current user's data and permission checks in your controllers.
10+
11+
### Setup
12+
13+
Load the component in your AppController:
14+
15+
```php
16+
// src/Controller/AppController.php
17+
18+
public function initialize(): void {
19+
parent::initialize();
20+
21+
$this->loadComponent('TinyAuth.AuthUser');
22+
}
23+
```
24+
25+
### Available Methods
26+
27+
#### `id()`
28+
Get the current user's ID:
29+
30+
```php
31+
$userId = $this->AuthUser->id();
32+
```
33+
34+
#### `isMe(int|string $id)`
35+
Check if a given ID belongs to the current user:
36+
37+
```php
38+
if ($this->AuthUser->isMe($post->user_id)) {
39+
// User owns this post
40+
}
41+
```
42+
43+
#### `hasRole(string|int $role)`
44+
Check if the user has a specific role (by alias or ID):
45+
46+
```php
47+
if ($this->AuthUser->hasRole('admin')) {
48+
// User is an admin
49+
}
50+
51+
if ($this->AuthUser->hasRole(ROLE_MODERATOR)) {
52+
// User is a moderator (using constant)
53+
}
54+
```
55+
56+
#### `hasRoles(array $roles)`
57+
Check if the user has any of the specified roles:
58+
59+
```php
60+
if ($this->AuthUser->hasRoles(['admin', 'moderator'])) {
61+
// User is either admin or moderator
62+
}
63+
```
64+
65+
#### `roles()`
66+
Get all roles for the current user:
67+
68+
```php
69+
$userRoles = $this->AuthUser->roles();
70+
```
71+
72+
#### `hasAccess(array $url)`
73+
Check if the user has access to a specific URL (checks ACL):
74+
75+
```php
76+
if ($this->AuthUser->hasAccess(['action' => 'delete', $id])) {
77+
return $this->redirect(['action' => 'delete', $id]);
78+
}
79+
// Do something else instead
80+
```
81+
82+
**Note:** By default, `hasAccess()` only checks the `auth_acl.ini` file, not `auth_allow.ini`. Set `includeAuthentication` config to `true` if you need to check public actions as well.
83+
84+
#### `identity()`
85+
Get the full identity object/array:
86+
87+
```php
88+
$identity = $this->AuthUser->identity();
89+
// Returns the original data from Authentication/Authorization identity
90+
```
91+
92+
### Example Usage
93+
94+
```php
95+
// In a controller action
96+
public function edit($id) {
97+
$post = $this->Posts->get($id);
98+
99+
// Only allow editing own posts unless admin
100+
if (!$this->AuthUser->isMe($post->user_id) && !$this->AuthUser->hasRole('admin')) {
101+
$this->Flash->error(__('You can only edit your own posts.'));
102+
return $this->redirect(['action' => 'index']);
103+
}
104+
105+
// Continue with edit logic...
106+
}
107+
```
108+
109+
## AuthUser Helper
110+
111+
The helper provides the same functionality in your templates, plus additional methods for conditionally displaying links.
112+
113+
### Setup
114+
115+
Load the helper in your AppView:
116+
117+
```php
118+
// src/View/AppView.php
119+
120+
public function initialize(): void {
121+
parent::initialize();
122+
123+
$this->loadHelper('TinyAuth.AuthUser');
124+
}
125+
```
126+
127+
**Important:** The helper requires the component to be loaded, as it needs data passed from the controller.
128+
129+
### Available Methods
130+
131+
The helper has all the same methods as the component:
132+
- `id()`
133+
- `isMe($id)`
134+
- `hasRole($role)`
135+
- `hasRoles($roles)`
136+
- `roles()`
137+
- `hasAccess($url)`
138+
- `identity()`
139+
140+
### Additional Helper-Only Methods
141+
142+
#### `link(string $title, array $url, array $options = [])`
143+
Display a link only if the user has access to that URL:
144+
145+
```php
146+
// Only displays if user has access to Admin prefix
147+
echo $this->AuthUser->link('Admin Backend', ['prefix' => 'Admin', 'action' => 'index']);
148+
```
149+
150+
If the user doesn't have access, nothing is displayed.
151+
152+
#### `postLink(string $title, array $url, array $options = [])`
153+
Display a POST link only if the user has access:
154+
155+
```php
156+
// Only displays delete link if user has delete permission
157+
echo $this->AuthUser->postLink('Delete', ['action' => 'delete', $id], [
158+
'confirm' => 'Are you sure?',
159+
]);
160+
```
161+
162+
### Named Routes Support
163+
164+
Both `link()` and `postLink()` support named routes:
165+
166+
```php
167+
<?= $this->AuthUser->link('Change Password', ['_name' => 'admin:account:password']); ?>
168+
```
169+
170+
### Template Examples
171+
172+
#### Conditional Content Display
173+
174+
```php
175+
<?php if ($this->AuthUser->hasRole('admin')): ?>
176+
<div class="admin-tools">
177+
<?= $this->AuthUser->link('Manage Users', ['controller' => 'Users', 'action' => 'index']); ?>
178+
<?= $this->AuthUser->link('Settings', ['controller' => 'Settings', 'action' => 'index']); ?>
179+
</div>
180+
<?php endif; ?>
181+
```
182+
183+
#### Show/Hide Based on Ownership
184+
185+
```php
186+
<?php if ($this->AuthUser->isMe($comment->user_id)): ?>
187+
<?= $this->AuthUser->postLink(
188+
'Delete Comment',
189+
['action' => 'delete', $comment->id],
190+
['confirm' => 'Are you sure?']
191+
); ?>
192+
<?php endif; ?>
193+
```
194+
195+
#### Complex Access Checks
196+
197+
```php
198+
<?php if ($this->AuthUser->hasAccess(['action' => 'secretArea'])): ?>
199+
<div class="secret-section">
200+
<p>Only for you:</p>
201+
<?= $this->Html->link('Secret Area', ['action' => 'secretArea']); ?>
202+
<small>(do not tell anyone else!)</small>
203+
</div>
204+
<?php endif; ?>
205+
```
206+
207+
#### Role-Based Navigation
208+
209+
```php
210+
<nav>
211+
<ul>
212+
<li><?= $this->Html->link('Home', ['action' => 'index']); ?></li>
213+
214+
<?php if ($this->AuthUser->hasRole('user')): ?>
215+
<li><?= $this->AuthUser->link('My Posts', ['action' => 'myPosts']); ?></li>
216+
<?php endif; ?>
217+
218+
<?php if ($this->AuthUser->hasRoles(['admin', 'moderator'])): ?>
219+
<li><?= $this->AuthUser->link('Moderation', ['action' => 'moderate']); ?></li>
220+
<?php endif; ?>
221+
222+
<?php if ($this->AuthUser->hasRole('admin')): ?>
223+
<li><?= $this->AuthUser->link('Admin', ['prefix' => 'Admin', 'action' => 'dashboard']); ?></li>
224+
<?php endif; ?>
225+
</ul>
226+
</nav>
227+
```
228+
229+
## Configuration
230+
231+
### Including Authentication in Access Checks
232+
233+
By default, `hasAccess()` only checks authorization (ACL), not authentication (public actions).
234+
235+
To include public actions in the access check:
236+
237+
```php
238+
$this->loadComponent('TinyAuth.AuthUser', [
239+
'includeAuthentication' => true,
240+
]);
241+
```
242+
243+
**Note:** This only works with INI-based configuration. Controller-level `allow()` calls cannot be detected.
244+
245+
## Best Practices
246+
247+
### Use Constants for Roles
248+
249+
Instead of magic strings, define role constants:
250+
251+
```php
252+
// In your bootstrap
253+
define('ROLE_USER', 'user');
254+
define('ROLE_MODERATOR', 'moderator');
255+
define('ROLE_ADMIN', 'admin');
256+
257+
// In your code
258+
if ($this->AuthUser->hasRole(ROLE_ADMIN)) {
259+
// Much better than: hasRole('admin')
260+
}
261+
```
262+
263+
This provides:
264+
- IDE autocompletion
265+
- Easy refactoring
266+
- Prevents typos
267+
- Self-documenting code
268+
269+
### Combine with Form Helper
270+
271+
```php
272+
<?php
273+
echo $this->Form->create($post);
274+
echo $this->Form->control('title');
275+
echo $this->Form->control('body');
276+
277+
// Only admins can change the status
278+
if ($this->AuthUser->hasRole('admin')) {
279+
echo $this->Form->control('status');
280+
}
281+
282+
echo $this->Form->button(__('Submit'));
283+
echo $this->Form->end();
284+
?>
285+
```
286+
287+
## Standalone Usage
288+
289+
AuthUser works with any authentication solution, not just TinyAuth:
290+
291+
- **CakePHP Authentication plugin** - Works out of the box
292+
- **CakePHP Authorization plugin** - Works out of the box
293+
- **Custom auth** - As long as you set an identity in request attributes
294+
295+
The component looks for the identity in `$request->getAttribute('identity')` and works with any object that implements `getOriginalData()` or is an array.

docs/Authentication.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,80 @@ $this->loadComponent('TinyAuth.Authentication', [
155155
]);
156156
```
157157

158+
## Authentication Helper
159+
160+
The Authentication helper provides template-level methods for checking if URLs are public.
161+
162+
### Setup
163+
164+
Load the helper in your AppView:
165+
166+
```php
167+
// src/View/AppView.php
168+
169+
public function initialize(): void {
170+
parent::initialize();
171+
172+
$this->loadHelper('TinyAuth.Authentication');
173+
}
174+
```
175+
176+
### Available Methods
177+
178+
#### `isPublic(array $url = [])`
179+
180+
Check if a given URL is public (allowed in `auth_allow.ini`):
181+
182+
```php
183+
// Check if current page is public
184+
<?php if ($this->Authentication->isPublic()): ?>
185+
<p>This page is public</p>
186+
<?php endif; ?>
187+
188+
// Check if a specific URL is public
189+
<?php if ($this->Authentication->isPublic(['controller' => 'Users', 'action' => 'register'])): ?>
190+
<?= $this->Html->link('Register', ['controller' => 'Users', 'action' => 'register']); ?>
191+
<?php endif; ?>
192+
```
193+
194+
#### Named Routes Support
195+
196+
The helper also supports named routes:
197+
198+
```php
199+
<?php if ($this->Authentication->isPublic(['_name' => 'users:register'])): ?>
200+
<p>Registration is public</p>
201+
<?php endif; ?>
202+
```
203+
204+
### Example Usage
205+
206+
#### Conditional Navigation
207+
208+
```php
209+
<nav>
210+
<ul>
211+
<?php if ($this->Authentication->isPublic(['action' => 'index'])): ?>
212+
<li><?= $this->Html->link('Home', ['action' => 'index']); ?></li>
213+
<?php endif; ?>
214+
215+
<?php if ($this->Authentication->isPublic(['controller' => 'Articles', 'action' => 'view'])): ?>
216+
<li><?= $this->Html->link('Articles', ['controller' => 'Articles']); ?></li>
217+
<?php endif; ?>
218+
</ul>
219+
</nav>
220+
```
221+
222+
#### Show Login Link Only on Public Pages
223+
224+
```php
225+
<?php if ($this->Authentication->isPublic() && !$this->AuthUser->id()): ?>
226+
<div class="login-prompt">
227+
<?= $this->Html->link('Login', ['controller' => 'Users', 'action' => 'login']); ?>
228+
</div>
229+
<?php endif; ?>
230+
```
231+
158232
## Configuration
159233

160234
TinyAuth Authentication component supports the following configuration options.

0 commit comments

Comments
 (0)