From 67bb34092fd0ec61f634e1074895eda76bf41de6 Mon Sep 17 00:00:00 2001 From: dkovacevic Date: Fri, 19 Feb 2021 19:31:43 +0100 Subject: [PATCH 01/14] readme --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 488cedc..b205444 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ wss://proxy.services.wire.com/await/`` ### Events that are sent as HTTP `POST` to your endpoint (Webhook or Websocket) -- `bot_request`: When bot is added to a conversation ( 1-1 conversation or a group) +- `conversation.bot_request`: When bot is added to a conversation ( 1-1 conversation or a group) ``` { "type": "conversation.bot_request", @@ -85,7 +85,7 @@ wss://proxy.services.wire.com/await/`` Your service must be available at the moment `bot_request` event is sent. It must respond with http code `200`. In case of Websocket implementation it is enough the socket is connected to the Proxy at that moment. -- `init`: If your Service responded with `200` to a `bot_request` another event is sent: `init`. +- `conversation.init`: If your Service responded with `200` to a `bot_request` another event is sent: `init`. `text` field contains the name of the conversation your bot is being added to. ``` { @@ -98,7 +98,7 @@ Your service must be available at the moment `bot_request` event is sent. It mus } ``` -- `new_text`: When text is posted in a conversation where this bot is present +- `conversation.new_text`: When text is posted in a conversation where this bot is present ``` { "type": "conversation.new_text", @@ -111,7 +111,7 @@ Your service must be available at the moment `bot_request` event is sent. It mus "text": "Hi everybody!" } ``` -- `new_image`: When an image is posted in a conversation where this bot is present +- `conversation.new_image`: When an image is posted in a conversation where this bot is present ``` { From edfd175927bf18864183d306dc76f9f9b1341dcd Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Mon, 22 Feb 2021 19:47:50 +0100 Subject: [PATCH 02/14] add possibility to load pubkey from the env --- .../com/wire/bots/roman/model/Config.java | 9 +++++++ .../bots/roman/resources/ServiceResource.java | 27 +++++++++++++++---- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 328e204..416e3be 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.wire.lithium.Configuration; +import javax.annotation.Nullable; import javax.validation.constraints.NotNull; public class Config extends Configuration { @@ -31,4 +32,12 @@ public class Config extends Configuration { @NotNull @JsonProperty public String domain; + + @Nullable + @JsonProperty + public String romanPubKeyBase64; + + @Nullable + @JsonProperty + public String pathToRomanPubKey; } diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index 7f57aa4..09de2c4 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -7,6 +7,7 @@ import com.wire.bots.roman.*; import com.wire.bots.roman.DAO.ProvidersDAO; import com.wire.bots.roman.filters.ServiceAuthorization; +import com.wire.bots.roman.model.Config; import com.wire.bots.roman.model.Provider; import com.wire.bots.roman.model.Service; import com.wire.xenon.assets.Picture; @@ -31,6 +32,9 @@ import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Base64; import java.util.UUID; @@ -243,12 +247,25 @@ public Response get(@ApiParam(hidden = true) @CookieParam(Z_ROMAN) String token, } } - private Service newService() throws IOException { - final String domain = Application.getInstance().getConfig().domain; + private String getPubKey(final Config config) throws IOException { + String pubKey; + if (config.romanPubKeyBase64 != null) { + byte[] keyBytes = Base64.getDecoder().decode(config.romanPubKeyBase64); + pubKey = new String(keyBytes, StandardCharsets.UTF_8); + } else if (config.pathToRomanPubKey != null) { + byte[] keyBytes = Files.readAllBytes(Paths.get(config.pathToRomanPubKey)); + pubKey = new String(keyBytes, StandardCharsets.UTF_8); + } else { + pubKey = Tools.getPubkey(config.domain); + } + return pubKey; + } + private Service newService() throws IOException { + final Config config = Application.getInstance().getConfig(); Service ret = new Service(); - ret.baseUrl = domain; - ret.pubkey = Tools.getPubkey(domain); + ret.baseUrl = config.domain; + ret.pubkey = getPubKey(config); ret.assets = new ArrayList<>(); Service._Asset asset1 = new Service._Asset(); @@ -360,4 +377,4 @@ static class _Result { @JsonProperty public String service; } -} \ No newline at end of file +} From 0a7b878284457f6bba63d8d0430d2978cc22cb78 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Mon, 22 Feb 2021 20:00:17 +0100 Subject: [PATCH 03/14] add correct yaml with the docs --- roman.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/roman.yaml b/roman.yaml index f838182..c954ff3 100644 --- a/roman.yaml +++ b/roman.yaml @@ -46,3 +46,9 @@ key: ${APP_KEY:-} domain: ${PROXY_DOMAIN:-https://proxy.services.wire.com} apiHost: ${WIRE_API_HOST:-https://prod-nginz-https.wire.com} +# if the proxy does not have access to it's domain, one needs to specify the +# TLS pub key manually - either by adding it directly in base64 +romanPubKeyBase64: ${ROMAN_PUB_KEY_BASE64:-} +# or by specifying the path to the file with the key +pathToRomanPubKey: ${PATH_TO_ROMAN_PUB_KEY:-} +# if both options are specified, the proxy uses the key defined in romanPubKeyBase64 From 88451af9a4c72a3143d7a0bb95a58ea07be664e9 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Mon, 22 Feb 2021 20:08:59 +0100 Subject: [PATCH 04/14] typo --- roman.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roman.yaml b/roman.yaml index c954ff3..7e9ca92 100644 --- a/roman.yaml +++ b/roman.yaml @@ -46,8 +46,8 @@ key: ${APP_KEY:-} domain: ${PROXY_DOMAIN:-https://proxy.services.wire.com} apiHost: ${WIRE_API_HOST:-https://prod-nginz-https.wire.com} -# if the proxy does not have access to it's domain, one needs to specify the -# TLS pub key manually - either by adding it directly in base64 +# if the proxy does not have access to its own domain, one needs to specify the +# TLS public key manually - either by adding it directly in base64 romanPubKeyBase64: ${ROMAN_PUB_KEY_BASE64:-} # or by specifying the path to the file with the key pathToRomanPubKey: ${PATH_TO_ROMAN_PUB_KEY:-} From 9e9d08f97b000029735ce28aaddbb761a35a7390 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 11:28:36 +0100 Subject: [PATCH 05/14] load key just from the base64 env --- roman.yaml | 6 +---- src/main/java/com/wire/bots/roman/Tools.java | 10 ++++++++- .../roman/commands/UpdateCertCommand.java | 6 ++--- .../com/wire/bots/roman/model/Config.java | 9 +++----- .../bots/roman/resources/ServiceResource.java | 22 ++----------------- 5 files changed, 18 insertions(+), 35 deletions(-) diff --git a/roman.yaml b/roman.yaml index 7e9ca92..3c06c88 100644 --- a/roman.yaml +++ b/roman.yaml @@ -46,9 +46,5 @@ key: ${APP_KEY:-} domain: ${PROXY_DOMAIN:-https://proxy.services.wire.com} apiHost: ${WIRE_API_HOST:-https://prod-nginz-https.wire.com} -# if the proxy does not have access to its own domain, one needs to specify the -# TLS public key manually - either by adding it directly in base64 +# TLS public key in base64 format romanPubKeyBase64: ${ROMAN_PUB_KEY_BASE64:-} -# or by specifying the path to the file with the key -pathToRomanPubKey: ${PATH_TO_ROMAN_PUB_KEY:-} -# if both options are specified, the proxy uses the key defined in romanPubKeyBase64 diff --git a/src/main/java/com/wire/bots/roman/Tools.java b/src/main/java/com/wire/bots/roman/Tools.java index 379fc9f..8df3926 100644 --- a/src/main/java/com/wire/bots/roman/Tools.java +++ b/src/main/java/com/wire/bots/roman/Tools.java @@ -1,5 +1,6 @@ package com.wire.bots.roman; +import com.wire.bots.roman.model.Config; import io.jsonwebtoken.Jwts; import javax.net.ssl.HttpsURLConnection; @@ -7,6 +8,7 @@ import javax.net.ssl.SSLSocketFactory; import java.io.IOException; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.security.PublicKey; import java.security.cert.Certificate; import java.util.Base64; @@ -41,7 +43,13 @@ static String generateToken(UUID botId, long exp) { .compact(); } - public static String getPubkey(String hostname) throws IOException { + public static String getPubKey(final Config config) { + byte[] keyBytes = Base64.getDecoder().decode(config.romanPubKeyBase64); + return new String(keyBytes, StandardCharsets.UTF_8); + } + + @SuppressWarnings("unused") // this is quite useful, leaving here in case we need it + public static String getPubKey(String hostname) throws IOException { String str = null; String raw_hostname = URI.create(hostname).getHost(); PublicKey publicKey = getPublicKey(raw_hostname); diff --git a/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java b/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java index 547c398..4a49da6 100644 --- a/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java +++ b/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java @@ -1,6 +1,7 @@ package com.wire.bots.roman.commands; import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.wire.bots.roman.Application; import com.wire.bots.roman.DAO.ProvidersDAO; import com.wire.bots.roman.ProviderClient; import com.wire.bots.roman.Tools; @@ -18,7 +19,6 @@ import javax.ws.rs.client.Client; import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; -import java.io.IOException; import java.util.List; public class UpdateCertCommand extends ConfiguredCommand { @@ -38,7 +38,7 @@ public void configure(Subparser subparser) { } @Override - public void run(Bootstrap bootstrap, Namespace namespace, Config config) throws IOException { + public void run(Bootstrap bootstrap, Namespace namespace, Config config) { Environment environment = new Environment("UpdateCertCommand"); Client client = new JerseyClientBuilder(environment) @@ -55,7 +55,7 @@ public void run(Bootstrap bootstrap, Namespace namespace, Config config) String hostname = namespace.getString("domain"); - String pubkey = Tools.getPubkey(hostname); + String pubkey = Tools.getPubKey(Application.getInstance().getConfig()); System.out.printf("\nCert:\n%s\n\n", pubkey); diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 416e3be..84ece63 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -21,7 +21,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.wire.lithium.Configuration; -import javax.annotation.Nullable; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; public class Config extends Configuration { @@ -33,11 +33,8 @@ public class Config extends Configuration { @JsonProperty public String domain; - @Nullable + @NotNull + @NotEmpty @JsonProperty public String romanPubKeyBase64; - - @Nullable - @JsonProperty - public String pathToRomanPubKey; } diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index 09de2c4..f0ace12 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -28,13 +28,9 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; -import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Base64; import java.util.UUID; @@ -247,25 +243,11 @@ public Response get(@ApiParam(hidden = true) @CookieParam(Z_ROMAN) String token, } } - private String getPubKey(final Config config) throws IOException { - String pubKey; - if (config.romanPubKeyBase64 != null) { - byte[] keyBytes = Base64.getDecoder().decode(config.romanPubKeyBase64); - pubKey = new String(keyBytes, StandardCharsets.UTF_8); - } else if (config.pathToRomanPubKey != null) { - byte[] keyBytes = Files.readAllBytes(Paths.get(config.pathToRomanPubKey)); - pubKey = new String(keyBytes, StandardCharsets.UTF_8); - } else { - pubKey = Tools.getPubkey(config.domain); - } - return pubKey; - } - - private Service newService() throws IOException { + private Service newService() { final Config config = Application.getInstance().getConfig(); Service ret = new Service(); ret.baseUrl = config.domain; - ret.pubkey = getPubKey(config); + ret.pubkey = Tools.getPubKey(config); ret.assets = new ArrayList<>(); Service._Asset asset1 = new Service._Asset(); From 8d1d920d3593ee3b2d9610ffa6950eeefd2cc8cb Mon Sep 17 00:00:00 2001 From: dkovacevic Date: Tue, 23 Feb 2021 14:36:21 +0100 Subject: [PATCH 06/14] made NewService.summary optional --- .../java/com/wire/bots/roman/resources/ServiceResource.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index f0ace12..1111638 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -277,9 +277,8 @@ static class _NewService { public String avatar; @JsonProperty - @NotNull @Length(min = 3, max = 128) - public String summary; + public String summary = "Summary"; @ValidationMethod(message = "`url` is not a valid URL") @JsonIgnore From 3e7ea170e72d9c6fcee99816f381888329deeaa9 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 15:04:51 +0100 Subject: [PATCH 07/14] validate format of the public key --- .../java/com/wire/bots/roman/model/Config.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 84ece63..2f5fc1b 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -18,8 +18,11 @@ package com.wire.bots.roman.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; +import com.wire.bots.roman.Tools; import com.wire.lithium.Configuration; +import io.dropwizard.validation.ValidationMethod; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; @@ -37,4 +40,19 @@ public class Config extends Configuration { @NotEmpty @JsonProperty public String romanPubKeyBase64; + + @ValidationMethod(message = "`romanPubKeyBase64` is not a valid base65") + @JsonIgnore + public boolean pubKeyFormatIsNotValid() { + boolean isValid = romanPubKeyBase64 != null && !romanPubKeyBase64.isEmpty(); + if (isValid) { + try { + Tools.getPubKey(this); + } catch (Exception ignored) { + isValid = false; + } + } + return isValid; + } + } From 0a0f3e40c08ee64569a716faeee8c3a859df4db5 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 15:06:06 +0100 Subject: [PATCH 08/14] wording --- src/main/java/com/wire/bots/roman/model/Config.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 2f5fc1b..8671fe1 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -41,7 +41,7 @@ public class Config extends Configuration { @JsonProperty public String romanPubKeyBase64; - @ValidationMethod(message = "`romanPubKeyBase64` is not a valid base65") + @ValidationMethod(message = "`romanPubKeyBase64` is not in a valid base64 format") @JsonIgnore public boolean pubKeyFormatIsNotValid() { boolean isValid = romanPubKeyBase64 != null && !romanPubKeyBase64.isEmpty(); From fc28921accc32bf221c4e4b0f303585356cb920c Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 15:07:45 +0100 Subject: [PATCH 09/14] delete obsolete getPubKey methods --- src/main/java/com/wire/bots/roman/Tools.java | 28 -------------------- 1 file changed, 28 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/Tools.java b/src/main/java/com/wire/bots/roman/Tools.java index 8df3926..d34a46d 100644 --- a/src/main/java/com/wire/bots/roman/Tools.java +++ b/src/main/java/com/wire/bots/roman/Tools.java @@ -3,14 +3,7 @@ import com.wire.bots.roman.model.Config; import io.jsonwebtoken.Jwts; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; -import java.io.IOException; -import java.net.URI; import java.nio.charset.StandardCharsets; -import java.security.PublicKey; -import java.security.cert.Certificate; import java.util.Base64; import java.util.Date; import java.util.UUID; @@ -47,25 +40,4 @@ public static String getPubKey(final Config config) { byte[] keyBytes = Base64.getDecoder().decode(config.romanPubKeyBase64); return new String(keyBytes, StandardCharsets.UTF_8); } - - @SuppressWarnings("unused") // this is quite useful, leaving here in case we need it - public static String getPubKey(String hostname) throws IOException { - String str = null; - String raw_hostname = URI.create(hostname).getHost(); - PublicKey publicKey = getPublicKey(raw_hostname); - if (publicKey != null) - str = Base64.getEncoder().encodeToString(publicKey.getEncoded()); - final String start = "-----BEGIN PUBLIC KEY-----"; - final String end = "-----END PUBLIC KEY-----"; - return String.format("%s\n%s\n%s", start, str, end); - } - - private static PublicKey getPublicKey(String hostname) throws IOException { - SSLSocketFactory factory = HttpsURLConnection.getDefaultSSLSocketFactory(); - SSLSocket socket = (SSLSocket) factory.createSocket(hostname, 443); - socket.startHandshake(); - Certificate[] certs = socket.getSession().getPeerCertificates(); - Certificate cert = certs[0]; - return cert.getPublicKey(); - } } From 213702c82c7b8d5fbb5412a81352bdec3298b620 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 15:10:03 +0100 Subject: [PATCH 10/14] use decodeBase64 instead --- src/main/java/com/wire/bots/roman/Tools.java | 5 ++--- .../java/com/wire/bots/roman/commands/UpdateCertCommand.java | 2 +- src/main/java/com/wire/bots/roman/model/Config.java | 2 +- .../java/com/wire/bots/roman/resources/ServiceResource.java | 2 +- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/Tools.java b/src/main/java/com/wire/bots/roman/Tools.java index d34a46d..6d9d71b 100644 --- a/src/main/java/com/wire/bots/roman/Tools.java +++ b/src/main/java/com/wire/bots/roman/Tools.java @@ -1,6 +1,5 @@ package com.wire.bots.roman; -import com.wire.bots.roman.model.Config; import io.jsonwebtoken.Jwts; import java.nio.charset.StandardCharsets; @@ -36,8 +35,8 @@ static String generateToken(UUID botId, long exp) { .compact(); } - public static String getPubKey(final Config config) { - byte[] keyBytes = Base64.getDecoder().decode(config.romanPubKeyBase64); + public static String decodeBase64(final String base64String) { + byte[] keyBytes = Base64.getDecoder().decode(base64String); return new String(keyBytes, StandardCharsets.UTF_8); } } diff --git a/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java b/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java index 4a49da6..f47458c 100644 --- a/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java +++ b/src/main/java/com/wire/bots/roman/commands/UpdateCertCommand.java @@ -55,7 +55,7 @@ public void run(Bootstrap bootstrap, Namespace namespace, Config config) String hostname = namespace.getString("domain"); - String pubkey = Tools.getPubKey(Application.getInstance().getConfig()); + String pubkey = Tools.decodeBase64(Application.getInstance().getConfig().romanPubKeyBase64); System.out.printf("\nCert:\n%s\n\n", pubkey); diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 8671fe1..3e80499 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -47,7 +47,7 @@ public boolean pubKeyFormatIsNotValid() { boolean isValid = romanPubKeyBase64 != null && !romanPubKeyBase64.isEmpty(); if (isValid) { try { - Tools.getPubKey(this); + Tools.decodeBase64(romanPubKeyBase64); } catch (Exception ignored) { isValid = false; } diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index 1111638..5964bc3 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -247,7 +247,7 @@ private Service newService() { final Config config = Application.getInstance().getConfig(); Service ret = new Service(); ret.baseUrl = config.domain; - ret.pubkey = Tools.getPubKey(config); + ret.pubkey = Tools.decodeBase64(config.romanPubKeyBase64); ret.assets = new ArrayList<>(); Service._Asset asset1 = new Service._Asset(); From a2a081c4e85af0867f12ff0d5f624f179cd78453 Mon Sep 17 00:00:00 2001 From: Lukas Forst Date: Tue, 23 Feb 2021 15:23:56 +0100 Subject: [PATCH 11/14] use a regex to check the base64 encoding --- .../java/com/wire/bots/roman/model/Config.java | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/model/Config.java b/src/main/java/com/wire/bots/roman/model/Config.java index 3e80499..8fc269c 100644 --- a/src/main/java/com/wire/bots/roman/model/Config.java +++ b/src/main/java/com/wire/bots/roman/model/Config.java @@ -20,7 +20,6 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; -import com.wire.bots.roman.Tools; import com.wire.lithium.Configuration; import io.dropwizard.validation.ValidationMethod; @@ -44,15 +43,8 @@ public class Config extends Configuration { @ValidationMethod(message = "`romanPubKeyBase64` is not in a valid base64 format") @JsonIgnore public boolean pubKeyFormatIsNotValid() { - boolean isValid = romanPubKeyBase64 != null && !romanPubKeyBase64.isEmpty(); - if (isValid) { - try { - Tools.decodeBase64(romanPubKeyBase64); - } catch (Exception ignored) { - isValid = false; - } - } - return isValid; + return romanPubKeyBase64 != null + && !romanPubKeyBase64.isEmpty() + && romanPubKeyBase64.matches("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"); } - } From 3d62e191e50ddd81a9c61f6622f096f0e14cc6a1 Mon Sep 17 00:00:00 2001 From: dkovacevic Date: Wed, 24 Feb 2021 10:57:40 +0100 Subject: [PATCH 12/14] check for avatar.isEmpty in validation --- .../wire/bots/roman/resources/ServiceResource.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index 1111638..4ac6617 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -84,10 +84,12 @@ public Response create(@ApiParam(hidden = true) @CookieParam(Z_ROMAN) String tok if (payload.avatar != null) { byte[] image = Base64.getDecoder().decode(payload.avatar); - Picture mediumImage = ImageProcessor.getMediumImage(new Picture(image)); - String key = providerClient.uploadProfilePicture(cookie, mediumImage.getImageData(), mediumImage.getMimeType()); - service.assets.get(0).key = key; - service.assets.get(1).key = key; + if (image != null) { + Picture mediumImage = ImageProcessor.getMediumImage(new Picture(image)); + String key = providerClient.uploadProfilePicture(cookie, mediumImage.getImageData(), mediumImage.getMimeType()); + service.assets.get(0).key = key; + service.assets.get(1).key = key; + } } Response create = providerClient.createService(cookie, service); @@ -296,7 +298,8 @@ public boolean isUrlValid() { @ValidationMethod(message = "`avatar` is not a Base64 encoded string") @JsonIgnore public boolean isAvatarValid() { - return avatar == null || avatar.matches("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$"); + return avatar == null + || (!avatar.isEmpty() && avatar.matches("^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$")); } } From 21867a947951e092114b9986e5a69b5fe3b10223 Mon Sep 17 00:00:00 2001 From: Dejan Kovacevic Date: Wed, 24 Feb 2021 14:07:22 +0100 Subject: [PATCH 13/14] Delete Service (#44) * Delete Service * Fixed DAO * README.md and Payload.url="null" * validation --- README.md | 7 ++-- .../com/wire/bots/roman/DAO/ProvidersDAO.java | 8 ++++ .../com/wire/bots/roman/ProviderClient.java | 8 ++++ .../bots/roman/resources/ServiceResource.java | 40 ++++++++++++++++++- .../bots/roman/integrations/DatabaseTest.java | 13 +++++- 5 files changed, 70 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index b205444..483238e 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,10 @@ Uses [lithium](https://github.com/wireapp/lithium) to utilize Wire Bot API ``` { - "name": "My Cool Bot", - "url": "https://my.server.com/webhook", // Pass _null_ if you prefere websockets - "avatar": "..." // Base64 encoded image + "name": "My Cool Bot", + "summary": "Short summary of this cool bot" // Optional + "url": "https://my.server.com/webhook", // Optional: Leave as null if you prefere websockets + "avatar": "..." // Optional: Base64 encoded image } ``` diff --git a/src/main/java/com/wire/bots/roman/DAO/ProvidersDAO.java b/src/main/java/com/wire/bots/roman/DAO/ProvidersDAO.java index 2d7717b..30bb6e8 100644 --- a/src/main/java/com/wire/bots/roman/DAO/ProvidersDAO.java +++ b/src/main/java/com/wire/bots/roman/DAO/ProvidersDAO.java @@ -36,6 +36,14 @@ int update(@Bind("id") UUID id, @Bind("serviceId") UUID serviceId, @Bind("serviceName") String serviceName); + @SqlUpdate("UPDATE Providers SET " + + "url = null," + + "service_auth = null, " + + "service = null, " + + "service_name = null " + + "WHERE id = :id") + int deleteService(@Bind("id") UUID providerId); + @SqlUpdate("UPDATE Providers SET url = :url WHERE id = :id") int updateUrl(@Bind("id") UUID id, @Bind("url") String url); diff --git a/src/main/java/com/wire/bots/roman/ProviderClient.java b/src/main/java/com/wire/bots/roman/ProviderClient.java index dcf7ae4..559accf 100644 --- a/src/main/java/com/wire/bots/roman/ProviderClient.java +++ b/src/main/java/com/wire/bots/roman/ProviderClient.java @@ -61,6 +61,14 @@ public Response createService(NewCookie zprovider, Service service) { .post(Entity.entity(service, MediaType.APPLICATION_JSON)); } + public Response deleteService(NewCookie zprovider, UUID serviceId) { + return servicesTarget + .path(serviceId.toString()) + .request(MediaType.APPLICATION_JSON) + .cookie(zprovider) + .delete(); + } + public Response enableService(NewCookie zprovider, UUID serviceId, String password) { _UpdateService updateService = new _UpdateService(); updateService.enabled = true; diff --git a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java index e376117..5ad7355 100644 --- a/src/main/java/com/wire/bots/roman/resources/ServiceResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ServiceResource.java @@ -33,6 +33,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.Base64; +import java.util.Objects; import java.util.UUID; import static com.wire.bots.roman.Const.Z_PROVIDER; @@ -161,7 +162,8 @@ public Response update(@Context ContainerRequestContext context, } if (payload.url != null) { - providersDAO.updateUrl(provider.id, payload.url); + String url = payload.url.equals("null") ? null : payload.url; + providersDAO.updateUrl(provider.id, url); } Response login = providerClient.login(provider.email, provider.password); @@ -245,6 +247,40 @@ public Response get(@ApiParam(hidden = true) @CookieParam(Z_ROMAN) String token, } } + @DELETE + @ApiOperation(value = "Delete the Service", response = _Result.class) + @ServiceAuthorization + public Response delete(@ApiParam(hidden = true) @CookieParam(Z_ROMAN) String token, + @Context ContainerRequestContext context) { + try { + UUID providerId = (UUID) context.getProperty(Const.PROVIDER_ID); + + Logger.debug("ServiceResource.delete: provider: %s", providerId); + + Provider provider = providersDAO.get(providerId); + + final int update = providersDAO.deleteService(providerId); + + Response login = providerClient.login(provider.email, provider.password); + + NewCookie cookie = login.getCookies().get(Z_PROVIDER); + + final Response response = providerClient.deleteService(cookie, provider.serviceId); + + return Response. + ok(). + build(); + + } catch (Exception e) { + e.printStackTrace(); + Logger.error("ServiceResource.delete: %s", e); + return Response + .ok(new ErrorMessage("Something went wrong")) + .status(500) + .build(); + } + } + private Service newService() { final Config config = Application.getInstance().getConfig(); Service ret = new Service(); @@ -318,7 +354,7 @@ static class _UpdateService { @ValidationMethod(message = "`url` is not a valid URL") @JsonIgnore public boolean isUrlValid() { - if (url == null) + if (url == null || Objects.equals(url, "null")) return true; try { new URL(url).toURI(); diff --git a/src/test/java/com/wire/bots/roman/integrations/DatabaseTest.java b/src/test/java/com/wire/bots/roman/integrations/DatabaseTest.java index 9bb848a..9b2fe8b 100644 --- a/src/test/java/com/wire/bots/roman/integrations/DatabaseTest.java +++ b/src/test/java/com/wire/bots/roman/integrations/DatabaseTest.java @@ -18,7 +18,14 @@ public class DatabaseTest { private static final DropwizardTestSupport SUPPORT = new DropwizardTestSupport<>( Application.class, "roman.yaml", - ConfigOverride.config("key", "TcZA2Kq4GaOcIbQuOvasrw34321cZAfLW4Ga54fsds43hUuOdcdm42")); + ConfigOverride.config("key", "TcZA2Kq4GaOcIbQuOvasrw34321cZAfLW4Ga54fsds43hUuOdcdm42"), + ConfigOverride.config("romanPubKeyBase64", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3xtHqyZPlb0lxlnP0rNA\n" + + "JVmAjB1Tenl11brkkKihcJNRAYrnrT/6sPX4u2lVn/aPncUTjN8omL47MBct7qYV\n" + + "1VY4a5beOyNiVL0ZjZMuh07aL9Z2A4cu67tKZrCoGttn3jpSVlqoOtwEgW+Tpgpm\n" + + "KojcRC4DDXEZTEvRoi0RLzAyWCH/8hwWzXR7J082zmn0Ur211QVbOJN/62PAIWyj\n" + + "l5bLglp00AY5OnBHgRNwwRkBJIJLwgNm8u9+0ZplqmMGd3C/QFNngCOeRvFe+5g4\n" + + "qfO4/FOlbkM2kYFAi5KUowfG7cdMQELI+fe4v7yNsgrbMKhnIiLtDIU4wiQIRjbr\n" + + "ZwIDAQAB")); private Jdbi jdbi; @Before @@ -91,6 +98,10 @@ public void testProviderDAO() { provider = providersDAO.get(providerId); assert provider != null; assert provider.serviceName.equals(newName); + + final int deleteService = providersDAO.deleteService(providerId); + provider = providersDAO.get(providerId); + } @Test From 6ddf4cddd6db5e96818a79f346195da5d3fef925 Mon Sep 17 00:00:00 2001 From: Dejan Kovacevic Date: Tue, 2 Mar 2021 13:40:08 +0100 Subject: [PATCH 14/14] Lowercase email in /provider (#45) --- pom.xml | 2 +- .../java/com/wire/bots/roman/resources/ProviderResource.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 26f64dd..7f298bb 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ roman com.wire.bots - 0.2.0 + 0.2.1 diff --git a/src/main/java/com/wire/bots/roman/resources/ProviderResource.java b/src/main/java/com/wire/bots/roman/resources/ProviderResource.java index 2d6c11c..96599a1 100644 --- a/src/main/java/com/wire/bots/roman/resources/ProviderResource.java +++ b/src/main/java/com/wire/bots/roman/resources/ProviderResource.java @@ -47,7 +47,7 @@ public ProviderResource(Jdbi jdbi, ProviderClient providerClient) { public Response register(@ApiParam @Valid _NewUser payload) { try { String name = payload.name; - String email = payload.email; + String email = payload.email.toLowerCase(); Response register = providerClient.register(name, email); @@ -83,7 +83,8 @@ public Response register(@ApiParam @Valid _NewUser payload) { @ApiOperation(value = "Login as Wire Bot Developer") public Response login(@ApiParam @Valid SignIn payload) { try { - Provider provider = providersDAO.get(payload.email); + final String email = payload.email.toLowerCase(); + Provider provider = providersDAO.get(email); if (provider == null || !SCryptUtil.check(payload.password, provider.hash)) { return Response .ok(new ErrorMessage("Wrong email or password"))