Skip to content

Commit

Permalink
fix: parse login command regexp and other regexp (redhat-developer#884)
Browse files Browse the repository at this point in the history
* fix: parse login command regexp and other regexp

Signed-off-by: Stephane Bouchet <[email protected]>

* fix: parse login command regexp and other regexp

Signed-off-by: Stephane Bouchet <[email protected]>

* fix: parse login command regexp and other regexp

Signed-off-by: Stephane Bouchet <[email protected]>

---------

Signed-off-by: Stephane Bouchet <[email protected]>
  • Loading branch information
sbouchet authored Jul 26, 2024
1 parent 85ad9db commit d92992d
Show file tree
Hide file tree
Showing 10 changed files with 525 additions and 332 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class TelemetrySender implements TelemetryHandler {
private static final Pattern CLUSTER_URL_PATTERN = Pattern.compile("http(.*)/apis", Pattern.CASE_INSENSITIVE);
public static final String ANONYMOUS_CLUSTER_URL = "<CLUSTER_URL>";

private static final Pattern TOKEN_PATTERN = Pattern.compile("token-(.*):([\\d]+)", Pattern.CASE_INSENSITIVE);
private static final Pattern TOKEN_PATTERN = Pattern.compile("token-(.*):(\\d+)", Pattern.CASE_INSENSITIVE);
public static final String ANONYMOUS_TOKEN = "<TOKEN>";

private final TelemetryMessageBuilder.ActionMessage telemetry;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,25 @@
******************************************************************************/
package org.jboss.tools.intellij.openshift.ui.cluster;

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;

/**
* Helper class to handle Openshift token authentication response
*
*/
public class TokenExtractor {
/**
* Regular expression used to check if browser page is page that displays the OAuth token
*/
public static final Pattern TOKEN_PAGE_PATTERN = Pattern
.compile(".*<h2>Your API token is<\\/h2>.*<code>(.*)<\\/code>.*", Pattern.DOTALL);

private final Matcher matcher;
private final Document doc;

public TokenExtractor(String content) {
matcher = TOKEN_PAGE_PATTERN.matcher(content);
}
public TokenExtractor(String content) {
doc = Jsoup.parse(content);
}

public boolean isTokenPage() {
return matcher.matches();
}
public boolean isTokenPage() {
return doc.select("h2").text().contains("Your API token is");
}

public String getToken() {
return matcher.group(1);
}
public String getToken() {
return doc.select("h2").next().select("code").text();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,24 @@
import java.util.regex.Pattern;

public class CountryCodeValidator implements Supplier<ValidationInfo> {
private final JTextComponent component;
private final JTextComponent component;

/*
* see https://github.com/codeready-toolchain/registration-service/blob/master/pkg/assets/landingpage.js
*/
private static final Pattern pattern = Pattern
.compile("^[+]?\\d+$");
private static final Pattern pattern = Pattern
.compile("^[+]?\\d{1,3}$");

public CountryCodeValidator(JTextComponent component) {
this.component = component;
}
public CountryCodeValidator(JTextComponent component) {
this.component = component;
}

@Override
public ValidationInfo get() {
String text = component.getText();
if (text.isEmpty()) {
return new ValidationInfo("Please provide a country code", component);
}
if (pattern.matcher(text).matches()) {
return null;
}
return new ValidationInfo("Country code must be a number", component);
@Override
public ValidationInfo get() {
String text = component.getText();
if (text.isEmpty()) {
return new ValidationInfo("Please provide a country code", component);
}
if (pattern.matcher(text).matches()) {
return null;
}
return new ValidationInfo("Country code must be a number", component);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@
import java.util.regex.Pattern;

public class PhoneNumberValidator implements Supplier<ValidationInfo> {
private final JTextComponent component;
private final JTextComponent component;

/*
* see https://github.com/codeready-toolchain/registration-service/blob/master/pkg/assets/landingpage.js
*/
private static final Pattern pattern = Pattern
.compile("^[(]?[0-9]+[)]?[-\\s\\.]?[0-9]+[-\\s\\.\\/0-9]*$", Pattern.CASE_INSENSITIVE);
private static final Pattern pattern = Pattern
.compile("^[(]?\\d{2,3}[)]?[ \\-./]?\\d{2,3}[ \\-./]?\\d{2,4}[ \\-./]?\\d{0,4}[ \\-./]?\\d{0,4}$", Pattern.CASE_INSENSITIVE);

public PhoneNumberValidator(JTextComponent component) {
this.component = component;
}
public PhoneNumberValidator(JTextComponent component) {
this.component = component;
}

@Override
public ValidationInfo get() {
String text = component.getText();
if (text.isEmpty()) {
return new ValidationInfo("Please provide a phone number", component);
}
if (pattern.matcher(text).matches()) {
return null;
}
return new ValidationInfo("Phone number should be digits optionally separated by - or ' '", component);
@Override
public ValidationInfo get() {
String text = component.getText();
if (text.isEmpty()) {
return new ValidationInfo("Please provide a phone number", component);
}
if (pattern.matcher(text).matches()) {
if (text.chars().allMatch(Character::isDigit) && text.length() < 7) {
return new ValidationInfo("Phone number should be at least 7 digits", component);
}
return null;
}
return new ValidationInfo("Phone number should be digits optionally separated by space or '-' or '.' or '/'", component);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,107 +20,106 @@
*/
public final class OCCommandUtils {

private OCCommandUtils() {
//hide constructor
}
private OCCommandUtils() {
//hide constructor
}

/**
* Validates is oc command is in correct format with required fields.
*
* @param ocCommand the oc command
* @return false command has not correct format
*/
public static boolean isValidCommand(String ocCommand) {
ocCommand = ocCommand.trim();
return (ocCommand.startsWith("oc login ") && isValidAuthMethod(ocCommand)
&& getServer(ocCommand) != null);
}
/**
* Validates is oc command is in correct format with required fields.
*
* @param ocCommand the oc command
* @return false command has not correct format
*/
public static boolean isValidCommand(String ocCommand) {
ocCommand = ocCommand.trim();
return (ocCommand.startsWith("oc login ") && isValidAuthMethod(ocCommand)
&& getServer(ocCommand) != null);
}

/**
* Returns true if authorization schema of oc command is valid (basic/OAuth).
*
* @param ocCommand the oc command
* @return false command has not correct authorization schema
*/
public static boolean isValidAuthMethod(String ocCommand) {
ocCommand = ocCommand.trim();
return (ocCommand.contains(" -u") || ocCommand.contains(" --username") || ocCommand.contains("--token="));
}
/**
* Returns true if authorization schema of oc command is valid (basic/OAuth).
*
* @param ocCommand the oc command
* @return false command has not correct authorization schema
*/
private static boolean isValidAuthMethod(String ocCommand) {
return (ocCommand.contains(" -u") || ocCommand.contains(" --username") || ocCommand.contains("--token="));
}

/**
* Parses server address from oc command.
*
* @param ocCommand the oc command
* @return server address
*/
public static String getServer(String ocCommand) {
String server = applyPattern(ocCommand, "(?<=\\s)https[a-zA-Z0-9:/.-]+", 0);
if (server != null) {
return server;
} else {
return applyPattern(ocCommand, "(?<=[\\s=])https[a-zA-Z0-9:/.-]+", 0);
}
/**
* Parses server address from oc command.
*
* @param ocCommand the oc command
* @return server address
*/
public static String getServer(String ocCommand) {
String server = applyPattern(ocCommand, "(?<=\\s)https[a-zA-Z0-9:/.-]+", 0);
if (server != null) {
return server;
} else {
return applyPattern(ocCommand, "(?<=[\\s=])https[a-zA-Z0-9:/.-]+", 0);
}
}

/**
* Parses token from oc command.
*
* @param ocCommand the oc command
* @return token
*/
public static String getToken(String ocCommand) {
return applyPattern(ocCommand, "(?<=--token=)[~a-zA-Z0-9:._-]+", 0);
}
/**
* Parses token from oc command.
*
* @param ocCommand the oc command
* @return token
*/
public static String getToken(String ocCommand) {
return applyPattern(ocCommand, "(?<=--token=)[~a-zA-Z0-9:._-]+", 0);
}

/**
* Parses username from oc command.
*
* @param ocCommand the oc command
* @return username
*/
public static String getUsername(String ocCommand) {
String username = applyPattern(ocCommand, "(?<=-u[\\s=])[a-zA-Z0-9:]+", 0);
if (username != null) {
return username;
} else {
return applyPattern(ocCommand, "(?<=--username[\\s=])[a-zA-Z0-9:]+", 0);
}
/**
* Parses username from oc command.
*
* @param ocCommand the oc command
* @return username
*/
public static String getUsername(String ocCommand) {
String username = applyPattern(ocCommand, "(?<=-u[\\s=])[a-zA-Z0-9:]+", 0);
if (username != null) {
return username;
} else {
return applyPattern(ocCommand, "(?<=--username[\\s=])[a-zA-Z0-9:]+", 0);
}
}

/**
* Parses password from oc command.
*
* @param ocCommand the oc command
* @return password
*/
public static String getPassword(String ocCommand) {
String password = searchInStringForPattern(ocCommand, "(?<=-p[\\s=])(.*)(?=\\b)");
if (password != null) {
return password;
} else {
return searchInStringForPattern(ocCommand, "(?<=--password[\\s=])(.*)(?=\\b)");
}
/**
* Parses password from oc command.
*
* @param ocCommand the oc command
* @return password
*/
public static String getPassword(String ocCommand) {
String password = searchInStringForPattern(ocCommand, "(?<=-p[\\s=])([^\\s ]*)(?=\\b)");
if (password != null) {
return password;
} else {
return searchInStringForPattern(ocCommand, "(?<=--password[\\s=])([^\\s ]*)(?=\\b)");
}
}

private static String searchInStringForPattern(String stringToVerify, String pattern) {
if (stringToVerify.contains("-p")) {
return applyPattern(stringToVerify, pattern);
}
return null;
private static String searchInStringForPattern(String stringToVerify, String pattern) {
if (stringToVerify.contains("-p")) {
return applyPattern(stringToVerify, pattern);
}
return null;
}

private static String applyPattern(String stringToVerify, String pattern) {
return applyPattern(stringToVerify, pattern, 1);
}
private static String applyPattern(String stringToVerify, String pattern) {
return applyPattern(stringToVerify, pattern, 1);
}

private static String applyPattern(String stringToVerify, String pattern, int group) {
stringToVerify = stringToVerify.trim();
Pattern patternToken = Pattern.compile(pattern);
java.util.regex.Matcher matcherToken = patternToken.matcher(stringToVerify);
if (matcherToken.find()) {
return matcherToken.group(group);
}
return null;
private static String applyPattern(String stringToVerify, String pattern, int group) {
stringToVerify = stringToVerify.trim();
Pattern patternToken = Pattern.compile(pattern);
java.util.regex.Matcher matcherToken = patternToken.matcher(stringToVerify);
if (matcherToken.find()) {
return matcherToken.group(group);
}
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2024 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.intellij.openshift.ui.cluster;


import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class TokenExtractorTest {

@Test
public void checkTokenExtractionOk() {
String contents = "<html><head></head><body><h2>Your API token is</h2>\n <code>sha256~abcd-1234567890ABCDEF</code>\n</body></html>";
TokenExtractor extractor = new TokenExtractor(contents);
assertTrue(extractor.isTokenPage());
assertEquals("sha256~abcd-1234567890ABCDEF", extractor.getToken());
}

@Test
public void checkTokenExtractionEmpty() {
String contents = "<html><head></head><body><h2>Your API token is</h2>\n <code></code>\n</body></html>";
TokenExtractor extractor = new TokenExtractor(contents);
assertTrue(extractor.isTokenPage());
assertEquals("", extractor.getToken());
}

@Test
public void checkTokenExtractionFails() {
String contents = "<html><head></head><body></body></html>";
TokenExtractor extractor = new TokenExtractor(contents);
assertFalse(extractor.isTokenPage());
}

@Test
public void checkTokenExtractionWithMultipleH2() {
String contents = "<html><head></head><body><h2>Your API token is</h2>\n <code>sha256~abcd-1234567890ABCDEF</code>\n<h2>Log in with this token</h2>\n<pre>oc login <span class=\"nowrap\">--token=sha256~abcd-1234567890ABCDEF</span> <span class=\"nowrap\">--server=https://url.com:1234</span></pre></body></html>";
TokenExtractor extractor = new TokenExtractor(contents);
assertTrue(extractor.isTokenPage());
assertEquals("sha256~abcd-1234567890ABCDEF", extractor.getToken());
}
}
Loading

0 comments on commit d92992d

Please sign in to comment.