-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validate endpoints #76
Merged
skin27
merged 12 commits into
develop
from
feature/issue-75/validate-endpoints---expressions
Jan 13, 2023
Merged
Changes from 6 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
25e14a6
Create draft PR for #75
brunovg c2bb9d8
endpoint that validates expressions
brunovg 875f267
ftp endpoint
brunovg 8d4eda9
regex endpoint
brunovg 00933fb
cron endpoint
brunovg fcab053
url endpoint
brunovg ad580be
httpsCertificate endpoint
brunovg ef667d1
scripts endpoint
brunovg c151ed4
removed scope tag
brunovg 1378934
removed some system.out.println lines
brunovg 1b27ad7
refactoring the pom files
brunovg c22dee2
Merge branch 'develop' into feature/issue-75/validate-endpoints---exp…
skin27 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
dil/src/main/java/org/assimbly/dil/validation/CronValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import org.assimbly.util.error.ValidationErrorMessage; | ||
import org.quartz.CronExpression; | ||
|
||
public class CronValidator { | ||
|
||
private static final ValidationErrorMessage EMPTY_CRON_ERROR = new ValidationErrorMessage("Empty crons aren't allowed!"); | ||
|
||
public ValidationErrorMessage validate(String cronExpression) { | ||
|
||
if (cronExpression.isEmpty()) | ||
return EMPTY_CRON_ERROR; | ||
|
||
try { | ||
new CronExpression(cronExpression); | ||
} catch (Exception e) { | ||
return new ValidationErrorMessage("Cron Validation error: " + e.getMessage()); | ||
} | ||
|
||
return null; | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
dil/src/main/java/org/assimbly/dil/validation/ExpressionsValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import org.assimbly.dil.validation.beans.Expression; | ||
import org.assimbly.dil.validation.expressions.*; | ||
import org.assimbly.util.error.ValidationErrorMessage; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class ExpressionsValidator { | ||
|
||
private static final ValidationErrorMessage EMPTY_EXPRESSION_ERROR = new ValidationErrorMessage("Empty expressions aren't allowed!"); | ||
|
||
private JsonPathValidator jsonPathValidator = new JsonPathValidator(); | ||
private SimpleValidator simpleValidator = new SimpleValidator(); | ||
private XPathValidator xpathValidator = new XPathValidator(); | ||
private ConstantValidator constantValidator = new ConstantValidator(); | ||
private GroovyValidator groovyValidator = new GroovyValidator(); | ||
|
||
public List<ValidationErrorMessage> validate(List<Expression> expressions) { | ||
|
||
List<ValidationErrorMessage> validationErrors = new ArrayList<>(); | ||
|
||
if (expressions.isEmpty()) { | ||
validationErrors.add(EMPTY_EXPRESSION_ERROR); | ||
return validationErrors; | ||
} | ||
|
||
for (Expression expression : expressions) { | ||
ValidationErrorMessage error; | ||
|
||
switch(expression.getExpressionType()) { | ||
case "constant": | ||
error = constantValidator.validate(expression); | ||
break; | ||
case "groovy": | ||
error = groovyValidator.validate(expression); | ||
break; | ||
case "jsonpath": | ||
error = jsonPathValidator.validate(expression); | ||
break; | ||
case "simple": | ||
error = simpleValidator.validate(expression); | ||
break; | ||
case "xpath": | ||
error = xpathValidator.validate(expression); | ||
break; | ||
default: | ||
throw new RuntimeException("Dovetail could not validate the type of expression submitted."); | ||
} | ||
|
||
if (error != null) { | ||
validationErrors.add(error); | ||
} | ||
} | ||
|
||
if (validationErrors.isEmpty()) | ||
return null; | ||
|
||
return validationErrors; | ||
} | ||
} |
162 changes: 162 additions & 0 deletions
162
dil/src/main/java/org/assimbly/dil/validation/FtpValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import com.jcraft.jsch.Channel; | ||
import com.jcraft.jsch.JSch; | ||
import com.jcraft.jsch.JSchException; | ||
import com.jcraft.jsch.Session; | ||
import org.apache.commons.net.ftp.FTPClient; | ||
import org.apache.commons.net.ftp.FTPReply; | ||
import org.apache.commons.net.ftp.FTPSClient; | ||
import org.assimbly.dil.validation.beans.FtpSettings; | ||
import org.assimbly.util.error.ValidationErrorMessage; | ||
|
||
import java.io.BufferedWriter; | ||
import java.io.File; | ||
import java.io.FileWriter; | ||
import java.io.IOException; | ||
import java.net.ConnectException; | ||
import java.net.UnknownHostException; | ||
|
||
public class FtpValidator { | ||
|
||
private static final int TIMEOUT = 3000; | ||
private static final ValidationErrorMessage UNREACHABLE_ERROR = | ||
new ValidationErrorMessage("Cannot login into FTP from the Dovetail server!"); | ||
|
||
public ValidationErrorMessage validate(FtpSettings ftpSettings) { | ||
|
||
if (ftpSettings.getProtocol().equalsIgnoreCase("ftp")) | ||
return checkFtpConnection(ftpSettings.getUser(), ftpSettings.getPwd(), ftpSettings.getHost(), ftpSettings.getPort(), false); | ||
else if (ftpSettings.getProtocol().equalsIgnoreCase("ftps")) | ||
return checkFtpConnection(ftpSettings.getUser(), ftpSettings.getPwd(), ftpSettings.getHost(), ftpSettings.getPort(), true); | ||
else | ||
return checkSFtpConnection(ftpSettings.getUser(), ftpSettings.getPwd(), ftpSettings.getHost(), ftpSettings.getPort(), ftpSettings.getPkf(), ftpSettings.getPkfd()); | ||
} | ||
|
||
private Session setupDefaultSession(JSch jsch, String userName, String host, int port) throws JSchException { | ||
Session session = jsch.getSession(userName, host, port); | ||
session.setConfig("StrictHostKeyChecking", "no"); | ||
|
||
return session; | ||
} | ||
|
||
private ValidationErrorMessage checkSFtpConnection(String userName, String password, String host, int port, String privateKeyFilePath, String privateKeyFileData) { | ||
Session session = null; | ||
Channel channel = null; | ||
File tempFile = null; | ||
JSch jsch; | ||
|
||
try { | ||
jsch = new JSch(); | ||
|
||
session = setupDefaultSession(jsch, userName, host, port); | ||
|
||
if (password != null && !password.isEmpty()) | ||
session.setPassword(password); | ||
|
||
if (privateKeyFileData != null && !privateKeyFileData.isEmpty()) { | ||
tempFile = File.createTempFile("temp", ""); | ||
try (BufferedWriter writer = new BufferedWriter(new FileWriter(tempFile))){ | ||
writer.write(privateKeyFileData); | ||
} | ||
jsch.addIdentity(tempFile.getAbsolutePath()); | ||
} | ||
else if (privateKeyFilePath != null && !privateKeyFilePath.isEmpty()) | ||
jsch.addIdentity(privateKeyFilePath); | ||
|
||
session.connect(TIMEOUT); | ||
|
||
channel = session.openChannel("sftp"); | ||
channel.connect(); | ||
|
||
if (!channel.isConnected()) | ||
return UNREACHABLE_ERROR; | ||
|
||
} catch (Exception e) { | ||
return handleSftpException(e); | ||
} finally { | ||
if (channel != null) | ||
channel.disconnect(); | ||
if (session != null) | ||
session.disconnect(); | ||
if (tempFile != null) | ||
tempFile.delete(); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
private ValidationErrorMessage handleSftpException (Exception exception) { | ||
Throwable cause = exception.getCause(); | ||
|
||
if (cause != null) { | ||
return getMessageFromCause(cause); | ||
} else { | ||
return getMessageFromException(exception); | ||
} | ||
} | ||
|
||
private ValidationErrorMessage getMessageFromCause (Throwable cause) { | ||
if (cause instanceof ConnectException) { | ||
return new ValidationErrorMessage("Connection refused"); | ||
} else if (cause instanceof UnknownHostException) { | ||
return new ValidationErrorMessage("Host name could not be resolved"); | ||
} else { | ||
return new ValidationErrorMessage(cause.getMessage()); | ||
} | ||
} | ||
|
||
private ValidationErrorMessage getMessageFromException (Exception exception) { | ||
if (exception.getMessage().contains("ConnectException")) { | ||
return new ValidationErrorMessage("Connection refused"); | ||
} else if (exception.getMessage().contains("UnknownHostException")) { | ||
return new ValidationErrorMessage("Host name could not be resolved"); | ||
} else { | ||
return new ValidationErrorMessage(exception.getMessage()); | ||
} | ||
} | ||
|
||
private ValidationErrorMessage checkFtpConnection(String userName, String password, String host, int port, boolean secure) { | ||
FTPClient ftp = null; | ||
|
||
try { | ||
if(secure) { | ||
ftp = new FTPSClient(); | ||
} else { | ||
ftp = new FTPClient(); | ||
} | ||
|
||
ftp.connect(host, port); | ||
|
||
// After connection attempt, you should check the reply code to verify success. | ||
int reply = ftp.getReplyCode(); | ||
if (!FTPReply.isPositiveCompletion(reply)) { | ||
ftp.disconnect(); | ||
|
||
return UNREACHABLE_ERROR; | ||
} | ||
|
||
if (!ftp.login(userName, password)) { | ||
ftp.logout(); | ||
|
||
return UNREACHABLE_ERROR; | ||
} | ||
} catch (ConnectException e){ | ||
return new ValidationErrorMessage("Connection refused"); | ||
} catch (UnknownHostException e) { | ||
return new ValidationErrorMessage("Host name could not be resolved"); | ||
} catch (Exception e) { | ||
return new ValidationErrorMessage(e.getMessage()); | ||
} finally { | ||
if (ftp != null && ftp.isConnected()) { | ||
try { | ||
ftp.disconnect(); | ||
} catch (IOException ioe) { | ||
// Do nothing | ||
} | ||
} | ||
} | ||
|
||
return null; | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
dil/src/main/java/org/assimbly/dil/validation/RegexValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import org.assimbly.dil.validation.beans.Regex; | ||
import org.assimbly.util.error.ValidationErrorMessage; | ||
|
||
import java.util.AbstractMap; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
import java.util.regex.PatternSyntaxException; | ||
|
||
public class RegexValidator { | ||
|
||
public AbstractMap.SimpleEntry validate(Regex expression) { | ||
|
||
AbstractMap.SimpleEntry<Integer, String> response = null; | ||
String regex = expression.getExpression(); | ||
|
||
if (regex.isEmpty()) { | ||
return new AbstractMap.SimpleEntry(-1, "Regex cannot be empty"); | ||
} | ||
|
||
try { | ||
Pattern pattern = Pattern.compile(regex); | ||
Matcher matcher = pattern.matcher(""); | ||
response = new AbstractMap.SimpleEntry(1, String.valueOf(matcher.groupCount())); | ||
|
||
} catch (PatternSyntaxException e) { | ||
response = new AbstractMap.SimpleEntry(-1, e.getMessage()); | ||
} | ||
|
||
return response; | ||
} | ||
|
||
} |
50 changes: 50 additions & 0 deletions
50
dil/src/main/java/org/assimbly/dil/validation/UrlValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import org.assimbly.util.error.ValidationErrorMessage; | ||
|
||
import java.net.HttpURLConnection; | ||
import java.net.URL; | ||
import java.net.URLDecoder; | ||
import java.net.UnknownHostException; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
public class UrlValidator { | ||
|
||
private static final int TIMEOUT = 5000; | ||
private static final ValidationErrorMessage UNREACHABLE_ERROR = new ValidationErrorMessage("Url is not reachable from the server!"); | ||
private static final ValidationErrorMessage INVALID_URL_ERROR = new ValidationErrorMessage("Url is not valid!"); | ||
|
||
public ValidationErrorMessage validate(String url) { | ||
final HttpURLConnection httpUrlConn; | ||
|
||
try { | ||
String decodedUrl = URLDecoder.decode(url, "UTF-8"); | ||
|
||
if(!validateURL(decodedUrl)) | ||
return INVALID_URL_ERROR; | ||
|
||
httpUrlConn = (HttpURLConnection) new URL(decodedUrl).openConnection(); | ||
|
||
httpUrlConn.setRequestMethod("HEAD"); | ||
|
||
// Set timeouts in milliseconds | ||
httpUrlConn.setConnectTimeout(TIMEOUT); | ||
httpUrlConn.connect(); | ||
//need to trigger exception when no connection can be established | ||
httpUrlConn.getResponseMessage(); | ||
} catch (UnknownHostException e) { | ||
return UNREACHABLE_ERROR; | ||
} catch (Exception e) { | ||
return new ValidationErrorMessage(e.getMessage()); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
public static final boolean validateURL(String url) { | ||
Pattern regex = Pattern.compile("^(https?):\\/\\/[-a-zA-Z0-9+&@#\\/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#\\/%=~_|]"); | ||
Matcher matcher = regex.matcher(url); | ||
return matcher.find(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package org.assimbly.dil.validation; | ||
|
||
import org.assimbly.dil.validation.beans.Expression; | ||
import org.assimbly.util.error.ValidationErrorMessage; | ||
|
||
public interface Validator { | ||
|
||
ValidationErrorMessage validate(Expression expression); | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two remarks:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏻