aboutsummaryrefslogtreecommitdiff
path: root/lib/models/Token.php
blob: dd52602f9a34f77835f347621cd47ac9aa87d912 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
<?php
/**
 * Token.php - Token class
 *
 * @author    Jan-Hendrik Willms <tleilax+studip@gmail.com>
 * @author    Marco Diedrich <mdiedric@uos.de>
 * @license   GPL2 or any later version
 */
class Token extends SimpleORMap
{
    /**
     * Configures the model
     *
     * @param array $config
     */
    protected static function configure($config = [])
    {
        $config['db_table'] = 'user_token';

        $config['belongs_to']['user'] = [
            'class_name'  => User::class,
            'foreign_key' => 'user_id',
        ];

        // Create new token and ensure token is unique upon store
        $config['registered_callbacks']['before_create'][] = function ($object) {
            do {
                $token = md5(uniqid(__CLASS__, true));
            } while (Token::exists($token));

            $object->token = $token;
        };

        // Ensure tokens are not changed
        $config['registered_callbacks']['before_store'][] = function ($object) {
            if (!$object->isNew() && $object->isFieldDirty('token')) {
                return false;
            }
        };

        parent::configure($config);
    }

    /**
     * Creates a new token.
     *
     * @param  integer $duration Lifetime of the token
     * @param  mixed   $user_id  Optional id of the user (defaults to current user)
     * @return string the token
     */
    public static function create($duration = 30, $user_id = null)
    {
        $token = new static();
        $token->user_id    = $user_id ?? $GLOBALS['user']->id;
        $token->expiration = strtotime("+{$duration} seconds");
        $token->store();

        return $token->token;
    }

    /**
     * Checks if a token is valid (for a given user).
     *
     * Based on the number of paremters this either returns the id of the user
     * the token belongs to or a boolean if the id of a user was already given.
     *
     * @param  string  $token   Token to check
     * @param  mixed   $user_id Optional id of a user
     * @return mixed  User id of none was given or boolean
     */
    public static function isValid($token, $user_id = null)
    {
        $token = static::find($token);

        // No db entry for token
        if (!$token || $token->isExpired()) {
            return null;
        }

        // Token is valid
        $token_user_id = $token->user_id;
        $token->delete();

        return func_num_args() === 1
             ? $token_user_id
             : $token_user_id === ($user_id ?? $GLOBALS['user']->id);
    }

    /**
     * Returns whether the token is expired
     * @return boolean
     */
    public function isExpired()
    {
        return $this->expiration < time();
    }
}