]> git.immae.eu Git - github/wallabag/wallabag.git/blob - src/Wallabag/CoreBundle/GuzzleSiteAuthenticator/GrabySiteConfigBuilder.php
Add ability to match many domains for credentials
[github/wallabag/wallabag.git] / src / Wallabag / CoreBundle / GuzzleSiteAuthenticator / GrabySiteConfigBuilder.php
1 <?php
2
3 namespace Wallabag\CoreBundle\GuzzleSiteAuthenticator;
4
5 use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfig;
6 use BD\GuzzleSiteAuthenticator\SiteConfig\SiteConfigBuilder;
7 use Graby\SiteConfig\ConfigBuilder;
8 use Psr\Log\LoggerInterface;
9 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
10 use Wallabag\CoreBundle\Repository\SiteCredentialRepository;
11 use Wallabag\UserBundle\Entity\User;
12
13 class GrabySiteConfigBuilder implements SiteConfigBuilder
14 {
15 /**
16 * @var ConfigBuilder
17 */
18 private $grabyConfigBuilder;
19
20 /**
21 * @var SiteCredentialRepository
22 */
23 private $credentialRepository;
24
25 /**
26 * @var LoggerInterface
27 */
28 private $logger;
29
30 /**
31 * @var User|null
32 */
33 private $currentUser;
34
35 /**
36 * GrabySiteConfigBuilder constructor.
37 *
38 * @param ConfigBuilder $grabyConfigBuilder
39 * @param TokenStorage $token
40 * @param SiteCredentialRepository $credentialRepository
41 * @param LoggerInterface $logger
42 */
43 public function __construct(ConfigBuilder $grabyConfigBuilder, TokenStorage $token, SiteCredentialRepository $credentialRepository, LoggerInterface $logger)
44 {
45 $this->grabyConfigBuilder = $grabyConfigBuilder;
46 $this->credentialRepository = $credentialRepository;
47 $this->logger = $logger;
48
49 if ($token->getToken()) {
50 $this->currentUser = $token->getToken()->getUser();
51 }
52 }
53
54 /**
55 * {@inheritdoc}
56 */
57 public function buildForHost($host)
58 {
59 // required by credentials below
60 $host = strtolower($host);
61 if ('www.' === substr($host, 0, 4)) {
62 $host = substr($host, 4);
63 }
64
65 $credentials = null;
66 if ($this->currentUser) {
67 $hosts = [$host];
68 // will try to see for a host without the first subdomain (fr.example.org & .example.org)
69 $split = explode('.', $host);
70
71 if (\count($split) > 1) {
72 // remove first subdomain
73 array_shift($split);
74 $hosts[] = '.' . implode('.', $split);
75 }
76
77 $credentials = $this->credentialRepository->findOneByHostsAndUser($hosts, $this->currentUser->getId());
78 }
79
80 if (null === $credentials) {
81 $this->logger->debug('Auth: no credentials available for host.', ['host' => $host]);
82
83 return false;
84 }
85
86 $config = $this->grabyConfigBuilder->buildForHost($host);
87 $parameters = [
88 'host' => $host,
89 'requiresLogin' => $config->requires_login ?: false,
90 'loginUri' => $config->login_uri ?: null,
91 'usernameField' => $config->login_username_field ?: null,
92 'passwordField' => $config->login_password_field ?: null,
93 'extraFields' => $this->processExtraFields($config->login_extra_fields),
94 'notLoggedInXpath' => $config->not_logged_in_xpath ?: null,
95 'username' => $credentials['username'],
96 'password' => $credentials['password'],
97 ];
98
99 $config = new SiteConfig($parameters);
100
101 // do not leak usernames and passwords in log
102 $parameters['username'] = '**masked**';
103 $parameters['password'] = '**masked**';
104
105 $this->logger->debug('Auth: add parameters.', ['host' => $host, 'parameters' => $parameters]);
106
107 return $config;
108 }
109
110 /**
111 * Processes login_extra_fields config, transforming an '=' separated array of strings
112 * into a key/value array.
113 *
114 * @param array|mixed $extraFieldsStrings
115 *
116 * @return array
117 */
118 protected function processExtraFields($extraFieldsStrings)
119 {
120 if (!\is_array($extraFieldsStrings)) {
121 return [];
122 }
123
124 $extraFields = [];
125 foreach ($extraFieldsStrings as $extraField) {
126 if (false === strpos($extraField, '=')) {
127 continue;
128 }
129
130 list($fieldName, $fieldValue) = explode('=', $extraField, 2);
131 $extraFields[$fieldName] = $fieldValue;
132 }
133
134 return $extraFields;
135 }
136 }