Completed
Push — master ( afaf42...8ac772 )
by Raffael
20:10 queued 16:21
created

Factory::setOptions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 10
Ratio 66.67 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 10
loc 15
ccs 0
cts 13
cp 0
rs 9.7666
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 12
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2018 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\Filesystem\Storage\Adapter\Smb;
13
14
use Balloon\Filesystem\Storage\Adapter\AdapterInterface;
15
use Balloon\Filesystem\Storage\Adapter\Smb;
16
use Icewind\SMB\AnonymousAuth;
17
use Icewind\SMB\BasicAuth;
18
use Icewind\SMB\ServerFactory;
19
use InvalidArgumentException;
20
use ParagonIE\Halite\Symmetric\Crypto as Symmetric;
21
use ParagonIE\Halite\Symmetric\EncryptionKey;
22
use Psr\Log\LoggerInterface;
23
24
class Factory
25
{
26
    /**
27
     * Logger.
28
     *
29
     * @var LoggerInterface
30
     */
31
    protected $logger;
32
33
    /**
34
     * Balloon system folder.
35
     *
36
     * @var string
37
     */
38
    protected $system_folder = '.balloon';
39
40
    /**
41
     * Encryption key.
42
     *
43
     * @var EncryptionKey
44
     */
45
    protected $key;
46
47
    /**
48
     * Construct.
49
     */
50
    public function __construct(LoggerInterface $logger, EncryptionKey $key, array $config = [])
51
    {
52
        $this->logger = $logger;
53
        $this->key = $key;
54
        $this->setOptions($config);
55
    }
56
57
    /**
58
     * Create adapter.
59
     **/
60
    public function build(array $options): AdapterInterface
61
    {
62
        $options = $this->validate($options);
63
64
        $factory = new ServerFactory();
65
66
        if (!isset($options['username']) || !isset($options['password'])) {
67
            $auth = new AnonymousAuth();
68
        } else {
69
            $this->logger->debug('decrypt basic auth credentials for username ['.$options['username'].']', [
70
                'category' => get_class($this),
71
            ]);
72
73
            $options = array_merge(['workgroup' => null], $options);
74
75
            try {
76
                $decrypted = Symmetric::decrypt($options['password'], $this->key);
77
                $auth = new BasicAuth($options['username'], $options['workgroup'], $decrypted->getString());
78
            } catch (\Exception $e) {
79
                $this->logger->error('failed decrypt basic auth credentials, fallback to anonymous auth', [
80
                    'category' => get_class($this),
81
                    'exception' => $e,
82
                ]);
83
84
                $auth = new AnonymousAuth();
85
            }
86
        }
87
88
        $smb = $factory->createServer($options['host'], $auth);
89
        $share = $smb->getShare($options['share']);
90
91
        return new Smb($share, $this->logger, [
92
            Smb::OPTION_SYSTEM_FOLDER => $this->system_folder,
93
        ]);
94
    }
95
96
    /**
97
     * Validate.
98
     */
99
    public function validate(array $options): array
100
    {
101
        return Validator::validate($options);
102
    }
103
104
    /**
105
     * Set options.
106
     */
107
    protected function setOptions(array $config = []): self
108
    {
109 View Code Duplication
        foreach ($config as $option => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
            switch ($option) {
111
                case 'system_folder':
112
                    $this->{$option} = (string) $value;
113
114
                break;
115
                default:
116
                    throw new InvalidArgumentException('unknown option '.$option.' given');
117
            }
118
        }
119
120
        return $this;
121
    }
122
}
123