<file_sep>import turtle
import json
from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image
from random import choice, shuffle, randint
from cryptography.fernet import Fernet
from login.login import LoginPasswordManager


# ---------------------------- CONSTANTS ------------------------------------ # 
ecolor = 'white'
lcolor = '#994422'
l = ('Consolas', 13)


# ---------------------------- SEARCH DETAILS ------------------------------------ #
def search_info():
    if website_entry.get().title() == "":
        messagebox.showerror(title="Error", message="Website Entry Field is Empty!!!")
    else:
        req_website = website_entry.get().title()
        try:
            with open("data.json", mode="r") as data_file:
                data = json.load(data_file)
            with open("key.json", mode="r") as key_file:
                key_data = json.load(key_file)
            req_email = data[req_website]["email"]
            req_encryp_password = data[req_website]["Encrypted Password"].encode("utf-8")
            req_key = key_data[req_website]["key"].encode("utf-8")

            fernet = Fernet(req_key)
            decrypted_password = fernet.decrypt(req_encryp_password).decode()

        except FileNotFoundError:
            messagebox.showerror(title="Error", message="No Data File Found.") 
        except KeyError:
            messagebox.showerror(title="Error", message=f"No Details for {req_website} exists.")
        else:
            website_entry.delete(0, END)         
            messagebox.showinfo(title=req_website, message=f"Email: {req_email} \nDecrypted Password: {decrypted_password}") 

# ---------------------------- PASSWORD GENERATOR ------------------------------- #
def generate_password():
    letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    symbols = ['!', '#', '$', '%', '&', '(', ')', '*', '+']

    password_list = [choice(letters) for _ in range(randint(8, 10))]
    password_list += [choice(symbols) for _ in range(randint(2, 4))]
    password_list += [choice(numbers) for _ in range(randint(2, 4))]

    shuffle(password_list)
    generated_password = "".join(password_list)

    password_entry.delete(0, END)
    password_entry.insert(0, generated_password) 

# ---------------------------- SAVE DETAILS ------------------------------- #
def save_info():
    website = website_entry.get().title()
    email = email_username_entry.get()
    password = <PASSWORD>()
    
    if len(website) == 0 or len(password) == 0 or len(email) == 0: 
        messagebox.showerror(title="Oops", message="PLease don't leave any fields empty!!!")
    else:
        key = Fernet.generate_key()
        fernet = Fernet(key)
        encPassword = fernet.encrypt(password.encode())

        new_data = {
            website: {
                "email": email,
                "Encrypted Password": encPassword.decode()
            }
        }
        new_key = {
            website: {
                "key": key.decode()
            }
        }

        try:
            with open("data.json", mode="r") as data_file:
                #Reading old Data
                data = json.load(data_file)
            with open("key.json", mode="r") as key_file:
                #Reading old Key
                key_data = json.load(key_file)
        except FileNotFoundError: 
            with open("data.json", mode="w") as data_file:
                json.dump(new_data, data_file, indent=4)
            with open("key.json", mode="w") as key_file:
                json.dump(new_key, key_file, indent=4)
                
            website_entry.delete(0, END)
            email_username_entry.delete(0, END)
            password_entry.delete(0, END)
            website_entry.focus()

            messagebox.showinfo(title="Success", message="Details saved successfully!!!")
        else:
            #Updating old Data with new Data in data file
            data.update(new_data)

            with open("data.json", mode="w") as data_file:
                #Saving updated Data in data file
                json.dump(data, data_file, indent=4)


            #Updating old Data with new Data in key file
            key_data.update(new_key)

            with open("key.json", mode="w") as key_file:
                #Saving updated Data in key file
                json.dump(key_data, key_file, indent=4)

            website_entry.delete(0, END)
            email_username_entry.delete(0, END)
            password_entry.delete(0, END)
            website_entry.focus()
            
            messagebox.showinfo(title="Success", message="Details saved successfully!!!")
            


# ---------------------------- EDIT DETAILS ------------------------------- #
def edit_info():
    screen = turtle.Screen()
    screen.bye()
    edit_website = screen.textinput(title="Edit Details", prompt="Enter the Website").title()
    if edit_website != "":
        try:
            with open("data.json", mode="r") as data_file:
                edit_data = json.load(data_file)
            with open("key.json", mode="r") as key_file:
                key_edit_data = json.load(key_file)
            edit_email = edit_data[edit_website]["email"]
            edit_password_enc = edit_data[edit_website]["Encrypted Password"].encode("utf-8")
            edit_key = key_edit_data[edit_website]["key"].encode("utf-8")
        except FileNotFoundError:
            messagebox.showerror(title="Error", message="No Data File Found to Edit.") 
        except KeyError:
            messagebox.showerror(title="Error", message=f"No Details for {edit_website} exists to Edit.")
        else:
            website_entry.delete(0, END)
            email_username_entry.delete(0, END)
            password_entry.delete(0, END)

            fernet = Fernet(edit_key)
            edit_password_dec = fernet.decrypt(edit_password_enc).decode()

            website_entry.insert(0, edit_website)
            email_username_entry.insert(0, edit_email)
            password_entry.insert(0, edit_password_dec)
    else:
        messagebox.showerror(title="Error", message="Website Entry Field is Empty!!!")

    
# ---------------------------- DELETE DETAILS ------------------------------- #
def delete_info():
    screen = turtle.Screen()
    screen.bye()
    delete_website = screen.textinput(title="Delete Details", prompt="Enter the Website").title()
    if delete_website != "":
        try:
            with open("data.json", mode="r") as data_file:
                delete_data = json.load(data_file)
            with open("key.json", mode="r") as key_file:
                key_delete_data = json.load(key_file)

            del delete_data[delete_website]
            del key_delete_data[delete_website]
        except FileNotFoundError:
            messagebox.showerror(title="Error", message="No Data File Found to Delete.")
        except KeyError:
            messagebox.showerror(title="Error", message=f"No Details for {delete_website} exists to Delete.")
        else:
            with open("data.json", mode="w") as data_file:
                #Saving updated Data in data file after deletion
                json.dump(delete_data, data_file, indent=4)

            with open("key.json", mode="w") as key_file:
                #Saving updated Data in key file after deletion
                json.dump(key_delete_data, key_file, indent=4)

            messagebox.showinfo(title="Success", message=f"Details for {delete_website} deleted successfully!!!")
    else:
        messagebox.showerror(title="Error", message="Website Entry Field is Empty!!!")
        


# ---------------------------- UI SETUP ------------------------------- #
login_window = LoginPasswordManager()

if login_window.success:
    window = Tk()
    window.geometry('600x600')
    window.title("<NAME>       <NAME>")

    #Making gradient frame
    j=0
    r=10
    for i in range(100):
        c=str(222222+r)
        Frame(window,width=10,height=600,bg="#"+c).place(x=j,y=0)   
        j=j+10                                                  
        r=r+1

    Frame(window, width=500, height=500, bg='white').place(x=50, y=50)

    #Password Manager Logo
    imagea=Image.open("logo.png")
    imageb= ImageTk.PhotoImage(imagea) 
    image_label = Label(image=imageb, border=0, justify=CENTER)
    image_label.place(x=200, y=65)



    #Labels
    website_label=Label(window, text="Website:", bg="white", font=l)
    website_label.place(x=133, y=290)

    email_username_label = Label(window, text="Email/Username:", bg='white', font=l)
    email_username_label.place(x=70, y=340)

    password_label = Label(window, text="Password:", bg="white", font=l)
    password_label.place(x=123, y=390)



    #lineframe on entry
    Frame(window, width=180, height=2, bg='#141414').place(x=225, y=312)
    Frame(window, width=280, height=2, bg='#141414').place(x=225, y=362)
    Frame(window, width=180, height=2, bg='#141414').place(x=225, y=412)



    #Entries
    website_entry = Entry(window, width=20, border=0, font=l)
    website_entry.place(x=225, y=290)
    website_entry.focus()

    email_username_entry = Entry(window, width=31, border=0, font=l)
    email_username_entry.place(x=225, y=340)

    password_entry = Entry(window, width=20, border=0, font=l)
    password_entry.place(x=225, y=390)



    #Buttons
    #Search Button
    search_button = Button(window,text='S E A R C H',
                        width=13,
                        height=1,
                        fg=ecolor,
                        border=0,
                        bg=lcolor,
                        activeforeground=lcolor,
                        activebackground=ecolor,
                        command=search_info)               
    search_button.place(x=425, y=290)

    #Generate Password Button
    generate_password_btn = Button(window,text="GENERATE   PASSWORD",
                        width=18,
                        height=1,
                        fg=ecolor,
                        border=0,
                        bg="#17423a",
                        activeforeground=lcolor,
                        activebackground=ecolor,
                        command=generate_password)       
    generate_password_btn.place(x=412, y=390)

    #Add Button
    add_btn = Button(window,text="A D D",
                        width=20,
                        height=2,
                        fg=ecolor,
                        border=0,
                        bg="#064018",
                        activeforeground=lcolor,
                        activebackground=ecolor,
                        command=save_info)       
    add_btn.place(x=220, y=460)

    #Edit Button
    edit_btn = Button(window,text="E D I T",
                        width=18,
                        height=2,
                        fg=ecolor,
                        border=0,
                        bg="#5e0761",
                        activeforeground=lcolor,
                        activebackground=ecolor,
                        command=edit_info)       
    edit_btn.place(x=140, y=510)

    #Delete Button
    delete_btn = Button(window,text="D E L E T E",
                        width=18,
                        height=2,
                        fg=ecolor,
                        border=0,
                        bg="#700926",
                        activeforeground=lcolor,
                        activebackground=ecolor,
                        command=delete_info)       
    delete_btn.place(x=315, y=510)



    window.mainloop() 
<file_sep>from tkinter import *
from tkinter import messagebox
from PIL import ImageTk, Image

ecolor = 'white'
lcolor = '#994422'


class LoginPasswordManager:
    def __init__(self):
        self.window = Tk()
        self.window.geometry('350x500')
        self.window.title(' L O G I N ')
        self.window.resizable(0, 0)
        self.success = None
        
        #Making gradient frame
        j=0
        r=10
        for i in range(100):
            c=str(222222+r)
            Frame(self.window,width=10,height=500,bg="#"+c).place(x=j,y=0)   
            j=j+10                                                  
            r=r+1

        Frame(self.window, width=250, height=400, bg='white').place(x=50, y=50)

        self.user_name_label=Label(self.window,text='Username',bg='white')
        self.l=('Consolas',13)
        self.user_name_label.config(font=self.l)
        self.user_name_label.place(x=80,y=200)

        #entry for username entry
        self.user_name_entry=Entry(self.window,width=20,border=0)
        self.l=('Consolas',13)
        self.user_name_entry.config(font=self.l)
        self.user_name_entry.place(x=80,y=230)

        #entry for password entry
        self.password_entry=Entry(self.window,width=20,border=0,show='*')
        self.password_entry.config(font=self.l)
        self.password_entry.place(x=80,y=310)


        self.password_label=Label(self.window,text='Password',bg='white')
        self.password_label.config(font=self.l)
        self.password_label.place(x=80,y=280)


        ###lineframe on entry
        Frame(self.window, width=180, height=2, bg='#141414').place(x=80, y=332)
        Frame(self.window, width=180, height=2, bg='#141414').place(x=80, y=252)
        
        self.imagea=Image.open("login/log.png")
        self.imageb= ImageTk.PhotoImage(self.imagea) 

        self.image_label = Label(image=self.imageb, border=0, justify=CENTER)
        self.image_label.place(x=115, y=50)

        #Login Button
        self.login_button = Button(self.window,text='L O G I N',
                    width=20,
                    height=2,
                    fg=ecolor,
                    border=0,
                    bg=lcolor,
                    activeforeground=lcolor,
                    activebackground=ecolor,
                    command=self.login_check)
                    
        self.login_button.bind("<Enter>", self.on_entera) 
        self.login_button.bind("<Leave>", self.on_leavea)
        self.window.bind("<Return>", self.login_check)

        self.login_button.place(x=100,y=375)
        self.window.mainloop()


    
    
    #Login check authentication
    def login_check(self, event=None):
        if self.user_name_entry.get() == "admin" and self.password_entry.get() == "<PASSWORD>":
            messagebox.showinfo(title="LOGIN SUCCESSFULL", message="         WELCOME TO PASSWORD MANAGER       ")
            self.window.destroy()
            self.success = True
        else:
            messagebox.showerror(title="LOGIN FAILED", message="        PLEASE TRY AGAIN        ")
            self.user_name_entry.delete(0, END)
            self.password_entry.delete(0, END)
            self.user_name_entry.focus()
            self.success = False
            



    #Button_with hover effect
    def on_entera(self,e):
        self.login_button['background'] = "#ffcc66" 
        self.login_button['foreground'] = "#000d33"  

    def on_leavea(self,e):
        self.login_button['background'] = lcolor
        self.login_button['foreground']= ecolor
<file_sep># Password Manager - GUI

A **GUI Application** for managing login credentials for any website in Local Environment

This application is basically built with **tkinter** and **turtle** graphics, **cryptography** module to Encrypt and Decrypt.


## How to run ?
- Run the main.py file.
- install required modules such as pillow and cryptogaphy using cmd commad - **pip install pillow** and **pip install cryptography**


## Features
- All the credentials User generated using the GUI with be saved in **data.json** and **key.json** which will be very beneficial for reading and writing
  data locally.
- The GUI performs **CRUD Operations** and hence manages credentials effectively.
- The GUI has **search button** which helps the users to search through the **data.json** and **key.json** to find the previously saved credentials.
- The GUI also has a **generate password button** which helps the users to generate a **Strong Password** for the websites.  
- The GUI Encrypt and Decrypt passwords for maintaining security of passwords.
- For login **username: admin** and **password: <PASSWORD>**.


## Author - **<NAME>**
