diff options
Diffstat (limited to 'src/Wallabag/UserBundle')
3 files changed, 79 insertions, 7 deletions
diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index ed6ce331..aba76ca7 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php | |||
@@ -6,6 +6,7 @@ use Doctrine\Common\Collections\ArrayCollection; | |||
6 | use Doctrine\ORM\Mapping as ORM; | 6 | use Doctrine\ORM\Mapping as ORM; |
7 | use JMS\Serializer\Annotation\Groups; | 7 | use JMS\Serializer\Annotation\Groups; |
8 | use JMS\Serializer\Annotation\XmlRoot; | 8 | use JMS\Serializer\Annotation\XmlRoot; |
9 | use JMS\Serializer\Annotation\Accessor; | ||
9 | use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; | 10 | use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; |
10 | use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; | 11 | use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; |
11 | use FOS\UserBundle\Model\User as BaseUser; | 12 | use FOS\UserBundle\Model\User as BaseUser; |
@@ -36,7 +37,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
36 | * @ORM\Id | 37 | * @ORM\Id |
37 | * @ORM\GeneratedValue(strategy="AUTO") | 38 | * @ORM\GeneratedValue(strategy="AUTO") |
38 | * | 39 | * |
39 | * @Groups({"user_api"}) | 40 | * @Groups({"user_api", "user_api_with_client"}) |
40 | */ | 41 | */ |
41 | protected $id; | 42 | protected $id; |
42 | 43 | ||
@@ -45,21 +46,21 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
45 | * | 46 | * |
46 | * @ORM\Column(name="name", type="text", nullable=true) | 47 | * @ORM\Column(name="name", type="text", nullable=true) |
47 | * | 48 | * |
48 | * @Groups({"user_api"}) | 49 | * @Groups({"user_api", "user_api_with_client"}) |
49 | */ | 50 | */ |
50 | protected $name; | 51 | protected $name; |
51 | 52 | ||
52 | /** | 53 | /** |
53 | * @var string | 54 | * @var string |
54 | * | 55 | * |
55 | * @Groups({"user_api"}) | 56 | * @Groups({"user_api", "user_api_with_client"}) |
56 | */ | 57 | */ |
57 | protected $username; | 58 | protected $username; |
58 | 59 | ||
59 | /** | 60 | /** |
60 | * @var string | 61 | * @var string |
61 | * | 62 | * |
62 | * @Groups({"user_api"}) | 63 | * @Groups({"user_api", "user_api_with_client"}) |
63 | */ | 64 | */ |
64 | protected $email; | 65 | protected $email; |
65 | 66 | ||
@@ -68,7 +69,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
68 | * | 69 | * |
69 | * @ORM\Column(name="created_at", type="datetime") | 70 | * @ORM\Column(name="created_at", type="datetime") |
70 | * | 71 | * |
71 | * @Groups({"user_api"}) | 72 | * @Groups({"user_api", "user_api_with_client"}) |
72 | */ | 73 | */ |
73 | protected $createdAt; | 74 | protected $createdAt; |
74 | 75 | ||
@@ -77,7 +78,7 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
77 | * | 78 | * |
78 | * @ORM\Column(name="updated_at", type="datetime") | 79 | * @ORM\Column(name="updated_at", type="datetime") |
79 | * | 80 | * |
80 | * @Groups({"user_api"}) | 81 | * @Groups({"user_api", "user_api_with_client"}) |
81 | */ | 82 | */ |
82 | protected $updatedAt; | 83 | protected $updatedAt; |
83 | 84 | ||
@@ -97,7 +98,8 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
97 | private $authCode; | 98 | private $authCode; |
98 | 99 | ||
99 | /** | 100 | /** |
100 | * @var bool Enabled yes/no | 101 | * @var bool |
102 | * | ||
101 | * @ORM\Column(type="boolean") | 103 | * @ORM\Column(type="boolean") |
102 | */ | 104 | */ |
103 | private $twoFactorAuthentication = false; | 105 | private $twoFactorAuthentication = false; |
@@ -108,10 +110,20 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
108 | private $trusted; | 110 | private $trusted; |
109 | 111 | ||
110 | /** | 112 | /** |
113 | * @var ArrayCollection | ||
114 | * | ||
111 | * @ORM\OneToMany(targetEntity="Wallabag\ApiBundle\Entity\Client", mappedBy="user", cascade={"remove"}) | 115 | * @ORM\OneToMany(targetEntity="Wallabag\ApiBundle\Entity\Client", mappedBy="user", cascade={"remove"}) |
112 | */ | 116 | */ |
113 | protected $clients; | 117 | protected $clients; |
114 | 118 | ||
119 | /** | ||
120 | * @see getFirstClient() below | ||
121 | * | ||
122 | * @Groups({"user_api_with_client"}) | ||
123 | * @Accessor(getter="getFirstClient") | ||
124 | */ | ||
125 | protected $default_client; | ||
126 | |||
115 | public function __construct() | 127 | public function __construct() |
116 | { | 128 | { |
117 | parent::__construct(); | 129 | parent::__construct(); |
@@ -288,4 +300,16 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf | |||
288 | { | 300 | { |
289 | return $this->clients; | 301 | return $this->clients; |
290 | } | 302 | } |
303 | |||
304 | /** | ||
305 | * Only used by the API when creating a new user it'll also return the first client (which was also created at the same time). | ||
306 | * | ||
307 | * @return Client | ||
308 | */ | ||
309 | public function getFirstClient() | ||
310 | { | ||
311 | if (!empty($this->clients)) { | ||
312 | return $this->clients->first(); | ||
313 | } | ||
314 | } | ||
291 | } | 315 | } |
diff --git a/src/Wallabag/UserBundle/EventListener/AuthenticationFailureListener.php b/src/Wallabag/UserBundle/EventListener/AuthenticationFailureListener.php new file mode 100644 index 00000000..10f13233 --- /dev/null +++ b/src/Wallabag/UserBundle/EventListener/AuthenticationFailureListener.php | |||
@@ -0,0 +1,40 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\UserBundle\EventListener; | ||
4 | |||
5 | use Psr\Log\LoggerInterface; | ||
6 | use Symfony\Component\EventDispatcher\EventSubscriberInterface; | ||
7 | use Symfony\Component\HttpFoundation\RequestStack; | ||
8 | use Symfony\Component\Security\Core\AuthenticationEvents; | ||
9 | |||
10 | class AuthenticationFailureListener implements EventSubscriberInterface | ||
11 | { | ||
12 | private $requestStack; | ||
13 | private $logger; | ||
14 | |||
15 | public function __construct(RequestStack $requestStack, LoggerInterface $logger) | ||
16 | { | ||
17 | $this->requestStack = $requestStack; | ||
18 | $this->logger = $logger; | ||
19 | } | ||
20 | |||
21 | /** | ||
22 | * {@inheritdoc} | ||
23 | */ | ||
24 | public static function getSubscribedEvents() | ||
25 | { | ||
26 | return [ | ||
27 | AuthenticationEvents::AUTHENTICATION_FAILURE => 'onAuthenticationFailure', | ||
28 | ]; | ||
29 | } | ||
30 | |||
31 | /** | ||
32 | * On failure, add a custom error in log so server admin can configure fail2ban to block IP from people who try to login too much. | ||
33 | */ | ||
34 | public function onAuthenticationFailure() | ||
35 | { | ||
36 | $request = $this->requestStack->getMasterRequest(); | ||
37 | |||
38 | $this->logger->error('Authentication failure for user "'.$request->request->get('_username').'", from IP "'.$request->getClientIp().'", with UA: "'.$request->server->get('HTTP_USER_AGENT').'".'); | ||
39 | } | ||
40 | } | ||
diff --git a/src/Wallabag/UserBundle/Resources/config/services.yml b/src/Wallabag/UserBundle/Resources/config/services.yml index bfba6010..d3925de3 100644 --- a/src/Wallabag/UserBundle/Resources/config/services.yml +++ b/src/Wallabag/UserBundle/Resources/config/services.yml | |||
@@ -35,3 +35,11 @@ services: | |||
35 | - "%wallabag_core.list_mode%" | 35 | - "%wallabag_core.list_mode%" |
36 | tags: | 36 | tags: |
37 | - { name: kernel.event_subscriber } | 37 | - { name: kernel.event_subscriber } |
38 | |||
39 | wallabag_user.listener.authentication_failure_event_listener: | ||
40 | class: Wallabag\UserBundle\EventListener\AuthenticationFailureListener | ||
41 | arguments: | ||
42 | - "@request_stack" | ||
43 | - "@logger" | ||
44 | tags: | ||
45 | - { name: kernel.event_listener, event: security.authentication.failure, method: onAuthenticationFailure } | ||