Completed
Push — master ( 2fcfce...de1d77 )
by Robbie
11s
created

getNewShareToken()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 34
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 21
nc 4
nop 0
dl 0
loc 34
rs 8.5806
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ShareDraftContent\Extensions;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Director;
7
use SilverStripe\Core\Config\Config;
8
use SilverStripe\ORM\DataExtension;
9
use SilverStripe\Security\RandomGenerator;
10
use SilverStripe\ShareDraftContent\Models\ShareToken;
11
12
/**
13
 * @mixin SiteTree
14
 */
15
class ShareDraftContentSiteTreeExtension extends DataExtension
16
{
17
    /**
18
     * The number of days a shared link should be valid for, before expiring.
19
     *
20
     * @config
21
     *
22
     * @var int
23
     */
24
    private static $valid_for_days = 30;
25
26
    /**
27
     * @var array
28
     */
29
    private static $db = array(
0 ignored issues
show
introduced by
The private property $db is not used, and could be removed.
Loading history...
30
        'ShareTokenSalt' => 'Varchar(16)',
31
    );
32
33
    /**
34
     * @var array
35
     */
36
    private static $has_many = array(
0 ignored issues
show
introduced by
The private property $has_many is not used, and could be removed.
Loading history...
37
        'ShareTokens' => ShareToken::class,
38
    );
39
40
    /**
41
     * @var array
42
     */
43
    private static $allowed_actions = array(
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
44
        'MakeShareDraftLink'
45
    );
46
47
    /**
48
     * @return string
49
     */
50
    public function ShareTokenLink()
51
    {
52
        $shareToken = $this->getNewShareToken();
53
54
        return Controller::join_links(
55
            Director::absoluteBaseURL(),
56
            'preview',
57
            $this->generateKey($shareToken->Token),
58
            $shareToken->Token
59
        );
60
    }
61
62
    /**
63
     * @return ShareToken
64
     */
65
    protected function getNewShareToken()
66
    {
67
        if (!$this->owner->ShareTokenSalt) {
68
            $this->owner->ShareTokenSalt = $this->getNewToken();
69
            $this->owner->write();
70
        }
71
72
        $found = null;
73
        $token = null;
74
        $tries = 1;
75
        $limit = 5;
76
77
        while (!$found && ($tries++ < $limit)) {
78
            $token = $this->getNewToken();
79
80
            $found = ShareToken::get()->filter(array(
81
                "Token" => $token,
82
                "PageID" => $this->owner->ID,
83
            ))->first();
84
        }
85
86
        $config = Config::forClass(__CLASS__);
87
88
        $validForDays = $config->valid_for_days;
89
90
        $token = ShareToken::create(array(
91
            "Token" => $token,
92
            "ValidForDays" => $validForDays,
93
            "PageID" => $this->owner->ID,
94
        ));
95
96
        $token->write();
97
98
        return $token;
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    protected function getNewToken()
105
    {
106
        $generator = new RandomGenerator();
107
108
        return substr($generator->randomToken('sha256'), 0, 16);
109
    }
110
111
    /**
112
     * @param string $salt
113
     *
114
     * @return string
115
     */
116
    public function generateKey($salt)
117
    {
118
        return hash_pbkdf2('sha256', $salt, $this->owner->SharedTokenSalt, 1000, 16);
0 ignored issues
show
Bug introduced by
The call to hash_pbkdf2() has too few arguments starting with raw_output. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
        return /** @scrutinizer ignore-call */ hash_pbkdf2('sha256', $salt, $this->owner->SharedTokenSalt, 1000, 16);

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
119
    }
120
121
    /**
122
     * @return string
123
     */
124
    public function getShareDraftLinkAction()
125
    {
126
        return $this->owner->Link('MakeShareDraftLink');
127
    }
128
}
129