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

lonnieezell / myth-auth / 3798654288

pending completion
3798654288

Pull #584

github

GitHub
Merge db6ea1b4f into da3522738
Pull Request #584: fixes bug with Group Permissions and User cache

829 of 2294 relevant lines covered (36.14%)

8.52 hits per line

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

94.67
/src/Models/GroupModel.php
1
<?php
2

3
namespace Myth\Auth\Models;
4

5
use CodeIgniter\Model;
6
use Faker\Generator;
7
use Myth\Auth\Entities\Group;
8
use Myth\Auth\Entities\Permission;
9
use Myth\Auth\Entities\User;
10
use stdClass;
11

12
class GroupModel extends Model
13
{
14
    protected $table         = 'auth_groups';
15
    protected $returnType    = Group::class;
16
    protected $allowedFields = [
17
        'name',
18
        'description',
19
    ];
20
    protected $validationRules = [
21
        'name'        => 'required|max_length[255]|is_unique[auth_groups.name,name,{name}]',
22
        'description' => 'max_length[255]',
23
    ];
24

25
    /**
26
     * The permission model to use.
27
     *
28
     * @see getPermissionsForGroup()
29
     */
30
    protected string $permissionModel = PermissionModel::class;
31

32
    // --------------------------------------------------------------------
33
    // Users
34
    // --------------------------------------------------------------------
35

36
    /**
37
     * Adds a single user to a single group.
38
     *
39
     * @return bool
40
     */
41
    public function addUserToGroup(int $userId, int $groupId)
42
    {
43
        cache()->delete("{$groupId}_users");
13✔
44
        cache()->delete("{$userId}_groups");
13✔
45
        cache()->delete("{$userId}_permissions");
13✔
46

47
        $data = [
13✔
48
            'user_id'  => $userId,
13✔
49
            'group_id' => $groupId,
13✔
50
        ];
13✔
51

52
        return $this->db->table('auth_groups_users')->insert($data);
13✔
53
    }
54

55
    /**
56
     * Removes a single user from a single group.
57
     *
58
     * @param int|string $groupId
59
     *
60
     * @return bool
61
     */
62
    public function removeUserFromGroup(int $userId, $groupId)
63
    {
64
        cache()->delete("{$groupId}_users");
3✔
65
        cache()->delete("{$userId}_groups");
3✔
66
        cache()->delete("{$userId}_permissions");
3✔
67

68
        return $this->db->table('auth_groups_users')
3✔
69
            ->where([
3✔
70
                'user_id'  => $userId,
3✔
71
                'group_id' => (int) $groupId,
3✔
72
            ])->delete();
3✔
73
    }
74

75
    /**
76
     * Removes a single user from all groups.
77
     *
78
     * @return bool
79
     */
80
    public function removeUserFromAllGroups(int $userId)
81
    {
82
        cache()->delete("{$userId}_groups");
1✔
83
        cache()->delete("{$userId}_permissions");
1✔
84

85
        return $this->db->table('auth_groups_users')
1✔
86
            ->where('user_id', $userId)
1✔
87
            ->delete();
1✔
88
    }
89

90
    /**
91
     * Returns an array of all groups that a user is a member of.
92
     *
93
     * @return array[]
94
     */
95
    public function getGroupsForUser(int $userId)
96
    {
97
        if (null === $found = cache("{$userId}_groups")) {
7✔
98
            $found = $this->builder()
5✔
99
                ->select('auth_groups_users.*, auth_groups.name, auth_groups.description')
5✔
100
                ->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
5✔
101
                ->where('user_id', $userId)
5✔
102
                ->get()->getResultArray();
5✔
103

104
            cache()->save("{$userId}_groups", $found, 300);
5✔
105
        }
106

107
        return $found;
7✔
108
    }
109

110
    /**
111
     * Returns an array of all users that are members of a group.
112
     *
113
     * @return array[]
114
     */
115
    public function getUsersForGroup(int $groupId)
116
    {
117
        if (null === $found = cache("{$groupId}_users")) {
14✔
118
            $found = $this->builder()
12✔
119
                ->select('auth_groups_users.*, users.*')
12✔
120
                ->join('auth_groups_users', 'auth_groups_users.group_id = auth_groups.id', 'left')
12✔
121
                ->join('users', 'auth_groups_users.user_id = users.id', 'left')
12✔
122
                ->where('auth_groups.id', $groupId)
12✔
123
                ->get()->getResultArray();
12✔
124

125
            cache()->save("{$groupId}_users", $found, 300);
12✔
126
        }
127

128
        return $found;
14✔
129
    }
130

131
    // --------------------------------------------------------------------
132
    // Permissions
133
    // --------------------------------------------------------------------
134

135
    /**
136
     * Gets all permissions for a group in a way that can be
137
     * easily used to check against:
138
     *
139
     * @return array<int, array|Permission> An array in format permissionId => permission
140
     */
141
    public function getPermissionsForGroup(int $groupId): array
142
    {
143
        $fromGroup = model($this->permissionModel)
2✔
144
            ->select('auth_permissions.*')
2✔
145
            ->join('auth_groups_permissions', 'auth_groups_permissions.permission_id = auth_permissions.id', 'inner')
2✔
146
            ->where('group_id', $groupId)
2✔
147
            ->findAll();
2✔
148

149
        $found = [];
2✔
150

151
        foreach ($fromGroup as $permission) {
2✔
152
            $id = is_object($permission) ? $permission->id : $permission['id'];
1✔
153

154
            $found[$id] = $permission;
1✔
155
        }
156

157
        return $found;
2✔
158
    }
159

160
    /**
161
     * Add a single permission to a single group, by IDs.
162
     */
163
    public function addPermissionToGroup(int $permissionId, int $groupId): bool
164
    {
165
        $this->handlePermissionsCache($groupId);
7✔
166

167
        $data = [
7✔
168
            'permission_id' => $permissionId,
7✔
169
            'group_id'      => $groupId,
7✔
170
        ];
7✔
171

172
        return $this->db->table('auth_groups_permissions')->insert($data);
7✔
173
    }
174

175
    // --------------------------------------------------------------------
176

177
    /**
178
     * Removes a single permission from a single group.
179
     *
180
     * @return mixed
181
     */
182
    public function removePermissionFromGroup(int $permissionId, int $groupId)
183
    {
184
        $this->handlePermissionsCache($groupId);
3✔
185

186
        return $this->db->table('auth_groups_permissions')
3✔
187
            ->where([
3✔
188
                'permission_id' => $permissionId,
3✔
189
                'group_id'      => $groupId,
3✔
190
            ])->delete();
3✔
191
    }
192

193
    // --------------------------------------------------------------------
194

195
    /**
196
     * Removes a single permission from all groups.
197
     *
198
     * @return mixed
199
     */
200
    public function removePermissionFromAllGroups(int $permissionId)
201
    {
202
        $alteredGroups = $this->db->table('auth_groups_permissions')
2✔
203
            ->where('permission_id', $permissionId)
2✔
204
            ->get()->getResultArray();
2✔
205

206
        foreach ($alteredGroups as $row) {
2✔
207
            $this->handlePermissionsCache($row['group_id']);
1✔
208
        }
209

210
        return $this->db->table('auth_groups_permissions')
2✔
211
            ->where('permission_id', $permissionId)
2✔
212
            ->delete();
2✔
213
    }
214

215
    /**
216
     * Updates user's permissons cache when group permissions altered.
217
     */
218
    private function handlePermissionsCache(int $groupId): void
219
    {
220
        $users = $this->getUsersForGroup($groupId);
11✔
221

222
        foreach ($users as $row) {
11✔
223
            cache()->delete("{$row['id']}_permissions");
11✔
224
        }
225
    }
226

227
    /**
228
     * Faked data for Fabricator.
229
     *
230
     * @return Group|stdClass See GroupFaker
231
     */
232
    public function fake(Generator &$faker)
233
    {
234
        return new Group([
×
235
            'name'        => $faker->word,
×
236
            'description' => $faker->sentence,
×
237
        ]);
×
238
    }
239
}
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

© 2025 Coveralls, Inc