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
public BotApiMethod onWebhookUpdateReceived(Update update) {
public BotApiMethod<?> onWebhookUpdateReceived(Update update) {
super.onUpdateReceived(update);
return null;
}
@Override
public void setWebhook(SetWebhook setWebhook) throws TelegramApiException {
WebhookUtils.setWebhook(this, setWebhook);
WebhookUtils.setWebhook(this, this, setWebhook);
}
@Override

View File

@ -1,9 +1,11 @@
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.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.BotSession;
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.WebhookBot;
@ -15,8 +17,6 @@ import java.lang.reflect.InvocationTargetException;
* Bots manager
*/
public class TelegramBotsApi {
private static final String webhookUrlFormat = "{0}callback/";
Class<? extends BotSession> botSessionClass;
private boolean useWebhook; ///< True to enable webhook usage
private Webhook webhook; ///< Webhook instance
@ -55,6 +55,12 @@ public class TelegramBotsApi {
* @param bot the bot to register
*/
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.clearWebhook();
BotSession session;
@ -74,18 +80,33 @@ public class TelegramBotsApi {
* Register a bot in the api that will receive updates using webhook method
* @param bot Bot to register
* @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 {
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 (webhook == null) {
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();
webhook.registerWebhook(bot);
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)
@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)
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
* @param update Update received
*/
BotApiMethod onWebhookUpdateReceived(Update update);
BotApiMethod<?> onWebhookUpdateReceived(Update update);
/**
* Execute setWebhook method to set up the url of the webhook

View File

@ -3,9 +3,9 @@ package org.telegram.telegrambots;
/**
* @author Ruben Bermudez
* @version 1.0
* @brief Constants needed for Telegram Bots API
* @date 20 of June of 2015
* Constants needed for Telegram Bots API
*/
public class Constants {
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
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.LoggerFactory;
import org.telegram.telegrambots.Constants;
import org.telegram.telegrambots.meta.api.methods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiValidationException;
@ -22,7 +23,7 @@ import java.util.concurrent.ConcurrentHashMap;
* @version 1.0
* Rest api to for webhook callback function
*/
@Path("callback")
@Path(Constants.WEBHOOK_URL_PATH)
public class RestApi {
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) {
if (callbacks.containsKey(botPath)) {
try {
BotApiMethod response = callbacks.get(botPath).onWebhookUpdateReceived(update);
BotApiMethod<?> response = callbacks.get(botPath).onWebhookUpdateReceived(update);
if (response != null) {
response.validate();
}

View File

@ -1,5 +1,6 @@
package org.telegram.telegrambots.util;
import com.google.common.base.Strings;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
@ -11,6 +12,7 @@ import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.telegram.telegrambots.Constants;
import org.telegram.telegrambots.bots.DefaultAbsSender;
import org.telegram.telegrambots.bots.DefaultBotOptions;
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.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.exceptions.TelegramApiRequestException;
import org.telegram.telegrambots.meta.generics.WebhookBot;
import java.io.File;
import java.io.IOException;
@ -43,7 +46,7 @@ public final class WebhookUtils {
* @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
*/
public static void setWebhook(DefaultAbsSender bot, SetWebhook setWebhook) throws TelegramApiException {
public static void setWebhook(DefaultAbsSender bot, WebhookBot webhookBot, SetWebhook setWebhook) throws TelegramApiException {
setWebhook.validate();
DefaultBotOptions botOptions = bot.getOptions();
@ -61,7 +64,7 @@ public final class WebhookUtils {
HttpPost httppost = new HttpPost(requestUrl);
httppost.setConfig(requestConfig);
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) {
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
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();
try (CloseableHttpClient httpclient = TelegramHttpClientBuilder.build(botOptions)) {
@ -120,7 +123,7 @@ public final class WebhookUtils {
HttpPost httppost = new HttpPost(requestUrl);
httppost.setConfig(requestConfig);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody(SetWebhook.URL_FIELD, url);
builder.addTextBody(SetWebhook.URL_FIELD, getBotUrl(url, webhookBot.getBotPath()));
if (botOptions.getMaxWebhookConnections() != null) {
builder.addTextBody(SetWebhook.MAXCONNECTIONS_FIELD, botOptions.getMaxWebhookConnections().toString());
}
@ -162,4 +165,24 @@ public final class WebhookUtils {
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;
}
}