Skip to content

Commit 35d4fd2

Browse files
Merge pull request #17 from stephanediondev/subscription
Refactoring subscriptions
2 parents eb52c04 + 41249ad commit 35d4fd2

19 files changed

+705
-329
lines changed

.env.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ KERNEL_CLASS='App\Kernel'
33
APP_SECRET='$ecretf0rt3st'
44
SYMFONY_DEPRECATIONS_HELPER=999999
55
PANTHER_APP_ENV=panther
6+
VAPID_PUBLIC_KEY='test'
7+
VAPID_PRIVATE_KEY='test'
39.6 KB
Loading
36 KB
Loading

src/Command/SendNotificationsCommand.php

Lines changed: 54 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -53,59 +53,61 @@ protected function execute(InputInterface $input, OutputInterface $output): int
5353

5454
foreach ($notifications as $notification) {
5555
foreach ($subscriptions as $subscription) {
56-
switch ($subscription->getType()) {
57-
case AppSubscriptionModel::TYPE_PUSH:
58-
$publicKey = $subscription->getPublicKey();
59-
$authenticationSecret = $subscription->getAuthenticationSecret();
60-
$contentEncoding = $subscription->getContentEncoding();
61-
62-
if ($publicKey && $authenticationSecret && $contentEncoding) {
63-
$payload = [
64-
'tag' => uniqid('', true),
65-
'title' => $notification->getTitle(),
66-
'body' => $notification->getBody(),
67-
'icon' => $notification->getIcon(),
68-
];
69-
70-
$subscription = Subscription::create([
71-
'endpoint' => $subscription->getEndpoint(),
72-
'publicKey' => $publicKey,
73-
'authToken' => $authenticationSecret,
74-
'contentEncoding' => $contentEncoding,
75-
]);
76-
77-
$webPush->queueNotification($subscription, json_encode($payload));
78-
}
79-
break;
80-
81-
case AppSubscriptionModel::TYPE_SLACK:
82-
try {
83-
$options = [
84-
'json' => [
85-
'text' => $notification->getTitle()."\r\n".$notification->getBody(),
86-
],
87-
];
88-
$this->client->request('POST', $subscription->getEndpoint(), $options);
89-
} catch (TransportException $e) {
90-
$output->writeln('<error>Message failed to sent for subscription '.$subscription->getEndpoint().': '.$e->getMessage().'</error>');
91-
}
92-
break;
93-
94-
case AppSubscriptionModel::TYPE_TEAMS:
95-
try {
96-
$options = [
97-
'json' => [
98-
'@context' => 'https://schema.org/extensions',
99-
'@type' => 'MessageCard',
56+
if (true === in_array($notification->getType(), $subscription->getNotifications())) {
57+
switch ($subscription->getType()) {
58+
case AppSubscriptionModel::TYPE_PUSH:
59+
$publicKey = $subscription->getPublicKey();
60+
$authenticationSecret = $subscription->getAuthenticationSecret();
61+
$contentEncoding = $subscription->getContentEncoding();
62+
63+
if ($publicKey && $authenticationSecret && $contentEncoding) {
64+
$payload = [
65+
'tag' => uniqid('', true),
10066
'title' => $notification->getTitle(),
101-
'text' => $notification->getBody(),
102-
],
103-
];
104-
$this->client->request('POST', $subscription->getEndpoint(), $options);
105-
} catch (TransportException $e) {
106-
$output->writeln('<error>Message failed to sent for subscription '.$subscription->getEndpoint().': '.$e->getMessage().'</error>');
107-
}
108-
break;
67+
'body' => $notification->getBody(),
68+
'icon' => $notification->getIcon(),
69+
];
70+
71+
$subscription = Subscription::create([
72+
'endpoint' => $subscription->getEndpoint(),
73+
'publicKey' => $publicKey,
74+
'authToken' => $authenticationSecret,
75+
'contentEncoding' => $contentEncoding,
76+
]);
77+
78+
$webPush->queueNotification($subscription, json_encode($payload));
79+
}
80+
break;
81+
82+
case AppSubscriptionModel::TYPE_SLACK:
83+
try {
84+
$options = [
85+
'json' => [
86+
'text' => $notification->getTitle()."\r\n".$notification->getBody(),
87+
],
88+
];
89+
$this->client->request('POST', $subscription->getEndpoint(), $options);
90+
} catch (TransportException $e) {
91+
$output->writeln('<error>Message failed to sent for subscription '.$subscription->getEndpoint().': '.$e->getMessage().'</error>');
92+
}
93+
break;
94+
95+
case AppSubscriptionModel::TYPE_TEAMS:
96+
try {
97+
$options = [
98+
'json' => [
99+
'@context' => 'https://schema.org/extensions',
100+
'@type' => 'MessageCard',
101+
'title' => $notification->getTitle(),
102+
'text' => $notification->getBody(),
103+
],
104+
];
105+
$this->client->request('POST', $subscription->getEndpoint(), $options);
106+
} catch (TransportException $e) {
107+
$output->writeln('<error>Message failed to sent for subscription '.$subscription->getEndpoint().': '.$e->getMessage().'</error>');
108+
}
109+
break;
110+
}
109111
}
110112
}
111113
}

src/Controller/AppSubscriptionsController.php

Lines changed: 92 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
namespace App\Controller;
44

55
use App\Controller\AbstractAppController;
6+
use App\Exception\CallException;
7+
use App\Form\Type\AppSubscriptionType;
68
use App\Model\CallRequestModel;
79
use App\Manager\AppSubscriptionManager;
810
use App\Manager\AppNotificationManager;
11+
use App\Model\AppNotificationModel;
912
use App\Model\AppSubscriptionModel;
1013
use DeviceDetector\DeviceDetector;
1114
use Minishlink\WebPush\WebPush;
@@ -16,31 +19,29 @@
1619
use Symfony\Component\HttpFoundation\JsonResponse;
1720
use Symfony\Component\Security\Core\Security;
1821
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
22+
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
1923

2024
/**
2125
* @Route("/admin")
2226
*/
2327
class AppSubscriptionsController extends AbstractAppController
2428
{
25-
public function __construct(AppSubscriptionManager $appSubscriptionManager, AppNotificationManager $appNotificationManager, Security $security)
29+
public function __construct(AppSubscriptionManager $appSubscriptionManager, AppNotificationManager $appNotificationManager, Security $security, string $vapidPublicKey, string $vapidPrivateKey)
2630
{
2731
$this->appSubscriptionManager = $appSubscriptionManager;
2832
$this->appNotificationManager = $appNotificationManager;
2933
$this->user = $security->getUser();
34+
$this->vapidPublicKey = $vapidPublicKey;
35+
$this->vapidPrivateKey = $vapidPrivateKey;
3036
}
3137

3238
/**
3339
* @Route("/subscriptions", name="app_subscriptions")
3440
*/
35-
public function index(Request $request, string $vapidPublicKey, string $vapidPrivateKey): Response
41+
public function index(Request $request): Response
3642
{
3743
$this->denyAccessUnlessGranted('APP_SUBSCRIPTIONS', 'global');
3844

39-
if ('' == $vapidPublicKey || '' == $vapidPrivateKey) {
40-
$this->addFlash('warning', 'Run bin/console app:generate-vapid');
41-
$this->addFlash('warning', 'Edit VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY in .env file');
42-
}
43-
4445
if (false === $this->appNotificationManager->infoFileExists()) {
4546
$this->addFlash('warning', 'Add to cron */5 * * * * cd '.str_replace('/public', '', $request->getBasePath()).' && bin/console app:send-notifications');
4647
}
@@ -52,48 +53,101 @@ public function index(Request $request, string $vapidPublicKey, string $vapidPri
5253

5354
return $this->renderAbstract($request, 'Modules/subscription/subscription_index.html.twig', [
5455
'subscriptions' => $subscriptions,
55-
'applicationServerKey' => $vapidPublicKey,
56+
'applicationServerKey' => $this->vapidPublicKey,
5657
]);
5758
}
5859

5960
/**
60-
* @Route("/subscriptions/create", name="app_subscriptions_create")
61+
* @Route("/subscriptions/create/{type}", name="app_subscriptions_create")
6162
*/
62-
public function create(Request $request): JsonResponse
63+
public function create(Request $request, string $type): Response
6364
{
6465
$this->denyAccessUnlessGranted('APP_SUBSCRIPTIONS', 'global');
6566

66-
$json = [];
67+
if (false === in_array($type, AppSubscriptionModel::getTypes())) {
68+
throw new AccessDeniedException();
69+
}
70+
71+
if (AppSubscriptionModel::TYPE_PUSH == $type) {
72+
if ('' == $this->vapidPublicKey || '' == $this->vapidPrivateKey) {
73+
$this->addFlash('warning', 'Run bin/console app:generate-vapid');
74+
$this->addFlash('warning', 'Edit VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY in .env file');
75+
76+
throw new AccessDeniedException();
77+
}
78+
}
79+
80+
$dd = new DeviceDetector($request->headers->get('User-Agent'));
81+
$dd->skipBotDetection();
82+
$dd->parse();
6783

68-
if ($content = $request->getContent()) {
69-
$content = json_decode($content, true);
84+
$client = $dd->getClient();
85+
$os = $dd->getOs();
7086

71-
$dd = new DeviceDetector($request->headers->get('User-Agent'));
72-
$dd->skipBotDetection();
73-
$dd->parse();
87+
$subscription = new AppSubscriptionModel();
88+
$subscription->setUserId($this->user->getId());
89+
$subscription->setType($type);
90+
$subscription->setIp($request->getClientIp());
91+
$subscription->setOs($os ? $os['name'].' '.$os['version'] : false);
92+
$subscription->setClient($client ? $client['name'].' '.$client['version'] : false);
93+
$subscription->setNotifications(AppNotificationModel::getTypes());
7494

75-
$client = $dd->getClient();
76-
$os = $dd->getOs();
95+
$form = $this->createForm(AppSubscriptionType::class, $subscription, ['type' => $type]);
7796

78-
$subscription = new AppSubscriptionModel();
79-
$subscription->setUserId($this->user->getId());
80-
$subscription->setType($content['type']);
81-
$subscription->setEndpoint($content['endpoint']);
82-
if (AppSubscriptionModel::TYPE_PUSH == $content['type']) {
83-
$subscription->setPublicKey($content['public_key']);
84-
$subscription->setAuthenticationSecret($content['authentication_secret']);
85-
$subscription->setContentEncoding($content['content_encoding']);
97+
$form->handleRequest($request);
98+
99+
if ($form->isSubmitted() && $form->isValid()) {
100+
try {
101+
$callResponse = $this->appSubscriptionManager->send($subscription);
102+
103+
$this->addFlash('info', json_encode($callResponse->getContent()));
104+
105+
return $this->redirectToRoute('app_subscriptions');
106+
} catch (CallException $e) {
107+
$this->addFlash('danger', $e->getMessage());
86108
}
87-
$subscription->setIp($request->getClientIp());
88-
$subscription->setOs($os ? $os['name'].' '.$os['version'] : false);
89-
$subscription->setClient($client ? $client['name'].' '.$client['version'] : false);
109+
}
110+
111+
return $this->renderAbstract($request, 'Modules/subscription/subscription_create.html.twig', [
112+
'form' => $form->createView(),
113+
'type' => $type,
114+
'applicationServerKey' => $this->vapidPublicKey,
115+
]);
116+
}
117+
118+
/**
119+
* @Route("/subscriptions/{id}/update", name="app_subscriptions_update")
120+
*/
121+
public function update(Request $request, string $id): Response
122+
{
123+
$this->denyAccessUnlessGranted('APP_SUBSCRIPTIONS', 'global');
90124

91-
$callResponse = $this->appSubscriptionManager->send($subscription);
125+
$subscription = $this->appSubscriptionManager->getById($id);
92126

93-
return new JsonResponse(json_encode($callResponse->getContent()), JsonResponse::HTTP_OK);
127+
if (null === $subscription) {
128+
throw new NotFoundHttpException();
94129
}
95130

96-
return new JsonResponse($json, JsonResponse::HTTP_OK);
131+
$form = $this->createForm(AppSubscriptionType::class, $subscription, ['type' => $subscription->getType(), 'context' => 'update']);
132+
133+
$form->handleRequest($request);
134+
135+
if ($form->isSubmitted() && $form->isValid()) {
136+
try {
137+
$callResponse = $this->appSubscriptionManager->send($subscription);
138+
139+
$this->addFlash('info', json_encode($callResponse->getContent()));
140+
141+
return $this->redirectToRoute('app_subscriptions');
142+
} catch (CallException $e) {
143+
$this->addFlash('danger', $e->getMessage());
144+
}
145+
}
146+
147+
return $this->renderAbstract($request, 'Modules/subscription/subscription_update.html.twig', [
148+
'subscription' => $subscription,
149+
'form' => $form->createView(),
150+
]);
97151
}
98152

99153
/**
@@ -119,7 +173,7 @@ public function delete(Request $request, string $id): Response
119173
/**
120174
* @Route("/subscriptions/{id}/test", name="app_subscriptions_test")
121175
*/
122-
public function test(Request $request, string $id, string $vapidPublicKey, string $vapidPrivateKey): JsonResponse
176+
public function test(Request $request, string $id): JsonResponse
123177
{
124178
$this->denyAccessUnlessGranted('APP_SUBSCRIPTIONS', 'global');
125179

@@ -129,15 +183,17 @@ public function test(Request $request, string $id, string $vapidPublicKey, strin
129183
throw new NotFoundHttpException();
130184
}
131185

186+
$this->clusterHealth = $this->elasticsearchClusterManager->getClusterHealth();
187+
132188
$json = [];
133189

134190
switch ($subscription->getType()) {
135191
case AppSubscriptionModel::TYPE_PUSH:
136192
$apiKeys = [
137193
'VAPID' => [
138194
'subject' => 'https://github.com/stephanediondev/elasticsearch-admin',
139-
'publicKey' => $vapidPublicKey,
140-
'privateKey' => $vapidPrivateKey,
195+
'publicKey' => $this->vapidPublicKey,
196+
'privateKey' => $this->vapidPrivateKey,
141197
],
142198
];
143199

@@ -150,7 +206,7 @@ public function test(Request $request, string $id, string $vapidPublicKey, strin
150206
if ($publicKey && $authenticationSecret && $contentEncoding) {
151207
$payload = [
152208
'tag' => uniqid('', true),
153-
'title' => 'test',
209+
'title' => $this->clusterHealth['cluster_name'].': test',
154210
'body' => 'test',
155211
'icon' => 'favicon-green-144.png',
156212
];

src/Controller/ElasticsearchRepositoryController.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public function create(Request $request, string $type): Response
5353
{
5454
$this->denyAccessUnlessGranted('REPOSITORIES_CREATE', 'global');
5555

56+
if (false === in_array($type, ElasticsearchRepositoryModel::getTypes())) {
57+
throw new AccessDeniedException();
58+
}
59+
5660
if ('s3' == $type && false === $this->callManager->hasPlugin('repository-s3')) {
5761
throw new AccessDeniedException();
5862
}

0 commit comments

Comments
 (0)