Skip to content
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

User authentication service #439

Open
wants to merge 8 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package de.cognicrypt.codegenerator.generator.test;

import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.logging.Logger;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import de.cognicrypt.codegenerator.generator.CodeGenerator;
import de.cognicrypt.codegenerator.generator.CrySLBasedCodeGenerator;
import de.cognicrypt.codegenerator.tasks.Task;
import de.cognicrypt.codegenerator.testutilities.TestUtils;
import de.cognicrypt.codegenerator.wizard.Configuration;
import de.cognicrypt.utils.DeveloperProject;

/**
* @author Shahrzad Asghari
*/
public class UserAuthManagerCodeGenTest {
private Logger log = Logger.getLogger(UserAuthManagerCodeGenTest.class.getName());
private IJavaProject testJavaProject;
private CodeGenerator generatorAuthManager;
private Task authManagerTask;
private Configuration configAuthManager;
private DeveloperProject developerProject;
private IResource targetFile;
private ICompilationUnit testClassUnit;
// private String taskName = "UserAuthorityManager";
Task taskName = TestUtils.getTask("UserAuthorityManager");

@After
public void tearDown() throws CoreException {
TestUtils.deleteProject(this.testJavaProject.getProject());
}

@Before
public void setUp() throws Exception {
this.testJavaProject = TestUtils.createJavaProject(CodeGenTestConstants.PROJECT_NAME);
targetFile = TestUtils.generateJavaClassInJavaProject(this.testJavaProject, CodeGenTestConstants.PACKAGE_NAME,
CodeGenTestConstants.CLASS_NAME);
this.authManagerTask = TestUtils.getTask("UserAuthorityManager");
this.generatorAuthManager = new CrySLBasedCodeGenerator(targetFile);
this.developerProject = this.generatorAuthManager.getDeveloperProject();
this.testClassUnit = TestUtils.getICompilationUnit(this.developerProject, CodeGenTestConstants.PACKAGE_NAME,
CodeGenTestConstants.JAVA_CLASS_NAME);
TestUtils.openJavaFileInWorkspace(this.developerProject, "testPackage", this.testClassUnit);

}

/**
* Scenario: User chooses User Authentication manager task and on the first pages
* chooses the second answer to generate user authentication service.
*
* @throws CoreException.
* @throws IOException this exception happens if an I/O error appears while creating and copying a file in createCrySLConfiguration.
* @throws CoreException this exceptions happens when the project does not exist or is not open.
*/
@Test
public void testCodeGenerationUserAuthentication() throws IOException, CoreException {
this.configAuthManager = TestUtils.createCrySLConfiguration("userauthoritymanagerauth", testClassUnit.getResource(),
generatorAuthManager, this.developerProject, taskName);
final boolean encCheck = this.generatorAuthManager.generateCodeTemplates(this.configAuthManager,
this.authManagerTask.getAdditionalResources());

assertTrue(encCheck);
}

/**
* Scenario: User chooses User Authentication manager task and on the first pages
* chooses the first answer to generate a password generator service.
*
* @throws CoreException this exceptions happens when the project does not exist or is not open.
* @throws IOException this exception happens if an I/O error appears while creating and copying a file in createCrySLConfiguration.
*/
@Test
public void testCodeGenerationPassGenerator() throws CoreException, IOException {
this.configAuthManager = TestUtils.createCrySLConfiguration("userauthoritymanagerpassgen", testClassUnit.getResource(),
generatorAuthManager, this.developerProject, taskName);
final boolean encCheck = this.generatorAuthManager.generateCodeTemplates(this.configAuthManager,
this.authManagerTask.getAdditionalResources());

assertTrue(encCheck);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class CrySLCodeGenerator implements RuleContext, BeforeRuleContext {

private RuleGenConfig last = null;
private List<RuleGenConfig> ruleConfigs;
private String customMain;

private CrySLCodeGenerator() {}

Expand Down Expand Up @@ -45,4 +46,8 @@ private void resolveLast() {
last = null;
}
}
public CrySLCodeGenerator setCustomMain(String customMain) {
this.customMain = customMain;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ public interface RuleContext {
public RuleContext includeClass(String rule);

public boolean generate();

public CrySLCodeGenerator setCustomMain(String string);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/********************************************************************************
* Copyright (c) 2015-2021 TU Darmstadt, Paderborn University
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
package de.cognicrypt.codegenerator.crysl.templates.userauthoritymanagerauth;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Base64;

import de.cognicrypt.codegenerator.crysl.CrySLCodeGenerator;

/**
* The Class UserAuthentication verifies the users input, the username and password.
*/
public class UserAuthentication {
//hash and salt will be stored as string
/**
* Takes username and password as inputs to verifies the password. Connects to the MySQL database
* and retrieves the hashed password and salt for the desired username and makes a new hash from the input password
* with the same salt, then checks the equality of the hash in the database and the new hash. If the username does not
* exist in the database, it throws an exception. Users may modify the database's username, password, URL and tableName to their own.
* Usernames and Passwords are all considered to be unique.
* note: SQL must be installed.
*
* @param username the input username to be searched in the database.
* @param pwd the input password for that username, the correction of this password will be checked by this method.
* @return true, if the username exists and the input password is correct.
* @throws Exception This exception is thrown if the username does not exist in the database.
* @throws ClassNotFoundException This exception is thrown if MySQL jar file is not in the buildpath. It contains the class "com.mysql.cj.jdbc.Driver".
* @throws GeneralSecurityException This exception is thrown if a security-related exception happens that extends this general exception.
* @throws InvalidKeySpecException This exception is thrown when key specifications are invalid.
*/
//for this to work, sql must be installed and put in env path
public static boolean userAuth(String username, char[] pwd) throws Exception {
String databaseUsername = "root";
String databasePassword = "test";
String databaseURL = "jdbc:mysql://localhost:3306/myDatabase";
String tableName = " mytb ";

Boolean result = false;

String salt = "" ;
String hash = "";

int iterationCount = 65536;
int keysize = 128;

byte[] hashedPwd = null;

Class.forName("com.mysql.cj.jdbc.Driver");

Connection connection = DriverManager.getConnection(databaseURL, databaseUsername, databasePassword);

Statement stmt = connection.createStatement();
String SQL = "SELECT * FROM" + tableName + "WHERE USERNAME='" + username + "'";
ResultSet queryResult = stmt.executeQuery(SQL);
if (queryResult.isBeforeFirst()) {
while (queryResult.next()) {
salt = queryResult.getString("salt");
hash = queryResult.getString("hash");
}
}else {
throw new Exception("User not found");
}

byte [] bytedSalt = Base64.getDecoder().decode(salt);

CrySLCodeGenerator.getInstance().includeClass("javax.crypto.spec.PBEKeySpec")
.addParameter(pwd, "password").addParameter(keysize, "keylength").addParameter(iterationCount, "iterationCount")
.addParameter(bytedSalt, "salt").includeClass("javax.crypto.SecretKeyFactory").includeClass("javax.crypto.SecretKey")
.addParameter(hashedPwd, "this").generate();

String hashedPwdString = Base64.getEncoder().encodeToString(hashedPwd);

if (hash.equals(hashedPwdString)) {
result = true;}
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/********************************************************************************
* Copyright (c) 2015-2021 TU Darmstadt, Paderborn University
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
********************************************************************************/
package de.cognicrypt.codegenerator.crysl.templates.userauthoritymanagerpassgen;

import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


import de.cognicrypt.codegenerator.crysl.CrySLCodeGenerator;

/**
* The Class PassGenerator generates a secure password that meets all requirements
* for a standard password described in NIST (National Institute of Standards and Technology).
*/

public class PassGenerator {

/**
* Generates a secure random password of length 12. This password consists of numbers, symbols, uppercase and lowercase
* letters that are randomly distributed in the password. The length of the password must be equal to or more than 4, cause it must include
* one of each set of characters.
*
* @return the password.
* @throws GeneralSecurityException This exception is thrown if a security-related exception happens that extends this general exception.
* @throws NoSuchAlgorithmException This exception is thrown if no Provider supports a SecureRandomSpi implementation for the specified algorithm. {@link #generateRandomCharacter(String) generateRandomCharacter}
*/
public static String generateRandomPassword() throws NoSuchAlgorithmException, GeneralSecurityException
{
int length = 12;
final String capitalAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
final String smallAlphabet = "abcdefghijklmnopqrstuvwxyz";
final String numbers = "0123456789";
//removed dot slashes and quotations- library
final String specialChars = "~!@#$%^&*()-_=+[{]};:,<>?";
final String allCases = capitalAlphabet + smallAlphabet + numbers + specialChars;

List<String> password = new ArrayList<String>();

password.add(generateRandomCharacter(capitalAlphabet));
password.add(generateRandomCharacter(smallAlphabet));
password.add(generateRandomCharacter(numbers));
password.add(generateRandomCharacter(specialChars));

for (int i = 4; i < length; i++) {
password.add(generateRandomCharacter(allCases));
}
// relocate each character in password
Collections.shuffle(password);
return String.join("", password);
}

/**
* Generates a random integer (randIndex) in range of length of characters (e.g. 10 in numbers)
* and returns the randIndex'th item of the list of characters.
*
* @param chars the character, e.g., upper case letters.
* @return the string one character from the character set that is randomly selected.
* @throws GeneralSecurityException This exception is thrown if a security-related exception happens that extends this general exception.
* @throws NoSuchAlgorithmException This exception is thrown if no Provider supports a SecureRandomSpi implementation for the specified algorithm.
*/
public static String generateRandomCharacter(String chars) throws NoSuchAlgorithmException, GeneralSecurityException{

int length = chars.length();
int randIndex = 0;
CrySLCodeGenerator.getInstance().includeClass("java.security.SecureRandom").addParameter(length, "range").addParameter(randIndex, "randIntInRange").setCustomMain("generateRandomPassword").generate();
return String.valueOf(chars.charAt(randIndex));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -429,10 +429,14 @@ private void generateTemplateUsageBody(Set<GeneratorClass> generatedClasses, Gen

List<Entry<String, String>> declaredVariables = new ArrayList<>();
declaredVariables.addAll(tmplUsage.getParameters());
//check if there is a custom main method in the class
for (GeneratorMethod gen : generatedClass.getMethods()) {
if (gen.getRules().isEmpty()) {
continue;
if (generatedClass.getCustomMain() != null) {
if (!gen.getName().equals(generatedClass.getCustomMain())) {
continue;
}
}
else if (gen.getRules().isEmpty()) {continue;}

tmplUsage.addExceptions(gen.getExceptions());
String returnType = gen.getReturnType();
Expand Down Expand Up @@ -1324,6 +1328,9 @@ public boolean visit(MethodInvocation node) {
methLims.put(1, node.getStartPosition() + node.getLength());
} else if ("getInstance".equals(calledMethodName)) {
methLims.put(0, node.getStartPosition() - "CrySLCodeGenerator.".length());
}else if ("setCustomMain".equals(calledMethodName)) {
String cMain = Utils.filterQuotes(arguments.get(0).toString());
templateClass.setCustomMain(cMain);
}
return super.visit(node);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,11 @@ public class GeneratorClass {
private String modifier;
private String className;
private List<GeneratorMethod> methods;
private File associatedFile;
private File associatedFile;
private String customMain;
private String header = "";
private String classJavaDoc = "";


public GeneratorClass() {
imports = new HashSet<String>();
Expand Down Expand Up @@ -138,5 +140,13 @@ public String toString() {
classContent.append("}");
return classContent.toString();
}
public void setCustomMain(String cMain) {
this.customMain = cMain;

}

public String getCustomMain() {
return this.customMain;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[{
"id": "0",
"content": [{
"id": "0",
"element": "radio",
"questionText": "Which of the following tasks do you wish to generate?",
"answers": [ {
"value": "A secure random password generator",
"option": "passgen",
"defaultAnswer": true
},
{
"value": "User Authentication service that checks user's username and password from SQL database",
"option": "auth",
"nextID": "-1"
}]
}],
"nextID": "-1"
}]
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@
"codeGen": "XSL",
"isSelected": false
},
{
"name": "UserAuthorityManager",
"description": "User authorization and secure password generator",
"taskDescription": "Cognicrypt provides a secure username and password and verifies the validity of a given username and password in this usecase.",
"image": "authManager",
"codeGen": "CrySL",
"isSelected": false
},
{
"name": "TestCryslTask",
"description": "TestCryslTask",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.