-2

My file works the way I want, except for one issue. After it runs prompt_log_out(), if I type n for no, my code does a System.out.print() of my get_temporary_user_credentials(). So the output looks like this:

Username: griffin.keyes
Password: alphabet soup

Hello, Zookeeper!

As zookeeper, you have access to all of the animals' information and their daily monitoring logs. This allows you to track their feeding habits, habitat conditions, and general welfare.

Would you like to log out?  Please type "y" for Yes or "n" for No.
n
Username: Password: <---This is what I don't understand
Username: griffin.keyes
Password: alphabet soup
...

My desired output is the two lines below it that prompt for a username and password again. I feel like it may have something to do with my while(!logout) { statement, but I can't really think of why this might be the issue.

Here is my code:

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.security.MessageDigest;

public class Authentication{
    public static User temporary_user = new User();
    public static File admin_file = new File("admin.txt");
    public static File veterinarian_file = new File("veterinarian.txt");
    public static File zookeeper_file = new File("zookeeper.txt");
    public static int attempt_counter = 0;
    public static boolean successful_login = false;
    public static Scanner user_input = new Scanner(System.in);
    public static boolean log_out = false;

    public static void main(String []args) throws Exception{
        while (!log_out) {
            start_login();
            if (successful_login) {
                prompt_log_out();
            }
        }
    }

    public static void start_login() throws Exception {
        User[] all_users = create_users();
        attempt_counter = 0;
        successful_login = false;

        while (attempt_counter < 3  && !successful_login) {
            get_temporary_user_credentials(user_input);
            for (User u : all_users) {
                if (temporary_user.username.equals(u.username)) {
                    if (temporary_user.encrypted_password.equals(u.encrypted_password)) {
                        print_file(u.role);
                        successful_login = true;
                        break;
                    }
                }
            }
            attempt_counter++;
        }

        if (attempt_counter == 3 && !successful_login) {
            //user_input.close();
            log_out = true; 
            System.out.println(); //prints out a blank line for easier readability
            System.out.println("You have made too many unsuccessful attempts.  The program will now exit.");
        }
    }

    public static void prompt_log_out(){
        System.out.println(); //prints out a blank line for easier readability
        System.out.println("Would you like to log out?  Please type \"y\" for Yes or \"n\" for No.");
        if ("y".equals(user_input.next())) {
            log_out = true;
        }
    }

    public static void get_temporary_user_credentials(Scanner user_input) throws Exception{
        System.out.print("Username: ");
        temporary_user.username = user_input.nextLine();
        System.out.print("Password: ");
        temporary_user.encrypted_password = encrypt(user_input.nextLine());
    }

    public static void check_credentials() {

    }

    public static String encrypt(String original) throws Exception {
        StringBuffer sb = new StringBuffer();
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(original.getBytes());
        byte[] digest = md.digest();
        for (byte b : digest) {
            sb.append(String.format("%02x", b & 0xff));
        }
        return sb.toString();
    }

    public static User[] create_users() throws Exception{
        User users[] = new User[6];
        int index_counter = 0;
        File credentials_file = new File("credentials.txt");
        String pattern = "[^\"\\s]+|\"(\\\\.|[^\\\\\"])*\"";
        Scanner file_reader = new Scanner(credentials_file);

        while (file_reader.hasNextLine()) {
            users[index_counter] = new User();
            users[index_counter].username = file_reader.findInLine(pattern);
            users[index_counter].encrypted_password = file_reader.findInLine(pattern);
            users[index_counter].password = file_reader.findInLine(pattern);
            users[index_counter].role = file_reader.findInLine(pattern);
            if (file_reader.hasNextLine() == true) {
                file_reader.nextLine();
            }
            index_counter++;
        }
        //file_reader.close();
        return users;
    }

    public static void print_file(String role) throws Exception {
        System.out.println(); //prints a blank line for easier readability.
        if (role.equals("admin")) {
            Scanner file_reader = new Scanner(admin_file);
            while (file_reader.hasNextLine()) {
                System.out.println(file_reader.nextLine());
            }
        }
        else if (role.equals("veterinarian")) {
            Scanner file_reader = new Scanner(veterinarian_file);
            while (file_reader.hasNextLine()) {
                System.out.println(file_reader.nextLine());
            }
        }
        else {
            Scanner file_reader = new Scanner(zookeeper_file);
            while (file_reader.hasNextLine()) {
                System.out.println(file_reader.nextLine());
            }
        }
    }
}

class User {
    String username;
    String password;
    String encrypted_password;
    String role;
}

Any help would be greatly appreciated.

K. Kretz
  • 72
  • 1
  • 9
  • 1
    You should follow the Java Naming Conventions: unlike in Python, variable names and method names are written in camelCase instead of snake_case. – MC Emperor Feb 22 '19 at 07:36
  • If the user has successfully logged in and doesn't want to log out, `start_login()` shouldn't be called. – LHCHIN Feb 22 '19 at 07:43
  • Possible duplicate of [Scanner is skipping nextLine() after using next() or nextFoo()?](https://stackoverflow.com/questions/13102045/scanner-is-skipping-nextline-after-using-next-or-nextfoo) – AxelH Feb 22 '19 at 08:09

2 Answers2

1

You have this method using the same Scanner Object "user_input", by call next(). The linebreak is still in the scanner buffer. Then the while loop back to start_login() if 'n' is enter. The linebreak is then consumed by temporary_user.username = user_input.nextLine();

public static void prompt_log_out(){
    System.out.println(); //prints out a blank line for easier readability
    System.out.println("Would you like to log out?  Please type \"y\" for Yes or \"n\" for No.");
    if ("y".equals(user_input.next())) {
        log_out = true;
    }
    // A quick and dirty fix
    user_input.nextLine()
}
Tempo810
  • 162
  • 7
0
attempt_counter = 0;
successful_login = false;
while (attempt_counter < 3  && !successful_login) {

Check the above condition its always true based on your declarations

eHowToNow
  • 24
  • 5