Skip to content

Commit

Permalink
Merge pull request #3 from doychin/master
Browse files Browse the repository at this point in the history
Different changes releated to login properties
  • Loading branch information
doychin authored May 26, 2024
2 parents e3c89cc + 3ff937a commit 8216517
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 38 deletions.
6 changes: 0 additions & 6 deletions microprofile-config-overrides.properties

This file was deleted.

3 changes: 3 additions & 0 deletions src/main/java/org/bgjug/jprime/registration/BadgePrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@

public class BadgePrinter {

private BadgePrinter() {
}

public static JasperPrint printBadge(String event, VisitorData visitorData, boolean printDay1,
boolean printDay2, boolean gift, boolean print) {
try {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/bgjug/jprime/registration/Globals.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public class Globals {

public static final String YEAR = ConfigProvider.getConfig()
.getOptionalValue("org.bgjug.jprime.registration.year", String.class)
.orElse("2023");
.orElse("2024");

public static final LocalDate FIRST_DAY = ConfigProvider.getConfig()
.getOptionalValue("org.bgjug.jprime.registration.first.day", LocalDate.class)
Expand Down
41 changes: 33 additions & 8 deletions src/main/java/org/bgjug/jprime/registration/LoginDialog.form
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
</grid>
</children>
</grid>
<grid id="e3588" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<grid id="e3588" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
Expand All @@ -59,34 +59,59 @@
<children>
<component id="3ebc4" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="User name"/>
</properties>
</component>
<component id="ebb0c" class="javax.swing.JTextField" binding="userNameField">
<component id="c4ebd" class="javax.swing.JPasswordField" binding="passwordField">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="200" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="c4ebd" class="javax.swing.JPasswordField" binding="passwordField">
<component id="e658b" class="javax.swing.JLabel">
<constraints>
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Password"/>
</properties>
</component>
<component id="225f4" class="javax.swing.JCheckBox" binding="chkSaveLoginDetails">
<constraints>
<grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Save my login details"/>
</properties>
</component>
<component id="37dd0" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Base URL:"/>
</properties>
</component>
<component id="ebb0c" class="javax.swing.JTextField" binding="userNameField">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="200" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="e658b" class="javax.swing.JLabel">
<component id="1a655" class="javax.swing.JComboBox" binding="comboUrlList">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Password"/>
<editable value="true"/>
<model/>
</properties>
</component>
</children>
Expand Down
135 changes: 128 additions & 7 deletions src/main/java/org/bgjug/jprime/registration/LoginDialog.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,41 @@
package org.bgjug.jprime.registration;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.bgjug.jprime.registration.client.RestClientFactory;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

public class LoginDialog extends JDialog {

private static final byte[] KEY_BYTES = "JPr1meEncrypti0nKeyT0SecureP@ssw".getBytes();

private static final String ERROR_TITLE = "Error";

private JPanel contentPane;

private JButton buttonOK;
Expand All @@ -22,6 +46,10 @@ public class LoginDialog extends JDialog {

private JPasswordField passwordField;

private JCheckBox chkSaveLoginDetails;

private JComboBox<String> comboUrlList;

private boolean success;

public LoginDialog() {
Expand All @@ -36,10 +64,26 @@ public LoginDialog() {
setTitle("JPrime " + Globals.YEAR + " Registration");

Config config = ConfigProvider.getConfig();
String[] urlList = config.getOptionalValue("org.bgjug.jprime.registration.url.list", String[].class)
.orElse(new String[] {});
comboUrlList.setModel(new DefaultComboBoxModel<>(urlList));

String url = config.getOptionalValue("org.bgjug.jprime.registration.url", String.class)
.orElse("http://localhost:8080/");
comboUrlList.setSelectedItem(url);
userNameField.setText(
config.getOptionalValue("org.bgjug.jprime.registration.username", String.class).orElse(null));
passwordField.setText(
config.getOptionalValue("org.bgjug.jprime.registration.password", String.class).orElse(null));
String encryptedPassword =
config.getOptionalValue("org.bgjug.jprime.registration.password", String.class).orElse(null);

if (StringUtils.isNotBlank(encryptedPassword)) {
try {
passwordField.setText(decryptPassword(encryptedPassword));
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException |
UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
passwordField.setText("");
}
}

buttonOK.addActionListener(e -> onOK());

Expand All @@ -49,6 +93,7 @@ public LoginDialog() {
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {

@Override
public void windowClosing(WindowEvent e) {
onCancel();
}
Expand All @@ -61,20 +106,70 @@ public void windowClosing(WindowEvent e) {

private void onOK() {
try {
success = RestClientFactory.initializeCredentials(userNameField.getText(),
new String(passwordField.getPassword()));
if (comboUrlList.getSelectedItem() == null || StringUtils.isBlank(
comboUrlList.getSelectedItem().toString())) {
JOptionPane.showMessageDialog(this, "Invalid or missing base URL!", "Unable to save settings",
JOptionPane.ERROR_MESSAGE);
return;
}
if (StringUtils.isBlank(userNameField.getText())) {
JOptionPane.showMessageDialog(this, "Username is required!", ERROR_TITLE,
JOptionPane.ERROR_MESSAGE);
return;
}
if (passwordField.getPassword().length == 0) {
JOptionPane.showMessageDialog(this, "Password is required!", ERROR_TITLE,
JOptionPane.ERROR_MESSAGE);
return;
}

success = RestClientFactory.initializeCredentials(comboUrlList.getSelectedItem().toString(),
userNameField.getText(), new String(passwordField.getPassword()));
if (!success) {
JOptionPane.showMessageDialog(this, "Invalid credentials!!!", "Error",
JOptionPane.showMessageDialog(this, "Invalid credentials!!!", ERROR_TITLE,
JOptionPane.ERROR_MESSAGE);
} else {
if (chkSaveLoginDetails.isSelected()) {
saveProperties();
}
}
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unable to login: " + e.getMessage(), "Error",
JOptionPane.showMessageDialog(this, "Unable to login: " + e.getMessage(), ERROR_TITLE,
JOptionPane.ERROR_MESSAGE);
e.printStackTrace();
}
// add your code here
dispose();
}

private void saveProperties() {
List<String> urlList = IntStream.range(0, comboUrlList.getItemCount())
.mapToObj(i -> comboUrlList.getItemAt(i))
.collect(Collectors.toList());

String selectedUrl = comboUrlList.getSelectedItem().toString();
if (!urlList.contains(selectedUrl)) {
urlList.add(selectedUrl);
}

Properties properties = new Properties();
properties.put("org.bgjug.jprime.registration.username", userNameField.getText());
properties.put("org.bgjug.jprime.registration.url", selectedUrl);
properties.put("org.bgjug.jprime.registration.url.list", String.join(",", urlList));

try (OutputStream output = Files.newOutputStream(
Paths.get("microprofile-config-overrides.properties"))) {
properties.put("org.bgjug.jprime.registration.password",
encryptPassword(new String(passwordField.getPassword())));
properties.store(output, "JPrime Registration program properties");
} catch (IOException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException |
InvalidKeyException | NoSuchAlgorithmException e) {
JOptionPane.showMessageDialog(this,
"Unable to store current settings to a properties file!!!\n Error: " + e.getMessage(),
"Unable to save settings", JOptionPane.ERROR_MESSAGE);
}
}

private void onCancel() {
success = false;
dispose();
Expand All @@ -83,4 +178,30 @@ private void onCancel() {
public boolean isSuccess() {
return success;
}

private String encryptPassword(String password)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
IllegalBlockSizeException, BadPaddingException {
Cipher cipher = initCipher(Cipher.ENCRYPT_MODE);
byte[] cipherText = cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64URLSafeString(cipherText);
}

private String decryptPassword(String encryptedPassword)
throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException,
UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
Cipher cipher = initCipher(Cipher.DECRYPT_MODE);
String decodeStr = URLDecoder.decode(encryptedPassword, StandardCharsets.UTF_8.toString());
byte[] base64decodedTokenArr = Base64.decodeBase64(decodeStr.getBytes(StandardCharsets.UTF_8));
byte[] decryptedPassword = cipher.doFinal(base64decodedTokenArr);
return new String(decryptedPassword, StandardCharsets.UTF_8);
}

private static Cipher initCipher(int decryptMode)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
SecretKeySpec key = new SecretKeySpec(KEY_BYTES, "AES");
cipher.init(decryptMode, key);
return cipher;
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package org.bgjug.jprime.registration.client;

import javax.swing.*;
import javax.ws.rs.core.Response;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Optional;
import java.security.InvalidParameterException;

import org.apache.commons.lang3.StringUtils;
import org.bgjug.jprime.registration.api.LoginApi;
import org.bgjug.jprime.registration.api.SpeakerApi;
import org.bgjug.jprime.registration.api.TicketApi;
import org.bgjug.jprime.registration.api.VisitorApi;
import org.eclipse.microprofile.config.ConfigProvider;
import org.eclipse.microprofile.rest.client.RestClientBuilder;

public class RestClientFactory {
Expand All @@ -30,14 +29,12 @@ public class RestClientFactory {

private final SpeakerApi speakerApi;

RestClientFactory() {
Optional<String> restEndPointUrl =
ConfigProvider.getConfig().getOptionalValue("org.bgjug.jprime.registration.url", String.class);
RestClientFactory(String address) {
URL url;
try {
url = new URL(restEndPointUrl.orElse("http://localhost:8080"));
url = new URL(address);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
throw new InvalidParameterException("RestClientFactory requires a valid address");
}

restClientBuilder = RestClientBuilder.newBuilder()
Expand All @@ -55,13 +52,23 @@ public class RestClientFactory {

private static RestClientFactory getInstance() {
if (instance == null) {
new RestClientFactory();
throw new IllegalStateException("RestClientFactory has not been initialized");
}
return instance;
}

public static LoginApi loginApi() {
return getInstance().loginApi;
private static synchronized RestClientFactory getInstance(String address) {
if (instance == null) {
if (StringUtils.isBlank(address)) {
throw new InvalidParameterException("RestClientFactory requires a valid address");
}
new RestClientFactory(address);
}
return instance;
}

public static LoginApi loginApi(String address) {
return getInstance(address).loginApi;
}

public static VisitorApi visitorApi() {
Expand All @@ -76,13 +83,13 @@ public static SpeakerApi speakerApi() {
return getInstance().speakerApi;
}

public static boolean initializeCredentials(String userName, String password) {
try (Response r = loginApi().login(userName, password, "Submit")) {
public static boolean initializeCredentials(String url, String userName, String password) {
try (Response r = loginApi(url).login(userName, password, "Submit")) {
if (r.getStatus() != 302 || !r.getHeaderString("Location").contains("admin")) {
return false;
}

SECURED_CALL_REQUEST_FILTER.initialize(loginApi(), userName, password,
SECURED_CALL_REQUEST_FILTER.initialize(loginApi(url), userName, password,
r.getCookies().get("JSESSIONID").getValue());
}
return true;
Expand Down
6 changes: 4 additions & 2 deletions src/main/resources/META-INF/microprofile-config.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
org.bgjug.jprime.registration.url=https://jprime.io
org.bgjug.jprime.registration.year=2023
org.bgjug.jprime.registration.url.list=https://jprime.io,http://localhost:8080
org.bgjug.jprime.registration.year=2024
org.bgjug.jprime.registration.first.day=2024-05-28
org.bgjug.jprime.registration.second.day=2024-05-29
smallrye.config.locations=.

0 comments on commit 8216517

Please sign in to comment.