I have written a very simple program that reads in a username and password from a text file, where the username and password are separated by a comma. The contents of the text file contains the following
accounts.txt
Alex,1234
David,5678
My java application is written as follows
public class Authenticate {
public void signIn(String username, String password) throws IOException {
FileReader fr = new FileReader("location/accounts.txt");
BufferedReader br = new BufferedReader(fr);
while (true) {//read file line by line
String line = br.readLine();
if (line == null) {
break;
}
String splitByComma = ",";
String[] details = line.split(splitByComma);
String registeredUser = details[0];
String registeredPass= details[1];
if(username.equals(registeredUser) && password.equals(registeredPass)){
System.out.println("signed in successfully!");
}
else{
System.out.println("sign in failed");
}
}
br.close();
}
}
My App class which called the program:
public class App {
public static void main(String[] args) throws IOException {
Register register = new Register("location/accounts.txt");
Authenticate auth = new Authenticate();
auth.signIn("David", "5678");
}
}
The problem is when I pass in "Alex" "1234" in method for example, the output is
signed in successfully!
sign in failed
And when I pass in "David" "5678" i get
sign in failed
signed in successfully!
I want the application to output "signed in successfully" and "sign in failed" only once depending on the credentials entered.
Many thanks!
This means you are calling your method twice with different values. Check the calling code (which you haven't provided to us).
Other remarks:
Please don't consider something like this for serious authentication. Passwords should at least be hashed in your file (for example using BCrypt). There are many frameworks which offer industry strength authentication solutions which you should use instead of 'rolling your own'.
You should close resources in one of these ways:
1) in a finally block:
BufferedReader br = null;
try {
br = new BufferedReader(...);
// do stuff
}
finally {
if (br != null) {
br.close();
}
}
2) using the Java 8 try-with-resources idiom:
try (BufferedReader br = new BufferedReader(...)) {
// do stuff
}
(the BufferedReader will be automatically closed by the runtime environment)
In your example above you should probably check the input for null values before checking the values with .equals.
First search for the user name. Once found, check the password and exit the loop:
public class Authenticate {
public void signIn(String username, String password) throws IOException {
try (
FileReader fr = new FileReader("location/accounts.txt");
BufferedReader br = new BufferedReader(fr);
) {
boolean success = false;
String line;
while ((line = br.readLine()) != null) {
String[] details = line.split(",");
String registeredUser = details[0];
if (registeredUser.equals(username)) {
String registeredPass = details[1];
success = registeredPass.equals(password);
break;
}
}
System.out.println(success ? "signed in successfully!" : "sign in failed");
}
}
}
Related
I am having a bit of an issues trying to pass in a file read by my program and sorted accordantly. I am not used to working with files, and i ran out of ideas as to how this could be achieved.
/////////////////////////////////////// class reads file ///////////////////////////////////
import java.io.*;
public class InFileReader {
private BufferedReader inputStream = null;
private String fileLine;
private StringBuilder sb;
public String getFile(File fileRead) throws FileNotFoundException,
IOException {
inputStream = new BufferedReader(new FileReader(fileRead)); //reads files
sb = new StringBuilder();
while((fileLine = inputStream.readLine()) != null){//keep reading lines in file till there is none
sb.append(fileLine).append("\n");
}
return sb.toString(); //returns StringBuffer read values in String form
}
}
///////////////////////////////////////////////////// end of read file class ///////////////////////
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
try {
String input = fileReader.getFile(fileRead.getAbsoluteFile());
HashMap<Integer, Thing.Ship> hashmap = new HashMap<>();
while (!input.isEmpty()) { // as long as there is data in the file keep looping
Scanner sc = new Scanner(input); // scan file
if (!input.startsWith("//")) { // take out "//" from directory
String type = "";
if (sc.hasNext()) { // if there are character lines get next line
type = sc.next();
}
if (type.equalsIgnoreCase("port")) { // looks for "port"
world.assignPort(new Thing.SeaPort(sc)); // assigns value to Seaport
} else if (type.equalsIgnoreCase("dock")) {
world.assignDock(new Thing.Dock(sc));
} else if (type.equalsIgnoreCase("ship")) {
Thing.Ship s = new Thing.Ship(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("pship")) {
Thing.Ship s = new Thing.PassengerShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("cship")) {
Thing.Ship s = new Thing.CargoShip(sc);
hashmap.put(s.getIndex(), s);
world.assignShip(s);
} else if (type.equalsIgnoreCase("person")) {
world.assignPerson(new Thing.Person(sc));
}
}
}
//inputOut.setText(type);
inputOut.setText(world.toString());
} catch (Exception e) {
System.out.println(e + "-----");
}
}
Here fileRead knows where to find the file to be read "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt"
public void getFile(File fileRead) throws FileNotFoundException,
IOException {
this is where things just fall apart:
String input = fileReader.getFile(fileRead.getAbsoluteFile());
My intent here is to pass the location of the file so that the getFile class can read it and then be sorted into the hashmap.
again i am not familiar with how to work with file, any suggestion or comment would be greatly appreciated.
thank you in advanced.
If you get a FileNotFoundException then the file was not found.
You say the filename was "C:\Users\abe\IdeaProjects\CreateSeaPortDataFile\src\text.txt".
If you type that name in the code you must escape the backslash:
"C:\\Users\\abe\\IdeaProjects\\CreateSeaPortDataFile\\src\\text.txt".
I have been trying to compare the file content with user input. The program is reading from a specific file and it checks against the user's string input. I am having trouble comparing the ArrayList with the user input.
public class btnLoginListener implements Listener
{
#Override
public void handleEvent(Event arg0)
{
//variables for the class
username = txtUsername.getText();
password = txtPassword.getText();
MessageBox messageBox = new MessageBox(shell, SWT.OK);
try {
writeFile();
messageBox.setMessage("Success Writing the File!");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when writing the file!");
}
try {
readFile("in.txt");
} catch (IOException x)
{
messageBox.setMessage("Something bad happened when reading the file!" + x);
}
if (username.equals(names))
{
messageBox.setMessage("Correct");
}
else
{
messageBox.setMessage("Wrong");
}
messageBox.open();
}
}
private static void readFile(String fileName) throws IOException
{
//use . to get current directory
File dir = new File(".");
File fin = new File(dir.getCanonicalPath() + File.separator + fileName);
// Construct BufferedReader from FileReader
BufferedReader br = new BufferedReader(new FileReader(fin));
String line = null;
while ((line = br.readLine()) != null)
{
Collections.addAll(names, line);
}
br.close();
}
I am assuming you are trying to check whether an element exists in the list. If yes, then you need to use contains method, here's the Javadoc.
So, instead of using if (username.equals(names)), you can use if (names.contains(username)).
Apart from this, you should make the following changes:
Don't read the file every time an event is called. As you are reading a static file, you can read it once and store it in an ArrayList.
Make variables username and password local.
Remove writeFile() call unless it's appending/writing dynamic values on each event.
I have 3 classes (Client, Server, and Protocol) that allow a user to login and send a message to another user. I'm trying to add a password feature to the program but nothing I've tried has worked so far. I've added my code below, I want to prompt the user to put the password in after the error checking on the username has been done. The password should be compared and checked that it is a match, and only then should the user be able to view their messages and send messages.
Any tips would really be appreciated, thanks!
Client.java
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
String messages = "";
// Makes sure there are only two arguments entered
if(args.length != 2) {
System.err.println("Usage: java Client <host name> <port number>");
System.exit(1);
}
// Stores the command line arguments for readability further in the program
String host = args[0];
int port = Integer.parseInt(args[1]);
try (
// Creates the socket to be used
Socket s = new Socket(host, port);
// Reader and Writer to talk with Server
PrintWriter pw =
new PrintWriter(s.getOutputStream(), true);
BufferedReader bf = new BufferedReader(
new InputStreamReader(s.getInputStream()));
) {
// Reader to read from standard input (keyboard)
BufferedReader keyboard =
new BufferedReader(new InputStreamReader(System.in));
// User interface
while (true) {
System.out.println("Please enter your username: ");
String username = keyboard.readLine();
// Check that the login is valid
if (username == null) {
System.out.println("No username entered");
}
else if (username.contains(" ")) {
System.out.println("Username cannot contain spaces");
}
// Send username to server and return number of messages
else {
pw.println(username);
messages = bf.readLine();
System.out.println("You have " + Integer.parseInt(messages) + " messages");
break;
}
}
// Enable the user to continue reading and composing messages until
// they choose to exit
while (true) {
System.out.println("Would you like to READ, COMPOSE or EXIT?");
String choice = keyboard.readLine();
// Shows the messages left for the user
if (choice.equals("READ")) {
pw.println("READ");
messages = bf.readLine();
if (messages == "0") {
System.out.println("NO MESSAGES");
}
else {
String incoming = bf.readLine();
System.out.println(incoming);
incoming = bf.readLine();
System.out.println(incoming);
}
}
// Allows user to write a message to another user
else if (choice.equals("COMPOSE")) {
pw.println("COMPOSE");
System.out.println("Enter message recipient");
String recipient = keyboard.readLine();
if (recipient == null) {
System.out.println("No recipient username entered");
}
else if (recipient.contains(" ")) {
System.out.println("Recipient username cannot contain spaces");
}
else {
pw.println(recipient);
System.out.println("Enter message to be sent");
String im = keyboard.readLine();
pw.println(im);
System.out.println(bf.readLine());
}
}
else if (choice.equals("EXIT")) {
pw.println("EXIT");
System.exit(1);
}
else {
System.out.println("Error: you must either READ, COMPOSE or EXIT");
}
}
}
// Catches the exception in which the server cannot be found
catch(IOException e) {
System.out.println("Error, could not connect to Server");
System.exit(1);
}
}
}
Server.java
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
String request;
// Makes sure that the user has specified the correct number of command line arguments
if(args.length != 1) {
System.err.println("Usage: java Server <port number>");
System.exit(1);
}
int port = Integer.parseInt(args[0]);
try (
// Creates a server socket and waits for a connection
ServerSocket ss = new ServerSocket(port);
// A socket to communicate with the client
Socket cs = ss.accept();
// Reader and Writer to talk with Client
PrintWriter pw =
new PrintWriter(cs.getOutputStream(), true);
BufferedReader bf = new BufferedReader(
new InputStreamReader(cs.getInputStream()));
)
// Links the server to the protocol
{
Protocol protocol = new Protocol();
protocol.storeUsername(bf.readLine());
pw.println(protocol.messagesNumber());
// Loop through user input until EXIT is entered
while (true) {
request = bf.readLine();
// Controls output if user inputs READ
if (request.equals("READ")) {
pw.println(protocol.messagesNumber());
pw.println(protocol.readSender());
pw.println(protocol.readMessage());
}
// Controls input if user inputs COMPOSE
else if (request.equals("COMPOSE")) {
String sender = bf.readLine();
String message = bf.readLine();
if (protocol.append(sender, message)) {
pw.println("MESSAGE SENT");
}
else {
pw.println("MESSAGE FAILED");
}
}
// Exits the server
else {
System.exit(1);
}
}
}
// Catches the exception in which the server cannot find a client
catch(IOException e) {
System.out.println("Failed to find a client");
System.exit(1);
}
}
}
Protocol.java
import java.net.*;
import java.io.*;
import java.util.*;
public class Protocol {
private String username;
private String recipient;
private String sender;
private HashMap<String, ArrayList<String>> senderMap = new HashMap<String, ArrayList<String>>();
private HashMap<String, ArrayList<String>> messageMap = new HashMap<String, ArrayList<String>>();
// Stores the username for the logged in user
public void storeUsername(String user) {
username = user;
}
// Stores the recipient name
public void storeRecipient(String name) {
recipient = name;
}
// Returns how many messages the logged in user has
public int messagesNumber() {
if(messageMap.containsKey(username))
return messageMap.get(username).size();
else
return 0;
}
public boolean append(String recipient, String message) {
boolean success = false;
// If there is an entry for that name, just add the message to the end
if(messageMap.containsKey(recipient)) {
senderMap.get(recipient).add(username);
messageMap.get(recipient).add(message);
success = true;
}
// If there is no entry for that name, create a new entry with a list of messages and add the first message
else {
senderMap.put(recipient, new ArrayList<String>());
senderMap.get(recipient).add(username);
messageMap.put(recipient, new ArrayList<String>());
messageMap.get(recipient).add(message);
success = true;
}
return success;
}
public String readSender() {
// If the user has an entry and has at least 1 sender, return the least recent sender and then remove it (the sender first in the list)
if(senderMap.containsKey(username)) {
if(senderMap.get(username).size() > 0) {
String temp = senderMap.get(username).get(0);
senderMap.get(username).remove(0);
return temp;
}
else
// If there are no messages left to read
return "NO MESSAGES";
}
else
// If the login hasn't been created yet
return "NO MESSAGES";
}
public String readMessage() {
// If the user has an entry and has at least 1 unread message, return the least recent unread message and then remove it (the first message in the list)
if(messageMap.containsKey(username)) {
if(messageMap.get(username).size() > 0) {
String temp = messageMap.get(username).get(0);
messageMap.get(username).remove(0);
return temp;
}
else
// If there are no messages left to read
return "NO MESSAGES";
}
else
// If the login hasn't been created yet
return "NO MESSAGES";
}
}
I want to query user credentials against an Active Directory without the user entering his credentials. i.e The user logs into his corporate system(Intranetwork) i need to use these credentials to verify against an AD and retrieve his email address if the user exists.(NO single sign on required)
Of course, It is too late to answer, but ... someone like me can search same answer...
I'm just not sure why do you need to verify user credentials?
If user already logged-in then ... credentials are verified.
Getting his email (and other info from AD) is possible by using Windows powershell.
public class TestWindowsAD {
public static void main(String... args) throws Exception {
System.out.println("Current user e-mail: " + getCurrentUserEmail());
}
private static String getCurrentUserEmail() {
String cmd = "powershell \"Add-Type -AssemblyName System.DirectoryServices.AccountManagement;[System.DirectoryServices.AccountManagement.UserPrincipal]::Current.EmailAddress;\"";
String userEmail = "";
if (!System.getProperty("os.name").toLowerCase().startsWith("win")) { throw new RuntimeException(
"We are not in Windows! OS is " + System.getProperty("os.name")); }
Runtime rt = Runtime.getRuntime();
Process pr;
try {
pr = rt.exec(cmd);
pr.waitFor();
BufferedReader bf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String nextLine = null;
while (true) {
nextLine = bf.readLine();
if (nextLine == null) break;
userEmail = nextLine;
}
bf.close();
} catch (Exception e) {
System.err.println("Failed to get user email: " + e.getMessage());
throw new RuntimeException(e);
}
return userEmail;
}
P.S. if you need more info just run in command prompt:
powershell "Add-Type -AssemblyName System.DirectoryServices.AccountManagement;[System.DirectoryServices.AccountManagement.UserPrincipal]::Current"
and pick what you need.
I need to be prove about user-input path.
Coz when user give not folder path but file path. Program "fall down".
I understand that this is a bug but how to be ensure about user path correct.
Code:
class PathAndWord {
final String path;
final String whatFind;
PathAndWord(String path, String whatFind) {
this.path = path;
this.whatFind = whatFind;
}
boolean isProperlyInitialized() {
return path != null && whatFind != null;
}
}
public void askUserPathAndWord() {
try {
tryToAskUserPathAndWord();
} catch (IOException | RuntimeException e) {
System.out.println("Wrong input!");
e.printStackTrace();
} catch (InterruptedException e) {
System.out.println("Interrupted.");
e.printStackTrace();
}
}
private void tryToAskUserPathAndWord() throws IOException, InterruptedException {
PathAndWord pathAndWord = readPathAndWord();
if (pathAndWord.isProperlyInitialized()) {
performScan(pathAndWord, "GameOver.tmp");
System.out.println("Thank you!");
} else {
System.out.println("You did not enter anything");
}
}
private PathAndWord readPathAndWord() throws IOException {
System.out.println("Please, enter a Path and Word (which you want to find):");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String path = readPath(bufferedReader);
String whatFind = readWord(bufferedReader);
return new PathAndWord(path, whatFind);
}
private String readPath(BufferedReader bufferedReader) throws IOException {
System.out.println("Please enter a Path:");
return bufferedReader.readLine();
}
private String readWord(BufferedReader bufferedReader) throws IOException {
System.out.println("Please enter a Word:");
return bufferedReader.readLine();
}
private void performScan(PathAndWord pathAndWord, String endOfWorkFileName) throws InterruptedException {
BlockingQueue<File> queue = new LinkedBlockingQueue<File>();
File endOfWorkFile = new File(endOfWorkFileName);
CountDownLatch latch = new CountDownLatch(2);
FolderScan folderScan = new FolderScan(pathAndWord.path, queue, latch,
endOfWorkFile);
FileScan fileScan = new FileScan(pathAndWord.whatFind, queue, latch,
endOfWorkFile);
Executor executor = Executors.newCachedThreadPool();
executor.execute(folderScan);
executor.execute(fileScan);
latch.await();
}
Qustions:
How do check if user input path is correct?
If path isn't correct
to show message that path is wrong! Try again.
Able to check word - whatFind whether it's correct, too.
Does need before point do?
private String readPath(BufferedReader bufferedReader) throws IOException {
boolean ok = false;
do {
System.out.println("Please enter a Path:");
File f = new File(bufferedReader.readLine());
if(f.exists() && f.isDirectory())
ok = true;
else
System.err.println("Doesn't exist or is not a folder.");
} while(!ok);
return f.getAbsolutePath();
}
EDIT: This method does a task "read a path from user, which exists and is a directory". If the user types invalid path (non-existent or a file) the method recognizes this, warns the user and asks them again... and again and again - until they answer correctly.
It's a good custom to check data locally, if you can. When calling the method later you can be sure it returns, what you expect.