Fix webhook version and validate username and token is present

This commit is contained in:
rubenlagus 2021-03-07 03:28:24 +00:00 committed by Ruben Bermudez
parent 272be4a79c
commit c7728fbc8a
8 changed files with 62 additions and 17 deletions

View File

@ -58,14 +58,14 @@ public abstract class AbilityWebhookBot extends BaseAbilityBot implements Webhoo
} }
@Override @Override
public BotApiMethod onWebhookUpdateReceived(Update update) { public BotApiMethod<?> onWebhookUpdateReceived(Update update) {
super.onUpdateReceived(update); super.onUpdateReceived(update);
return null; return null;
} }
@Override @Override
public void setWebhook(SetWebhook setWebhook) throws TelegramApiException { public void setWebhook(SetWebhook setWebhook) throws TelegramApiException {
WebhookUtils.setWebhook(this, setWebhook); WebhookUtils.setWebhook(this, this, setWebhook);
} }
@Override @Override

View File

@ -1,9 +1,11 @@
package org.telegram.telegrambots.meta; package org.telegram.telegrambots.meta;
import com.google.common.base.Strings;
import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook; import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.BotSession; import org.telegram.telegrambots.meta.generics.BotSession;
import org.telegram.telegrambots.meta.generics.LongPollingBot; import org.telegram.telegrambots.meta.generics.LongPollingBot;
import org.telegram.telegrambots.meta.generics.TelegramBot;
import org.telegram.telegrambots.meta.generics.Webhook; import org.telegram.telegrambots.meta.generics.Webhook;
import org.telegram.telegrambots.meta.generics.WebhookBot; import org.telegram.telegrambots.meta.generics.WebhookBot;
@ -15,8 +17,6 @@ import java.lang.reflect.InvocationTargetException;
* Bots manager * Bots manager
*/ */
public class TelegramBotsApi { public class TelegramBotsApi {
private static final String webhookUrlFormat = "{0}callback/";
Class<? extends BotSession> botSessionClass; Class<? extends BotSession> botSessionClass;
private boolean useWebhook; ///< True to enable webhook usage private boolean useWebhook; ///< True to enable webhook usage
private Webhook webhook; ///< Webhook instance private Webhook webhook; ///< Webhook instance
@ -55,6 +55,12 @@ public class TelegramBotsApi {
* @param bot the bot to register * @param bot the bot to register
*/ */
public BotSession registerBot(LongPollingBot bot) throws TelegramApiException { public BotSession registerBot(LongPollingBot bot) throws TelegramApiException {
if (bot == null) {
throw new TelegramApiException("Parameter bot can not be null");
}
if (!validateBotUsernameAndToken(bot)) {
throw new TelegramApiException("Bot token and username can't be empty");
}
bot.onRegister(); bot.onRegister();
bot.clearWebhook(); bot.clearWebhook();
BotSession session; BotSession session;
@ -74,18 +80,33 @@ public class TelegramBotsApi {
* Register a bot in the api that will receive updates using webhook method * Register a bot in the api that will receive updates using webhook method
* @param bot Bot to register * @param bot Bot to register
* @param setWebhook Set webhook request to initialize the bot * @param setWebhook Set webhook request to initialize the bot
*
* @apiNote The webhook url will be appended with `/callback/bot.getBotPath()` at the end
*/ */
public void registerBot(WebhookBot bot, SetWebhook setWebhook) throws TelegramApiException { public void registerBot(WebhookBot bot, SetWebhook setWebhook) throws TelegramApiException {
if (setWebhook == null) { if (setWebhook == null) {
throw new TelegramApiException("Parameter setWebhook can not be null or empty"); throw new TelegramApiException("Parameter setWebhook can not be null");
} }
if (useWebhook) { if (useWebhook) {
if (webhook == null) { if (webhook == null) {
throw new TelegramApiException("This instance doesn't support Webhook bot, use correct constructor"); throw new TelegramApiException("This instance doesn't support Webhook bot, use correct constructor");
} }
if (!validateBotUsernameAndToken(bot)) {
throw new TelegramApiException("Bot token and username can't be empty");
}
bot.onRegister(); bot.onRegister();
webhook.registerWebhook(bot); webhook.registerWebhook(bot);
bot.setWebhook(setWebhook); bot.setWebhook(setWebhook);
} }
} }
/**
* Checks that the username and token are presented
* @param telegramBot bot to register
* @return False if username or token are empty or null, true otherwise
*/
private boolean validateBotUsernameAndToken(TelegramBot telegramBot) {
return !Strings.isNullOrEmpty(telegramBot.getBotToken()) &&
!Strings.isNullOrEmpty(telegramBot.getBotUsername());
}
} }

View File

@ -50,7 +50,7 @@ public class SetWebhook extends BotApiMethod<Boolean> {
@JsonProperty(URL_FIELD) @JsonProperty(URL_FIELD)
@NonNull @NonNull
private String url; ///< Optional. HTTPS url to send updates to. Use an empty string to remove webhook integration private String url; ///< HTTPS url to send updates to. Use an empty string to remove webhook integration
@JsonProperty(CERTIFICATE_FIELD) @JsonProperty(CERTIFICATE_FIELD)
private InputFile certificate; ///< Optional. Upload your public key certificate so that the root certificate in use can be checked private InputFile certificate; ///< Optional. Upload your public key certificate so that the root certificate in use can be checked
/** /**

View File

@ -16,7 +16,7 @@ public interface WebhookBot extends TelegramBot {
* This method is called when receiving updates via webhook * This method is called when receiving updates via webhook
* @param update Update received * @param update Update received
*/ */
BotApiMethod onWebhookUpdateReceived(Update update); BotApiMethod<?> onWebhookUpdateReceived(Update update);
/** /**
* Execute setWebhook method to set up the url of the webhook * Execute setWebhook method to set up the url of the webhook

View File

@ -3,9 +3,9 @@ package org.telegram.telegrambots;
/** /**
* @author Ruben Bermudez * @author Ruben Bermudez
* @version 1.0 * @version 1.0
* @brief Constants needed for Telegram Bots API * Constants needed for Telegram Bots API
* @date 20 of June of 2015
*/ */
public class Constants { public class Constants {
public static final int SOCKET_TIMEOUT = 75 * 1000; public static final int SOCKET_TIMEOUT = 75 * 1000;
public static final String WEBHOOK_URL_PATH = "callback";
} }

View File

@ -23,6 +23,6 @@ public abstract class TelegramWebhookBot extends DefaultAbsSender implements Web
@Override @Override
public void setWebhook(SetWebhook setWebhook) throws TelegramApiException { public void setWebhook(SetWebhook setWebhook) throws TelegramApiException {
WebhookUtils.setWebhook(this, setWebhook); WebhookUtils.setWebhook(this, this, setWebhook);
} }
} }

View File

@ -2,6 +2,7 @@ package org.telegram.telegrambots.updatesreceivers;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.telegram.telegrambots.Constants;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod; import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.Update; import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException; import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
@ -22,7 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @version 1.0 * @version 1.0
* Rest api to for webhook callback function * Rest api to for webhook callback function
*/ */
@Path("callback") @Path(Constants.WEBHOOK_URL_PATH)
public class RestApi { public class RestApi {
private static final Logger log = LoggerFactory.getLogger(RestApi.class); private static final Logger log = LoggerFactory.getLogger(RestApi.class);
@ -44,7 +45,7 @@ public class RestApi {
public Response updateReceived(@PathParam("botPath") String botPath, Update update) { public Response updateReceived(@PathParam("botPath") String botPath, Update update) {
if (callbacks.containsKey(botPath)) { if (callbacks.containsKey(botPath)) {
try { try {
BotApiMethod response = callbacks.get(botPath).onWebhookUpdateReceived(update); BotApiMethod<?> response = callbacks.get(botPath).onWebhookUpdateReceived(update);
if (response != null) { if (response != null) {
response.validate(); response.validate();
} }

View File

@ -1,5 +1,6 @@
package org.telegram.telegrambots.util; package org.telegram.telegrambots.util;
import com.google.common.base.Strings;
import org.apache.http.HttpEntity; import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
@ -11,6 +12,7 @@ import org.apache.http.util.EntityUtils;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.telegram.telegrambots.Constants;
import org.telegram.telegrambots.bots.DefaultAbsSender; import org.telegram.telegrambots.bots.DefaultAbsSender;
import org.telegram.telegrambots.bots.DefaultBotOptions; import org.telegram.telegrambots.bots.DefaultBotOptions;
import org.telegram.telegrambots.facilities.TelegramHttpClientBuilder; import org.telegram.telegrambots.facilities.TelegramHttpClientBuilder;
@ -20,6 +22,7 @@ import org.telegram.telegrambots.meta.api.methods.updates.SetWebhook;
import org.telegram.telegrambots.meta.api.objects.InputFile; import org.telegram.telegrambots.meta.api.objects.InputFile;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException; import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException; import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.generics.WebhookBot;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -43,7 +46,7 @@ public final class WebhookUtils {
* @apiNote Telegram API parameters will be taken only from SetWebhook object * @apiNote Telegram API parameters will be taken only from SetWebhook object
* @apiNote Bot options will be fetched from Bot to set up the HTTP connection * @apiNote Bot options will be fetched from Bot to set up the HTTP connection
*/ */
public static void setWebhook(DefaultAbsSender bot, SetWebhook setWebhook) throws TelegramApiException { public static void setWebhook(DefaultAbsSender bot, WebhookBot webhookBot, SetWebhook setWebhook) throws TelegramApiException {
setWebhook.validate(); setWebhook.validate();
DefaultBotOptions botOptions = bot.getOptions(); DefaultBotOptions botOptions = bot.getOptions();
@ -61,7 +64,7 @@ public final class WebhookUtils {
HttpPost httppost = new HttpPost(requestUrl); HttpPost httppost = new HttpPost(requestUrl);
httppost.setConfig(requestConfig); httppost.setConfig(requestConfig);
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody(SetWebhook.URL_FIELD, setWebhook.getUrl(), TEXT_PLAIN_CONTENT_TYPE); builder.addTextBody(SetWebhook.URL_FIELD, getBotUrl(setWebhook, webhookBot), TEXT_PLAIN_CONTENT_TYPE);
if (setWebhook.getMaxConnections() != null) { if (setWebhook.getMaxConnections() != null) {
builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, setWebhook.getMaxConnections().toString(), TEXT_PLAIN_CONTENT_TYPE); builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, setWebhook.getMaxConnections().toString(), TEXT_PLAIN_CONTENT_TYPE);
} }
@ -100,10 +103,10 @@ public final class WebhookUtils {
} }
/** /**
* @deprecated Use {{@link #setWebhook(DefaultAbsSender, SetWebhook)}} instead * @deprecated Use {{@link #setWebhook(DefaultAbsSender, WebhookBot, SetWebhook)}} instead
*/ */
@Deprecated @Deprecated
public static void setWebhook(DefaultAbsSender bot, String url, String publicCertificatePath) throws TelegramApiRequestException { public static void setWebhook(DefaultAbsSender bot, WebhookBot webhookBot, String url, String publicCertificatePath) throws TelegramApiRequestException {
DefaultBotOptions botOptions = bot.getOptions(); DefaultBotOptions botOptions = bot.getOptions();
try (CloseableHttpClient httpclient = TelegramHttpClientBuilder.build(botOptions)) { try (CloseableHttpClient httpclient = TelegramHttpClientBuilder.build(botOptions)) {
@ -120,7 +123,7 @@ public final class WebhookUtils {
HttpPost httppost = new HttpPost(requestUrl); HttpPost httppost = new HttpPost(requestUrl);
httppost.setConfig(requestConfig); httppost.setConfig(requestConfig);
MultipartEntityBuilder builder = MultipartEntityBuilder.create(); MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody(SetWebhook.URL_FIELD, url); builder.addTextBody(SetWebhook.URL_FIELD, getBotUrl(url, webhookBot.getBotPath()));
if (botOptions.getMaxWebhookConnections() != null) { if (botOptions.getMaxWebhookConnections() != null) {
builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, botOptions.getMaxWebhookConnections().toString()); builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, botOptions.getMaxWebhookConnections().toString());
} }
@ -162,4 +165,24 @@ public final class WebhookUtils {
throw new TelegramApiRequestException("Error removing old webhook", e); throw new TelegramApiRequestException("Error removing old webhook", e);
} }
} }
private static String getBotUrl(SetWebhook setWebhook, WebhookBot webhookBot) {
String externalUrl = setWebhook.getUrl();
return getBotUrl(externalUrl, webhookBot.getBotPath());
}
private static String getBotUrl(String externalUrl, String botPath) {
if (!externalUrl.endsWith("/")) {
externalUrl += "/";
}
externalUrl += Constants.WEBHOOK_URL_PATH;
if (!Strings.isNullOrEmpty(botPath)) {
if (!botPath.startsWith("/")) {
externalUrl += "/";
}
externalUrl += botPath;
}
return externalUrl;
}
} }