Monday, June 3, 2024

Part 2: Library management in C | username/password login system and manage admin accounts

Previous Page                                                                                                                              Next Page

In this part, we will learn the techniques to implement a username and password login system and manage user accounts.

When a user runs the application for the first time in admin mode, the application requests the user to create an admin account. However, from the second run onwards, the user has to log in using their account details. After logging into admin mode, the user can add or modify multiple admin accounts. To identify the application’s first run, it will check if the admin account file exists in the system. If the file doesn’t exist, then the application calls the create account function. Otherwise, if the file exists, it will call the Admin login function.


int checkFirstLogin(){
    int flag=1;

    fa = fopen(DATA_FILE,"rb");

    if(fa!= NULL){
        flag= 0;
    }
    fclose(fa);

    return flag;

}

Source code of function to create account:


void createAccount(){

    char passV[MAX_PWD_SZ];
    struct password pd;

    printWelcomeMsg();

    gotoxy(35,8);
    printf("Please Enter New Username and Password.");
    gotoxy(35,10);
    printf("New User Name: ");
    getString(pd.userName,MAX_USR_SZ);
    gotoxy(35,11);
    printf("New Password: ");
    getPassword(pd.password,MAX_PWD_SZ);
    gotoxy(35,12);
    printf("Re-type Password: ");
    getPassword(passV,MAX_PWD_SZ);


    if(strcmp(passV,pd.password)==0){

        add(pd);

        printWelcomeMsg();

        gotoxy(35,8);
        printf("Congratulation! User account created.");
        gotoxy(35,10);
        printf("Please press any key to continue and log in.");
        if(getch()){
            adminLogin();
        }

    }
}

In the above code, it gets the username and password details from the user and saves them in a file. The most interesting part of this code is that it hides the password entered by the user. It displays an asterisk (*) instead of the actual character to hide the password. The user can even delete entered characters before confirming. The task of password hiding is performed by the function getPassword(), which is shown below.


static void getPassword(char *buff, size_t sz){

    char ch;
    int i=0;

    while(ch!=13 && i!=sz)
    {
        ch=getch();

        if(ch==8 && i>0){
            printf("\b \b");
            i--;
            buff[i]='\0';
        }else if(ch!=13 && ch!=8){

            putch('*');
            buff[i] = ch;
            i++;
        }
    }

    buff[i]='\0';
    ch=' ';i=0;
}

In above code, it reads user character using getch() function, display Asterix (*) using putch() function, and remove the character from the screen by printing backspace, space and backspace (printf("\b \b")). While loop is used to read multiple characters.

After getting username and password details from the user, we will call add() function inside create account function to save user account details in C file.

Now, we will create admin login function. Source code is given below:


void adminLogin(){

    struct password pd;

    printWelcomeMsg();

    gotoxy(35,8);
    printf("Please Enter Username and Password.");
    gotoxy(35,10);
    printf("User Name: ");
    getString(pd.userName,MAX_USR_SZ);
    gotoxy(35,11);
    printf("Password: ");
    getPassword(pd.password,MAX_PWD_SZ);

    if(check(pd,0)==1){

        printWelcomeMsg();

        gotoxy(35,10);
        printf("Login Successfull.");
        gotoxy(35,13);
        printf("Please press any key to continue.");
        if(getch()){
            adminMenu();
        }
    } else {

        printWelcomeMsg();

        gotoxy(35,10);
        printf("Sorry! Username or Password do not match.");
        gotoxy(35,13);
        printf("Please press any key to re-login.");
        if(getch()){
            adminLogin();
        }
    }
}

In the above code, it gets the username and password, and checks the details in the system using the check() function. The check function reads the user account details from the file and compares them with the details provided by the user. If the user account exists, then it will take the user to the adminMenu() screen. Otherwise, it will request the user to log in again.

From the admin menu, the user can add, modify, view, and delete admin accounts by selecting option A. We will not discuss the function which gets details from the user or displays details on the screen. The source code of the function given below will read or modify data from the C file where the user account details are stored.



#define DATA_FILE "adminAccess.dat"
#define TEMP_FILE "tempFile.dat"

//Read data from file

int check(struct password d,int flag){

    struct password a;
    int i=0;
    fp = fopen(DATA_FILE,"rb");
    while(fread(&a,sizeof(a),1,fp)==1){
        if(flag==0){
            if(strcmp(a.userName,d.userName)==0 && 
            strcmp(a.password,d.password)==0){
                i=1;
                break;
            }
        } else if (flag==1){
            if(strcmp(a.userName,d.userName)==0){
                i=1;
                break;
            }
        }
    }
    fclose(fp);
    return i;
}

//Read data from file
int view(struct password d[], int sz){

    struct password a;
    int i=0;
    fp = fopen(DATA_FILE,"rb");
    while(fread(&a,sizeof(a),1,fp)==1 && i<sz){
        d[i]=a;
        i++;
    }
    fclose(fp);
    return i;
}

//Add data into the file
void add(struct password d){

    fp = fopen(DATA_FILE,"ab+");
    fseek(fp,0,SEEK_END);
    fwrite(&d,sizeof(d),1,fp);
    fclose(fp);
}


//Update data into the file
int update(struct password d){

    struct password a;
    int flag=0;

    fp=fopen(DATA_FILE,"rb+");

    while(fread(&a,sizeof(a),1,fp)==1){
        if(strcmp(a.userName, d.userName)==0){
            fseek(fp,ftell(fp)-sizeof(a),0);
            fwrite(&d,sizeof(d),1,fp);
            fclose(fp);
            flag=1;
        }
    }
    fclose(fp);

    return flag;
}

//Delete data from the file
int del(char *userName){

    struct password a;
    int flag=0;

    fp=fopen(DATA_FILE,"rb+");
    ft=fopen(TEMP_FILE,"wb+");

    while(fread(&a,sizeof(a),1,fp)==1){
        if(strcmp(userName, a.userName)!=0){
            fwrite(&a,sizeof(a),1,ft);
        } else {
            flag=1;
        }
    }

    fclose(ft);
    fclose(fp);

    remove(DATA_FILE);
    rename(TEMP_FILE,DATA_FILE);

    return flag;

}

Above source code is reused from the project Contact Management. It will read, add, modify, and delete data from the file using C file handling functions. Please follow Contact Management project to understand the source code. 

No comments:

Post a Comment