Passed
Push — master ( 62435f...6c378b )
by Bence
04:18
created

Storage::GenerateBlobSas()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 49
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 34
nc 4
nop 3
dl 0
loc 49
ccs 0
cts 37
cp 0
crap 12
rs 9.2258
c 0
b 0
f 0
1
<?php
2
3
namespace CSFCloud\Azure;
4
5
use CSFCloud\Shell\CommandRunner;
6
7
class Storage {
8
9
    private $connection_string;
10
    private $container;
11
12
    private $account_name;
13
    private $account_key;
14
15
    private $exec;
16
17
    public function __construct(string $container, string $connection_string) {
18
        $this->exec = new CommandRunner();
19
20
        $this->connection_string = $connection_string;
21
        $this->container = $container;
22
23
        $dt = explode(";", $this->connection_string);
24
        foreach ($dt as $pair) {
25
            $pdt = explode("=", $pair);
26
            if ($pdt[0] == "AccountName") {
27
                $this->account_name = str_ireplace("AccountName=", "", $pdt[1]);
28
            } else if ($pdt[0] == "AccountKey") {
29
                $this->account_key = str_ireplace("AccountKey=", "", $pdt[1]);
30
            }
31
        }
32
    }
33
34
    protected function run($cmd) : string {
35
        $logfile = $this->exec->run(CommandRunner::COMMAND_SYNC, __DIR__, $cmd, true);
36
        $log = $logfile->getText();
37
        $logfile->delete();
38
        return $log;
39
    }
40
41
    public function getContainer() : string {
42
        return $this->container;
43
    }
44
45
    public function getAccountName() : string {
46
        $this->account_name;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
47
    }
48
49
    public function uploadToBlob(string $file, string $name, string $content_type = null) {
50
        if (!file_exists($file) || !is_file($file)) {
51
            throw new Exception("Invalid file");
0 ignored issues
show
Bug introduced by
The type CSFCloud\Azure\Exception was not found. Did you mean Exception? If so, make sure to prefix the type with \.
Loading history...
52
        }
53
54
        $cmd = "az storage blob upload";
55
56
        $cmd .= " -c " . escapeshellarg($this->container);
57
        $cmd .= " -f " . escapeshellarg($file);
58
        $cmd .= " -n " . escapeshellarg($name);
59
60
        if ($content_type != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $content_type of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
61
            $cmd .= " --content-type " . escapeshellarg($content_type);
62
        } else {
63
            $cmd .= " --content-type " . escapeshellarg(mime_content_type($file));
64
        }
65
66
        $cmd .= " --connection-string " . escapeshellarg($this->connection_string);
67
68
        $log = $this->run($cmd);
69
70
        return $log;
71
    }
72
73
    public function GenerateBlobSas(string $name, int $expire = 5 * 60 * 60, string $ip = null) : string {
74
        $signedPermissions = "r";
75
        //$signedStart = gmdate("Y-m-d\TH:i\Z", time());
76
        $signedExpiry = gmdate("Y-m-d\TH:i\Z", time() + $expire);
77
        $signedProtocol = "https";
78
        $signedVersion = "2017-07-29";//"2016-05-31";
79
80
        $parameters = array();
81
        $parameters[] = $signedPermissions;
82
        $parameters[] = ""; // signedStart;
83
        $parameters[] = $signedExpiry;
84
        $parameters[] = "/blob/" . $this->account_name . "/" . $this->container . "/" . $name;
85
        $parameters[] = ""; // signedIdentifier
86
        if ($ip == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $ip of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
87
            $parameters[] = "";
88
        } else {
89
            $parameters[] = $ip;
90
        }
91
        $parameters[] = $signedProtocol;
92
        $parameters[] = $signedVersion;
93
        $parameters[] = ""; // cacheControl
94
        $parameters[] = ""; // contentDisposition
95
        $parameters[] = ""; // contentEncoding
96
        $parameters[] = ""; // contentLanguage
97
        $parameters[] = ""; // contentType
98
99
        $stringToSign = utf8_encode(implode("\n", $parameters));
100
        $decodedAccountKey = base64_decode($this->account_key);
101
        $signature = hash_hmac("sha256", $stringToSign, $decodedAccountKey, true);
102
        $sig = urlencode(base64_encode($signature));
103
104
        $sas  = 'sv=' . $signedVersion;
105
        $sas .= '&sr=' . "b";
106
        //$sas .= $buildOptQueryStr($cacheControl, '&rscc=');
107
        //$sas .= $buildOptQueryStr($contentDisposition, '&rscd=');
108
        //$sas .= $buildOptQueryStr($contentEncoding, '&rsce=');
109
        //$sas .= $buildOptQueryStr($contentLanguage, '&rscl=');
110
        //$sas .= $buildOptQueryStr($contentType, '&rsct=');
111
        //$sas .= $buildOptQueryStr($signedStart, '&st=');
112
        $sas .= '&se=' . $signedExpiry;
113
        $sas .= '&sp=' . $signedPermissions;
114
        if ($ip != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $ip of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
115
            $sas .= '&sip=' . $ip;
116
        }
117
        $sas .= '&spr=' . $signedProtocol;
118
        //$sas .= $buildOptQueryStr($signedIdentifier, '&si=');
119
        $sas .= '&sig=' . $sig;
120
121
        return $sas;
122
    }
123
124
    public function getBlobUrl(string $name) {
125
        $url = "https://" . $this->account_name . ".blob.core.windows.net/" . $this->container . "/" . $name;
126
        return $url;
127
    }
128
129
}