• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

daycry / auth / 25518434194

07 May 2026 07:49PM UTC coverage: 58.608% (-6.4%) from 64.989%
25518434194

push

github

web-flow
Merge pull request #47 from daycry/development

Implement security enhancements and new account features

277 of 1030 new or added lines in 55 files covered. (26.89%)

11 existing lines in 6 files now uncovered.

3544 of 6047 relevant lines covered (58.61%)

47.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Filters/TokenScopeFilter.php
1
<?php
2

3
declare(strict_types=1);
4

5
/**
6
 * This file is part of Daycry Auth.
7
 *
8
 * (c) Daycry <daycry9@proton.me>
9
 *
10
 * For the full copyright and license information, please view
11
 * the LICENSE file that was distributed with this source code.
12
 */
13

14
namespace Daycry\Auth\Filters;
15

16
use CodeIgniter\HTTP\RedirectResponse;
17
use CodeIgniter\HTTP\RequestInterface;
18
use CodeIgniter\HTTP\ResponseInterface;
19
use Daycry\Auth\Entities\AccessToken;
20
use Daycry\Auth\Entities\User;
21

22
/**
23
 * API Token Scope Authorization Filter.
24
 *
25
 * Validates that the access token used to authenticate the current request
26
 * grants every scope declared in the filter arguments. Tokens with the
27
 * `*` wildcard scope satisfy any check.
28
 *
29
 * Usage in routes:
30
 *     $routes->group('api', ['filter' => 'access_token,token-scope:read'], ...);
31
 *     $routes->post('/posts', 'Posts::create', ['filter' => 'access_token,token-scope:posts.write']);
32
 *
33
 * Multiple scopes are AND-ed:
34
 *     ['filter' => 'token-scope:read,write']  // requires BOTH read AND write
35
 *
36
 * Requires the request to have already been authenticated by the
37
 * `access_token` (or compatible) filter — the user's `currentAccessToken()`
38
 * must return a non-null `AccessToken` entity.
39
 */
40
class TokenScopeFilter extends AbstractAuthFilter
41
{
42
    /**
43
     * Ensures the current access token grants every scope listed in $arguments.
44
     */
NEW
45
    protected function isAuthorized(array $arguments): bool
×
46
    {
NEW
47
        $user = auth()->user();
×
48

NEW
49
        if (! $user instanceof User) {
×
NEW
50
            return false;
×
51
        }
52

NEW
53
        $token = $this->resolveCurrentAccessToken($user);
×
54

NEW
55
        if (! $token instanceof AccessToken) {
×
NEW
56
            return false;
×
57
        }
58

NEW
59
        foreach ($arguments as $scope) {
×
NEW
60
            $scope = trim((string) $scope);
×
61

NEW
62
            if ($scope === '') {
×
NEW
63
                continue;
×
64
            }
65

NEW
66
            if ($token->cant($scope)) {
×
NEW
67
                return false;
×
68
            }
69
        }
70

NEW
71
        return true;
×
72
    }
73

74
    /**
75
     * Returns the current access token in use for the authenticated request,
76
     * or null when no compatible authenticator is active.
77
     */
NEW
78
    private function resolveCurrentAccessToken(User $user): ?AccessToken
×
79
    {
NEW
80
        $token = $user->currentAccessToken();
×
81

NEW
82
        return $token instanceof AccessToken ? $token : null;
×
83
    }
84

85
    /**
86
     * Builds the denial response (403 JSON for APIs, redirect otherwise).
87
     */
NEW
88
    protected function redirectToDeniedUrl(RequestInterface $request): RedirectResponse|ResponseInterface
×
89
    {
NEW
90
        return $this->buildDeniedResponse($request, config('Auth')->permissionDeniedRedirect());
×
91
    }
92
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc