1
0

Initial commit for push service

This commit is contained in:
2020-07-21 22:55:29 +02:00
commit 604cdd04b0
14 changed files with 583 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
package de.pushservice.server;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class PushServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(PushServiceApplication.class);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PushServiceApplication.class);
}
}

View File

@@ -0,0 +1,38 @@
package de.pushservice.server.controller;
import de.pushservice.client.ResponseReason;
import de.pushservice.client.dto.NotificationRequestDto;
import de.pushservice.server.decorator.MessageDecorator;
import de.pushservice.server.decorator.SubscriptionDecorator;
import nl.martijndwars.webpush.Notification;
import nl.martijndwars.webpush.PushService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class PushServiceController {
private static final Logger LOGGER = LoggerFactory.getLogger(PushServiceController.class);
@PostMapping
public ResponseEntity notify(NotificationRequestDto notificationRequestDto) {
try {
final SubscriptionDecorator subscription = SubscriptionDecorator
.fromDto(notificationRequestDto.getSubscriptionDto());
final Notification notification = MessageDecorator.fromDto(notificationRequestDto.getMessageDto())
.toNotification(subscription);
final PushService extPushService = new PushService();
extPushService.send(notification);
return ResponseReason.OK.toResponseEntity();
}
catch(Exception e) {
LOGGER.error("Error while sending notification!", e);
return ResponseReason.UNKNOWN_ERROR.toResponseEntity();
}
}
}

View File

@@ -0,0 +1,36 @@
package de.pushservice.server.decorator;
import de.pushservice.client.dto.MessageDto;
import nl.martijndwars.webpush.Notification;
import nl.martijndwars.webpush.Urgency;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.spec.InvalidKeySpecException;
public class MessageDecorator {
private MessageDto dto;
private MessageDecorator(MessageDto dto) {
this.dto = dto;
}
public static final MessageDecorator fromDto(MessageDto dto) {
return new MessageDecorator(dto);
}
public Notification toNotification(SubscriptionDecorator subscription) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
return Notification.builder()
.endpoint(subscription.getEndpoint())
.userPublicKey(subscription.getUserPublicKey())
.userAuth(subscription.getAuthAsBytes())
.payload(dto.getPayload())
.urgency(getExtUrgency())
.topic(dto.getTopic())
.build();
}
private Urgency getExtUrgency() {
return Urgency.valueOf(dto.getUrgency().name());
}
}

View File

@@ -0,0 +1,48 @@
package de.pushservice.server.decorator;
import de.pushservice.client.dto.SubscriptionDto;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
public class SubscriptionDecorator {
private SubscriptionDto dto;
private SubscriptionDecorator(SubscriptionDto dto) {
this.dto = dto;
}
public static final SubscriptionDecorator fromDto(SubscriptionDto dto) {
return new SubscriptionDecorator(dto);
}
byte[] getAuthAsBytes() {
return Base64.getDecoder().decode(dto.getAuth());
}
private byte[] getKeyAsBytes() {
return Base64.getDecoder().decode(dto.getKey());
}
PublicKey getUserPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException {
KeyFactory kf = KeyFactory.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec("secp256r1");
ECPoint point = ecSpec.getCurve().decodePoint(getKeyAsBytes());
ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, ecSpec);
return kf.generatePublic(pubSpec);
}
String getEndpoint() {
return dto.getEndpoint();
}
}