]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/UserTokenService.php
Apply fixes from StyleCI
[bookstack] / app / Auth / Access / UserTokenService.php
1 <?php
2
3 namespace BookStack\Auth\Access;
4
5 use BookStack\Auth\User;
6 use BookStack\Exceptions\UserTokenExpiredException;
7 use BookStack\Exceptions\UserTokenNotFoundException;
8 use Carbon\Carbon;
9 use Illuminate\Database\Connection as Database;
10 use Illuminate\Support\Str;
11 use stdClass;
12
13 class UserTokenService
14 {
15     /**
16      * Name of table where user tokens are stored.
17      *
18      * @var string
19      */
20     protected $tokenTable = 'user_tokens';
21
22     /**
23      * Token expiry time in hours.
24      *
25      * @var int
26      */
27     protected $expiryTime = 24;
28
29     protected $db;
30
31     /**
32      * UserTokenService constructor.
33      *
34      * @param Database $db
35      */
36     public function __construct(Database $db)
37     {
38         $this->db = $db;
39     }
40
41     /**
42      * Delete all email confirmations that belong to a user.
43      *
44      * @param User $user
45      *
46      * @return mixed
47      */
48     public function deleteByUser(User $user)
49     {
50         return $this->db->table($this->tokenTable)
51             ->where('user_id', '=', $user->id)
52             ->delete();
53     }
54
55     /**
56      * Get the user id from a token, while check the token exists and has not expired.
57      *
58      * @param string $token
59      *
60      * @throws UserTokenNotFoundException
61      * @throws UserTokenExpiredException
62      *
63      * @return int
64      */
65     public function checkTokenAndGetUserId(string $token): int
66     {
67         $entry = $this->getEntryByToken($token);
68
69         if (is_null($entry)) {
70             throw new UserTokenNotFoundException('Token "' . $token . '" not found');
71         }
72
73         if ($this->entryExpired($entry)) {
74             throw new UserTokenExpiredException("Token of id {$entry->id} has expired.", $entry->user_id);
75         }
76
77         return $entry->user_id;
78     }
79
80     /**
81      * Creates a unique token within the email confirmation database.
82      *
83      * @return string
84      */
85     protected function generateToken(): string
86     {
87         $token = Str::random(24);
88         while ($this->tokenExists($token)) {
89             $token = Str::random(25);
90         }
91
92         return $token;
93     }
94
95     /**
96      * Generate and store a token for the given user.
97      *
98      * @param User $user
99      *
100      * @return string
101      */
102     protected function createTokenForUser(User $user): string
103     {
104         $token = $this->generateToken();
105         $this->db->table($this->tokenTable)->insert([
106             'user_id'    => $user->id,
107             'token'      => $token,
108             'created_at' => Carbon::now(),
109             'updated_at' => Carbon::now(),
110         ]);
111
112         return $token;
113     }
114
115     /**
116      * Check if the given token exists.
117      *
118      * @param string $token
119      *
120      * @return bool
121      */
122     protected function tokenExists(string $token): bool
123     {
124         return $this->db->table($this->tokenTable)
125             ->where('token', '=', $token)->exists();
126     }
127
128     /**
129      * Get a token entry for the given token.
130      *
131      * @param string $token
132      *
133      * @return object|null
134      */
135     protected function getEntryByToken(string $token)
136     {
137         return $this->db->table($this->tokenTable)
138             ->where('token', '=', $token)
139             ->first();
140     }
141
142     /**
143      * Check if the given token entry has expired.
144      *
145      * @param stdClass $tokenEntry
146      *
147      * @return bool
148      */
149     protected function entryExpired(stdClass $tokenEntry): bool
150     {
151         return Carbon::now()->subHours($this->expiryTime)
152             ->gt(new Carbon($tokenEntry->created_at));
153     }
154 }