diff --git a/lib/json-simple-1.1.1-source.zip b/lib/json-simple-1.1.1-source.zip new file mode 100644 index 0000000..4f2ee86 Binary files /dev/null and b/lib/json-simple-1.1.1-source.zip differ diff --git a/lib/json-simple-1.1.1.jar b/lib/json-simple-1.1.1.jar new file mode 100644 index 0000000..66347a6 Binary files /dev/null and b/lib/json-simple-1.1.1.jar differ diff --git a/src/org/april/hebdobot/cli/HebdobotConfigFile.java b/src/org/april/hebdobot/cli/HebdobotConfigFile.java index e673b47..9b10815 100644 --- a/src/org/april/hebdobot/cli/HebdobotConfigFile.java +++ b/src/org/april/hebdobot/cli/HebdobotConfigFile.java @@ -1,5 +1,5 @@ /** - * Copyright (C) 2017-2018 Christian Pierre MOMON + * Copyright (C) 2017-2021 Christian Pierre MOMON * * This file is part of (April) Hebdobot. * @@ -346,6 +346,21 @@ public class HebdobotConfigFile extends Properties return result; } + /** + * Gets the name. + * + * @return the name + */ + public String getPrivateBinUrl() + { + String result; + + result = getProperty("privatebin.url"); + + // + return result; + } + /** * Gets the review directory. * diff --git a/src/org/april/hebdobot/privatebin/Base58.java b/src/org/april/hebdobot/privatebin/Base58.java new file mode 100644 index 0000000..6502903 --- /dev/null +++ b/src/org/april/hebdobot/privatebin/Base58.java @@ -0,0 +1,208 @@ +/* + * Copyright 2021 Christian Pierre MOMON + * Copyright 2020 Dr Ian Preston ianopolous + * Copyright 2018 Andreas Schildbach + * Copyright 2011 Google Inc. + * + * From: + * https://github.com/multiformats/java-multibase/blob/master/src/main/java/io/ipfs/multibase/Base58.java + * https://github.com/bitcoinj/bitcoinj/blob/master/core/src/main/java/org/bitcoinj/core/Base58.java + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.april.hebdobot.privatebin; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * Base58 is a way to encode Bitcoin addresses (or arbitrary data) as + * alphanumeric strings. + *

+ * Note that this is not the same base58 as used by Flickr, which you may find + * referenced around the Internet. + *

+ * Satoshi explains: why base-58 instead of standard base-64 encoding? + *

    + *
  • Don't want 0OIl characters that look the same in some fonts and could be + * used to create visually identical looking account numbers.
  • + *
  • A string with non-alphanumeric characters is not as easily accepted as an + * account number.
  • + *
  • E-mail usually won't line-break if there's no punctuation to break + * at.
  • + *
  • Doubleclicking selects the whole number as one word if it's all + * alphanumeric.
  • + *
+ *

+ * However, note that the encoding/decoding runs in O(n²) time, so it is + * not useful for large data. + *

+ * The basic idea of the encoding is to treat the data bytes as a large number + * represented using base-256 digits, convert the number to be represented using + * base-58 digits, preserve the exact number of leading zeros (which are + * otherwise lost during the mathematical operations on the numbers), and + * finally represent the resulting base-58 digits as alphanumeric ASCII + * characters. + */ +public class Base58 +{ + public static final char[] ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".toCharArray(); + private static final char ENCODED_ZERO = ALPHABET[0]; + private static final int[] INDEXES = new int[128]; + static + { + Arrays.fill(INDEXES, -1); + for (int i = 0; i < ALPHABET.length; i++) + { + INDEXES[ALPHABET[i]] = i; + } + } + + /** + * Decodes the given base58 string into the original data bytes. + * + * @param input + * the base58-encoded string to decode + * @return the decoded data bytes + */ + public static byte[] decode(final String input) + { + if (input.length() == 0) + { + return new byte[0]; + } + // Convert the base58-encoded ASCII chars to a base58 byte sequence + // (base58 digits). + byte[] input58 = new byte[input.length()]; + for (int i = 0; i < input.length(); ++i) + { + char c = input.charAt(i); + int digit = c < 128 ? INDEXES[c] : -1; + if (digit < 0) + { + throw new IllegalStateException("InvalidCharacter in base 58"); + } + input58[i] = (byte) digit; + } + // Count leading zeros. + int zeros = 0; + while (zeros < input58.length && input58[zeros] == 0) + { + ++zeros; + } + // Convert base-58 digits to base-256 digits. + byte[] decoded = new byte[input.length()]; + int outputStart = decoded.length; + for (int inputStart = zeros; inputStart < input58.length;) + { + decoded[--outputStart] = divmod(input58, inputStart, 58, 256); + if (input58[inputStart] == 0) + { + ++inputStart; // optimization - skip leading zeros + } + } + // Ignore extra leading zeroes that were added during the calculation. + while (outputStart < decoded.length && decoded[outputStart] == 0) + { + ++outputStart; + } + // Return decoded data (including original number of leading zeros). + return Arrays.copyOfRange(decoded, outputStart - zeros, decoded.length); + } + + public static BigInteger decodeToBigInteger(final String input) + { + return new BigInteger(1, decode(input)); + } + + /** + * Divides a number, represented as an array of bytes each containing a + * single digit in the specified base, by the given divisor. The given + * number is modified in-place to contain the quotient, and the return value + * is the remainder. + * + * @param number + * the number to divide + * @param firstDigit + * the index within the array of the first non-zero digit (this + * is used for optimization by skipping the leading zeros) + * @param base + * the base in which the number's digits are represented (up to + * 256) + * @param divisor + * the number to divide by (up to 256) + * @return the remainder of the division operation + */ + private static byte divmod(final byte[] number, final int firstDigit, final int base, final int divisor) + { + // this is just long division which accounts for the base of the input + // digits + int remainder = 0; + for (int i = firstDigit; i < number.length; i++) + { + int digit = number[i] & 0xFF; + int temp = remainder * base + digit; + number[i] = (byte) (temp / divisor); + remainder = temp % divisor; + } + return (byte) remainder; + } + + /** + * Encodes the given bytes as a base58 string (no checksum is appended). + * + * @param input + * the bytes to encode + * @return the base58-encoded string + */ + public static String encode(byte[] input) + { + if (input.length == 0) + { + return ""; + } + // Count leading zeros. + int zeros = 0; + while (zeros < input.length && input[zeros] == 0) + { + ++zeros; + } + // Convert base-256 digits to base-58 digits (plus conversion to ASCII + // characters) + input = Arrays.copyOf(input, input.length); // since we modify it + // in-place + char[] encoded = new char[input.length * 2]; // upper bound + int outputStart = encoded.length; + for (int inputStart = zeros; inputStart < input.length;) + { + encoded[--outputStart] = ALPHABET[divmod(input, inputStart, 256, 58)]; + if (input[inputStart] == 0) + { + ++inputStart; // optimization - skip leading zeros + } + } + // Preserve exactly as many leading encoded zeros in output as there + // were leading zeros in input. + while (outputStart < encoded.length && encoded[outputStart] == ENCODED_ZERO) + { + ++outputStart; + } + while (--zeros >= 0) + { + encoded[--outputStart] = ENCODED_ZERO; + } + // Return encoded string (including encoded leading zeros). + return new String(encoded, outputStart, encoded.length - outputStart); + } +} \ No newline at end of file diff --git a/src/org/april/hebdobot/privatebin/BurnAfterReading.java b/src/org/april/hebdobot/privatebin/BurnAfterReading.java new file mode 100644 index 0000000..e5cf03f --- /dev/null +++ b/src/org/april/hebdobot/privatebin/BurnAfterReading.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2019-2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Enum Option. + */ +public enum BurnAfterReading +{ + ON("1"), + OFF("0"); + + private final String value; + + /** + * Instantiates a new option. + * + * @param value + * the value + */ + private BurnAfterReading(final String value) + { + this.value = value; + } + + /** + * To string. + * + * @return the string + */ + @Override + public String toString() + { + String result; + + result = this.value; + + // + return result; + } +} diff --git a/src/org/april/hebdobot/privatebin/Compression.java b/src/org/april/hebdobot/privatebin/Compression.java new file mode 100644 index 0000000..874f3dd --- /dev/null +++ b/src/org/april/hebdobot/privatebin/Compression.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Enum Compression. + */ +public enum Compression +{ + NONE("none"), + ZLIB("zlib"); + + private final String value; + + /** + * Instantiates a new option. + * + * @param value + * the value + */ + private Compression(final String value) + { + this.value = value; + } + + /** + * To string. + * + * @return the string + */ + @Override + public String toString() + { + String result; + + result = this.value; + + // + return result; + } +} diff --git a/src/org/april/hebdobot/privatebin/Expiration.java b/src/org/april/hebdobot/privatebin/Expiration.java new file mode 100644 index 0000000..99eb799 --- /dev/null +++ b/src/org/april/hebdobot/privatebin/Expiration.java @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2017-2021 Christian Pierre MOMON + * Copyright (C) 2011-2013 Nicolas Vinot + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Enum Expiration. + */ +public enum Expiration +{ + MINUTE_5("5min"), + MINUTE_10("10min"), + HOUR_1("1hour"), + DAY_1("1day"), + WEEK_1("1week"), + MONTH_1("1month"), + YEAR_1("1year"), + NEVER("never"); + + private final String value; + + /** + * Instantiates a new expiration. + * + * @param value + * the value + */ + private Expiration(final String value) + { + this.value = value; + } + + /** + * To string. + * + * @return the string + */ + @Override + public String toString() + { + String result; + + result = this.value; + + // + return result; + } +} diff --git a/src/org/april/hebdobot/privatebin/Formatter.java b/src/org/april/hebdobot/privatebin/Formatter.java new file mode 100644 index 0000000..32f35b5 --- /dev/null +++ b/src/org/april/hebdobot/privatebin/Formatter.java @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2019-2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Enum Formatter. + */ +public enum Formatter +{ + PLAINTEXT("plaintext"), + SYNTAXHIGHLIGHTING("syntaxhighlighting"), + MARKDOWN("markdown"); + + private final String value; + + /** + * Instantiates a new format. + * + * @param value + * the value + */ + private Formatter(final String value) + { + this.value = value; + } + + /** + * To string. + * + * @return the string + */ + @Override + public String toString() + { + String result; + + result = this.value; + + // + return result; + } +} diff --git a/src/org/april/hebdobot/privatebin/OpenDiscussion.java b/src/org/april/hebdobot/privatebin/OpenDiscussion.java new file mode 100644 index 0000000..ac0f8aa --- /dev/null +++ b/src/org/april/hebdobot/privatebin/OpenDiscussion.java @@ -0,0 +1,57 @@ +/** + * Copyright (C) 2019-2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Enum Option. + */ +public enum OpenDiscussion +{ + ON("1"), + OFF("0"); + + private final String value; + + /** + * Instantiates a new option. + * + * @param value + * the value + */ + private OpenDiscussion(final String value) + { + this.value = value; + } + + /** + * To string. + * + * @return the string + */ + @Override + public String toString() + { + String result; + + result = this.value; + + // + return result; + } +} diff --git a/src/org/april/hebdobot/privatebin/PrivatebinClient.java b/src/org/april/hebdobot/privatebin/PrivatebinClient.java new file mode 100644 index 0000000..699804e --- /dev/null +++ b/src/org/april/hebdobot/privatebin/PrivatebinClient.java @@ -0,0 +1,301 @@ +/** + * Copyright (C) 2017-2021 Christian Pierre MOMON + * Copyright (C) 2011-2013 Nicolas Vinot + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URL; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import java.util.Random; +import java.util.zip.Deflater; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.GCMParameterSpec; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.SecretKeySpec; +import javax.net.ssl.HttpsURLConnection; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.NameValuePair; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.message.BasicNameValuePair; +import org.april.hebdobot.HebdobotException; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; + +import fr.devinsy.strings.StringList; + +/** + * The Class PastebinClient. + */ +public class PrivatebinClient +{ + private String serverUrl; + private Compression compression; + + /** + * Instantiates a new privatebin client. + * + * @param serverUrl + * the server url + */ + public PrivatebinClient(final String serverUrl) + { + this.serverUrl = serverUrl; + this.compression = Compression.ZLIB; + } + + /** + * Paste. + * + * @param serverUrl + * the server url + * @param expirationDate + * the expiration + * @param burnAfterReading + * the burn after reading + * @param openDiscussion + * the open discussion + * @return the string + * @throws HebdobotException + * the hebdobot exception + * @throws PrivatebinException + */ + public String paste(final String text, final Expiration expiration, final Formatter formatter, final BurnAfterReading burnAfterReading, + final OpenDiscussion openDiscussion) throws PrivatebinException + { + String result; + + result = null; + try + { + if (expiration == null) + { + throw new IllegalArgumentException("Null parameter expiration."); + } + else if (formatter == null) + { + throw new IllegalArgumentException("Null parameter formatter."); + } + else if (burnAfterReading == null) + { + throw new IllegalArgumentException("Null parameter burn after reading."); + } + else if (openDiscussion == null) + { + throw new IllegalArgumentException("Null parameter open discussion."); + } + else + { + // Note: the following code is based on: + // https://github.com/PrivateBin/PrivateBin/wiki/API + // https://github.com/kkingsley-BF/PrivateBin-Groovy/blob/master/Paste.groovy + + // Optional parameters + // =================== + + // Location of local file to attach, leave quotes empty for no + // file + String localAttachmentFilename = ""; + // Paste attachment name, leave quotes empty for no file + String pasteAttachmentFilename = ""; + // Read file contents into paste, leave quotes empty no no file + String plaintextFileLocation = ""; + // Set paste password, leave quotes empty for no password + String userPastePassword = ""; + + // + + // Generate password. + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + keyGen.init(192); + String randomPassword = Base64.getEncoder().encodeToString(keyGen.generateKey().getEncoded()); + String customPassword = randomPassword + userPastePassword; + + // Generate IV. + byte[] cipherIVBytes = new byte[16]; + new Random().nextBytes(cipherIVBytes); + String cipherIVEncoded = Base64.getEncoder().encodeToString(cipherIVBytes); + + // Generate salt. + byte[] kdfSaltBytes = new byte[8]; + new Random().nextBytes(kdfSaltBytes); + String kdfSaltEncoded = Base64.getEncoder().encodeToString(kdfSaltBytes); + + // Build message to encrypt. + String pasteData = "{\"paste\":\"" + text + "\"}"; + + // Compression. + byte[] pasteDataBytes; + if (StringUtils.equals(this.compression.toString(), "zlib")) + { + Deflater zipDeflater = new Deflater(); + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + zipDeflater.setInput(pasteData.getBytes()); + zipDeflater.finish(); + byte[] buffer = new byte[1024]; + while (!zipDeflater.finished()) + { + int count = zipDeflater.deflate(buffer); + stream.write(buffer, 0, count); + } + byte[] output; + output = stream.toByteArray(); + stream.close(); + zipDeflater.end(); + // Need to remove the header + pasteDataBytes = Arrays.copyOfRange(output, 2, output.length - 4); + } + else + { + pasteDataBytes = pasteData.getBytes(); + } + + // Generate secret key for cipher. + SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256"); + KeySpec passwordBasedEncryptionKeySpec = new PBEKeySpec(customPassword.toCharArray(), kdfSaltBytes, 100000, 256); + SecretKey secret = new SecretKeySpec(factory.generateSecret(passwordBasedEncryptionKeySpec).getEncoded(), "AES"); + + // Cipher AAD. + StringList gcmTagString = new StringList(); + gcmTagString.append("["); + gcmTagString.append("["); + gcmTagString.append("\"").append(cipherIVEncoded).append("\"").append(","); + gcmTagString.append("\"").append(kdfSaltEncoded).append("\"").append(","); + gcmTagString.append("100000,256,128,"); + gcmTagString.append("\"").append("aes").append("\"").append(","); + gcmTagString.append("\"").append("gcm").append("\"").append(","); + gcmTagString.append("\"").append(this.compression).append("\""); + gcmTagString.append("]"); + gcmTagString.append(","); + gcmTagString.append("\"").append(formatter).append("\"").append(","); + gcmTagString.append(openDiscussion).append(","); + gcmTagString.append(burnAfterReading); + gcmTagString.append("]"); + byte[] gcmBytes = gcmTagString.toString().getBytes(); + + System.out.println("gcm=" + gcmTagString.toString()); + + // Generate cipher text. + Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); + GCMParameterSpec spec = new GCMParameterSpec(128, cipherIVBytes); + cipher.init(Cipher.ENCRYPT_MODE, secret, spec); + cipher.updateAAD(gcmBytes); + byte[] cipherTextBytes = cipher.doFinal(pasteDataBytes); + String cipherText = Base64.getEncoder().encodeToString(cipherTextBytes); + + // Create POST payload. + StringList payload = new StringList(); + payload.append("{"); + payload.append("\"v\":2,"); + payload.append("\"adata\":").append(gcmTagString.toString()).append(","); + payload.append("\"ct\":\"").append(cipherText).append("\","); + payload.append("\"meta\":{\"expire\":\"").append(expiration).append("\"}"); + payload.append("}"); + + // POST Request. + HttpsURLConnection pasteRequest = (HttpsURLConnection) new URL(this.serverUrl).openConnection(); + pasteRequest.setRequestMethod("POST"); + pasteRequest.setDoOutput(true); + pasteRequest.setRequestProperty("X-Requested-With", "JSONHttpRequest"); + pasteRequest.getOutputStream().write(payload.toString().getBytes()); + System.out.println("PAYLOAD=" + payload.toString()); + + // Server response. + int responseCode = pasteRequest.getResponseCode(); + System.out.println("Server response: " + responseCode); + if (responseCode == 200) + { + + String out = IOUtils.toString(pasteRequest.getInputStream(), "UTF-8"); + System.out.println("===> " + out); + + JSONObject parser = (JSONObject) new JSONParser().parse(out); + String status = parser.get("status").toString(); + if (StringUtils.equals(status, "0")) + { + String id = parser.get("id").toString(); + String pasteURL = parser.get("url").toString(); + String deleteToken = parser.get("deletetoken").toString(); + String finalURL = this.serverUrl + pasteURL + "#" + Base58.encode(randomPassword.getBytes()); + String deleteURL = this.serverUrl + pasteURL + "&deletetoken=" + deleteToken; + System.out.println("SUCESS"); + System.out.println("Paste URL: " + finalURL); + System.out.println("Delete URL: " + deleteURL); + } + else + { + String output = parser.get("message").toString(); + System.out.println("message=" + output); + throw new PrivatebinException(out); + } + } + } + } + catch (BadPaddingException | IllegalBlockSizeException | InvalidAlgorithmParameterException | InvalidKeyException | InvalidKeySpecException + | NoSuchAlgorithmException | NoSuchPaddingException | ParseException | UnsupportedEncodingException + | ClientProtocolException exception) + { + throw new PrivatebinException(exception); + } + catch (IOException exception) + { + exception.printStackTrace(); + throw new PrivatebinException(exception); + } + + // + return result; + } + + /** + * Sets the parameter. + * + * @param params + * the params + * @param name + * the name + * @param value + * the value + */ + private static void setParameter(final List params, final String name, final String value) + { + if (value != null) + { + params.add(new BasicNameValuePair(name, value)); + } + } +} diff --git a/src/org/april/hebdobot/privatebin/PrivatebinException.java b/src/org/april/hebdobot/privatebin/PrivatebinException.java new file mode 100644 index 0000000..1891e12 --- /dev/null +++ b/src/org/april/hebdobot/privatebin/PrivatebinException.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +/** + * The Class PrivateBinException. + */ +public class PrivatebinException extends Exception +{ + private static final long serialVersionUID = -1113543017171098521L; + + /** + * Instantiates a new private bin exception. + */ + public PrivatebinException() + { + super(); + } + + /** + * Instantiates a new private bin exception. + * + * @param message + * the message + */ + public PrivatebinException(final String message) + { + super(message); + } + + /** + * Instantiates a new private bin exception. + * + * @param message + * the message + * @param cause + * the cause + */ + public PrivatebinException(final String message, final Throwable cause) + { + super(message, cause); + } + + /** + * Instantiates a new private bin exception. + * + * @param cause + * the cause + */ + public PrivatebinException(final Throwable cause) + { + super(cause); + } +} \ No newline at end of file diff --git a/src/org/april/hebdobot/privatebin/PrivatebinSettings.java b/src/org/april/hebdobot/privatebin/PrivatebinSettings.java new file mode 100644 index 0000000..fa3c9b2 --- /dev/null +++ b/src/org/april/hebdobot/privatebin/PrivatebinSettings.java @@ -0,0 +1,105 @@ +/** + * Copyright (C) 2019-2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +import org.apache.commons.lang3.StringUtils; + +/** + * The Class PrivatebinSettings + */ +public class PrivatebinSettings +{ + private String serverUrl; + private String expirationDate; + private String burnAfterReading; + private String openDiscussion; + + /** + * Instantiates a new Privatebin settings. + */ + public PrivatebinSettings() + { + this.serverUrl = null; + this.expirationDate = null; + this.burnAfterReading = null; + this.openDiscussion = null; + } + + public String getBurnAfterReading() + { + return this.burnAfterReading; + } + + public String getExpirationDate() + { + return this.expirationDate; + } + + public String getOpenDiscussion() + { + return this.openDiscussion; + } + + public String getServerUrl() + { + return this.serverUrl; + } + + /** + * Checks if is valid. + * + * @return true, if is valid + */ + public boolean isValid() + { + boolean result; + + if ((StringUtils.isBlank(this.serverUrl)) || (StringUtils.containsOnly(this.serverUrl, 'X'))) + { + result = false; + } + else + { + result = true; + } + + // + return result; + } + + public void setBurnAfterReading(final String burnAfterReading) + { + this.burnAfterReading = burnAfterReading; + } + + public void setExpirationDate(final String expirationDate) + { + this.expirationDate = expirationDate; + } + + public void setOpenDiscussion(final String openDiscussion) + { + this.openDiscussion = openDiscussion; + } + + public void setServerUrl(final String serverUrl) + { + this.serverUrl = serverUrl; + } +} diff --git a/test/org/april/hebdobot/privatebin/PrivatebinClientTest.java b/test/org/april/hebdobot/privatebin/PrivatebinClientTest.java new file mode 100644 index 0000000..5521000 --- /dev/null +++ b/test/org/april/hebdobot/privatebin/PrivatebinClientTest.java @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019-2021 Christian Pierre MOMON + * + * This file is part of (April) Hebdobot. + * + * Hebdobot is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Hebdobot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with Hebdobot. If not, see + */ +package org.april.hebdobot.privatebin; + +import org.junit.Test; + +/** + * The Class PrivatebinClientTest. + */ +public class PrivatebinClientTest +{ + /** + * Test paste. + * + * @throws Exception + * the exception + */ + @Test + public void testPaste00() throws Exception + { + PrivatebinClient client = new PrivatebinClient("https://cpaste.org/"); + // PrivatebinClient client = new + // PrivatebinClient("https://paste.chapril.org/"); + + String text = "This is a test."; + + String result = client.paste(text, Expiration.MINUTE_5, Formatter.PLAINTEXT, BurnAfterReading.OFF, OpenDiscussion.OFF); + + System.out.println("result:" + result); + } +}