Merge sane branch with main branch, release 1.0

Version 1.0 (Sane coding, finalized release)
main
Kamal Curi 4 years ago committed by GitHub
commit ca5d4969c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,3 +17,9 @@
- 0.6: - 0.6:
· Added "random string for password" function · Added "random string for password" function
· Fixed a bug with the copy command when the database is empty · Fixed a bug with the copy command when the database is empty
- 1.0:
· Code cleanup
· Added 'help' command
· Minor bug fixes:
· ITEM_CURSOR and GLOBAL_CURSOR now behave properly under all(tested) circumstances
· Added random string to modify password

@ -12,12 +12,12 @@ Just run `install.sh` **WITHOUT SUDO**
If you're upgrading Steelbox, don't worry: `install.sh` will do it automatically without messing with your password file If you're upgrading Steelbox, don't worry: `install.sh` will do it automatically without messing with your password file
#### Dependencies: #### Dependencies:
As of V0.5, you need the [pyperclip](https://pypi.org/project/pyperclip/) module. You can install it with [pip](https://pypi.org/project/pip/): Clipboard support needs the [pyperclip](https://pypi.org/project/pyperclip/) module. You can install it with [pip](https://pypi.org/project/pip/):
`pip3 install pyperclip` `pip3 install pyperclip`
Also, for clipboard support to work, you need [xclip](https://github.com/astrand/xclip) or [xsel](https://github.com/kfish/xsel) on your machine. Also for clipboard support, you need [xclip](https://github.com/astrand/xclip) or [xsel](https://github.com/kfish/xsel) on your machine.
This program has no support for the wayland clipboard. This program has no support for the wayland clipboard... Unless pyperclip starts supporting it :P
The standard ( this program was made with 3.10 ) python installation comes with the `curses` and `csv` modules, just make sure you have [GnuPG](https://gnupg.org/) installed. The standard ( this program was made with v3.10 ) python installation comes with the `curses` and `csv` modules, just make sure you have [GnuPG](https://gnupg.org/) installed.

@ -0,0 +1,29 @@
Made by Kamal 'brejela' Curi, kamalcuri@outlook.com ││
For licensing information, read LICENSE ││
-------------------------------------------------------------------------------- ││
Directional keys:...........Move the cursor ││
PgDown/F1:..................Previous Page ││
PgUp/F2:....................Next Page ││
Enter/E:....................View password ││
R:..........................Opens a window with a random string ││
##### These commands work wether there's an open password or not ##### ││
C/F3:.......................Copy password to clipboard (Requires xclip or xsel) ││
N/F4:.......................New password ││
M/F5:.......................Modify password ││
D/Del:......................Delete password ││
###################################################################### ││
When creating a password, you can leave the PSWD field empty, a random password ││
will be generated in its place. ││
Leaving the PSWD field empty when modifying a password will also give it ││
a random string.
------------------------------------------------------------------------ ││
In case you're not running this software under st or alacritty, ││
cursor navigation can be a bit janky: ││
CTRL+A to go to the far left of the field ││
CTRL+E to go to the far right of the field ││
CTRL+B to move the cursor once to the left ││
CTRL+F to move the cursor once to the right ││
CTRL+H to remove one character (Backspace) ││
CTRL+D to remove highlghted character (Delete) ││
CTRL+O to clear the field
------------------------------------------------------------------------

@ -1,11 +1,11 @@
import csv import csv
import curses import curses
from curses import wrapper
from curses.textpad import Textbox from curses.textpad import Textbox
import sys import sys
import os import os
import pyperclip as pc import pyperclip as pc
import random import random
version = sys.argv[1] version = sys.argv[1]
## Initialization of bottomline dependencies ## Initialization of bottomline dependencies
@ -22,33 +22,57 @@ fields = ["service", "user", "pswd"]
HOMEDIR = os.environ['HOME'] HOMEDIR = os.environ['HOME']
PASFILE=HOMEDIR+"/.pasfile.csv" PASFILE=HOMEDIR+"/.pasfile.csv"
# Initializes Curses' screen
def main(stdscr): def reloadFiles():
# Opens password file files.clear()
with open(PASFILE, mode='r') as pasfile: with open(PASFILE, mode='r') as pasfile:
# Creates reader object # Creates reader object
csvreader=csv.DictReader(pasfile) csvreader=csv.DictReader(pasfile)
for ids in csvreader: for ids in csvreader:
files.append(ids) files.append(ids)
## Initializes color pairs
# Password pallete (Foreground = Background)
curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_BLACK) # Initializes the curses screen
pwd_pallete = curses.color_pair(1) stdscr = curses.initscr()
# Main window pallete curses.noecho()
curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLACK) curses.cbreak()
main_pallete = curses.color_pair(2) stdscr.keypad(True)
stdscr.clear()
# Clears screen
stdscr.clear() def steelbox():
reloadFiles()
# Initializes the main window
global mainwin
mainwin = curses.newwin(TERM_LINES -1, TERM_COLS, 0, 0)
mainwin.keypad(True)
mainwin.border()
# Initializes the bottom window
global statuswin
statuswin= curses.newwin(3, TERM_COLS, TERM_LINES, 0)
statuswin.keypad(True)
statuswin.border()
cleanWins()
while True:
reloadFiles()
displayItems()
stdscr.move(TERM_LINES, TERM_COLS)
command()
# Defines global variables
def globals():
## Global variables
# Determines terminal size # Determines terminal size
global TERM_LINES global TERM_LINES
TERM_LINES=curses.LINES - 1 TERM_LINES=curses.LINES - 1
if TERM_LINES <= 20: if TERM_LINES <= 20:
sys.exit("ERROR: Your terminal is too small!") close("ERROR: Your terminal is too small!")
global TERM_COLS global TERM_COLS
TERM_COLS=curses.COLS - 1 TERM_COLS=curses.COLS - 1
if TERM_COLS <=80: if TERM_COLS <=80:
sys.exit("ERROR: Your terminal is too small!") close("ERROR: Your terminal is too small!")
# Global (program-wide) variables for cursor position # Global (program-wide) variables for cursor position
global LINE global LINE
LINE = 0 LINE = 0
@ -89,7 +113,6 @@ def main(stdscr):
# What row the cursor is in # What row the cursor is in
global CUROW global CUROW
CUROW = 0 CUROW = 0
global PSERV global PSERV
PSERV = "" PSERV = ""
global PUSER global PUSER
@ -97,76 +120,17 @@ def main(stdscr):
global PPSWD global PPSWD
PPSWD = "" PPSWD = ""
# Gets user command
def command():
# Initializes the main window
mainwin = curses.newwin(TERM_LINES -1, TERM_COLS, 0, 0)
mainwin.keypad(True)
mainwin.bkgd(' ', main_pallete)
mainwin.border()
# Initializes the bottom window
statusWin = curses.newwin(3, TERM_COLS, TERM_LINES, 0)
statusWin.keypad(True)
statusWin.border()
statusWin.bkgd(' ', main_pallete)
statusWin.border()
while True:
# Creates a name list
displayList = []
# This makes sure the cursor stays on the screen TODO: delete this
if ITEM_CURSOR < 0: ITEM_CURSOR = 0
if ITEM_CURSOR > MAX_ITEMS or ITEM_CURSOR > len(files)-1: ITEM_CURSOR = 0
# Makes sure the windows are properly clean
mainwin.border()
statusWin.border()
mainwin.border()
mainwin.addstr(0, 1, "SteelBox V" + str(version))
mainwin.refresh()
statusWin.border()
statusWin.refresh()
# Reset global necessities
LINE = 0
COLUMN = 0
currItem = 0
highOpt = ()
# Defines what to display
startDisplay = (CURR_PAGE-1)*MAX_ITEMS
stopDisplay = CURR_PAGE*MAX_ITEMS
# Appends the names in the CSV to display on the main window
for ps_name in files:
displayList.append(ps_name['service'][:15])
for item in displayList[startDisplay:stopDisplay]:
# If the item is the one with the cursor, highlight it
if currItem == ITEM_CURSOR:
mode = curses.A_REVERSE
highOpt = mainwin.getyx()
else:
mode = curses.A_NORMAL
mainwin.addstr(1 + LINE, 1 + COLUMN, item, mode)
LINE+=1
currItem+=1
if LINE >= WINLIMIT:
LINE = 0
COLUMN+=16
NROWS+=1
mainwin.refresh()
STATUS_MESSAGE = "PrvPage(F1),NxtPage(F2),(d|el),(e)xamine,(n)ew,(c)opy,(m)odify,(r)andom,(q)uit"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
## Command logic
# The GLOBAL_CURSOR points to the main files object, so that it gets the right file. # The GLOBAL_CURSOR points to the main files object, so that it gets the right file.
global c global c
global CUROW
global ITEM_CURSOR
global GLOBAL_CURSOR
global CURR_PAGE
c = mainwin.getch() c = mainwin.getch()
if c == ord('q'): if c == ord('q'):
return(0) close()
elif c == curses.KEY_DOWN: elif c == curses.KEY_DOWN:
if GLOBAL_CURSOR < len(files) - 1: if GLOBAL_CURSOR < len(files) - 1:
ITEM_CURSOR+=1 ITEM_CURSOR+=1
@ -176,10 +140,17 @@ def main(stdscr):
ITEM_CURSOR-=1 ITEM_CURSOR-=1
GLOBAL_CURSOR-=1 GLOBAL_CURSOR-=1
elif c == curses.KEY_RIGHT: elif c == curses.KEY_RIGHT:
if CUROW < NROWS: if CUROW < NROWS and (ITEM_CURSOR + MAX_LINES) < len(files) - 1:
ITEM_CURSOR+=MAX_LINES - 1 ITEM_CURSOR+=MAX_LINES - 1
GLOBAL_CURSOR+=MAX_LINES - 1 GLOBAL_CURSOR+=MAX_LINES - 1
CUROW+=1 CUROW+=1
else:
ITEM_CURSOR = len(files) - 1
GLOBAL_CURSOR = len(files) - 1
if CUROW < NROWS:
CUROW+=1
else:
CUROW = NROWS
elif c == curses.KEY_LEFT: elif c == curses.KEY_LEFT:
if CUROW > 0: if CUROW > 0:
ITEM_CURSOR-=MAX_LINES - 1 ITEM_CURSOR-=MAX_LINES - 1
@ -194,49 +165,66 @@ def main(stdscr):
if CURR_PAGE < MAX_PAGES: if CURR_PAGE < MAX_PAGES:
CURR_PAGE+=1 CURR_PAGE+=1
GLOBAL_CURSOR+=MAX_ITEMS GLOBAL_CURSOR+=MAX_ITEMS
elif c == 10 or c == curses.KEY_ENTER or c == ord('e'):
examine()
elif c == ord('c') or c == curses.KEY_F3: elif c == ord('c') or c == curses.KEY_F3:
if len(files) > 0: copy()
pc.copy(files[GLOBAL_CURSOR]['pswd']) elif c == ord('n') or c == curses.KEY_F4:
statusWin.border() newFile()
STATUS_MESSAGE = "Copied password for " + files[GLOBAL_CURSOR]['service'] elif c == ord('m') or c == curses.KEY_F5:
statusWin.addstr(0,0, STATUS_MESSAGE) modFile()
statusWin.refresh() elif c == ord('d') or c == curses.KEY_DC:
mainwin.getch() delFile()
elif c == ord('r'): elif c == ord('r'):
ranWin = curses.newwin(3, 49, int(TERM_LINES/2), int(TERM_COLS/2)) rwin()
ranWin.border() elif c == ord('h'):
ranWin.addstr(0, 1, "Random string") sbhelp()
ranWin.addstr(1, 1, randString())
ranWin.refresh()
ranWin.getch()
elif c == ord('d') or c == curses.KEY_DC:
dlWin = curses.newwin(3, 22, int(TERM_LINES/2), int(TERM_COLS/2)) def newFile():
dlWin.border() # Initializes the 'new password' window
dlWin.refresh() npWin = curses.newwin(5, 60,int(TERM_LINES/2)-2, int(TERM_COLS/2)-18)
statusWin.border() nwCord = npWin.getbegyx()
STATUS_MESSAGE = "Delete " + displayList[GLOBAL_CURSOR] + "?" # Initializes the windows in which the textboxes will reside for input
statusWin.addstr(0,0, STATUS_MESSAGE) svWin = curses.newwin(1, 45, nwCord[0]+1, nwCord[1]+6)
statusWin.refresh() svBox = Textbox(svWin)
dlWin.addstr(1, 1, "Are you sure? (y/N)") usWin = curses.newwin(1, 45, nwCord[0]+2, nwCord[1]+6)
c = dlWin.getch() usBox = Textbox(usWin)
if c == ord('y'): psWin = curses.newwin(1, 45, nwCord[0]+3, nwCord[1]+6)
files.pop(GLOBAL_CURSOR) psBox = Textbox(psWin)
# Clears the 'new password' window
npWin.border()
npWin.border()
npWin.addstr(0, 1, "New password")
npWin.addstr(1, 1, "SRVC:")
npWin.addstr(2, 1, "USER:")
npWin.addstr(3, 1, "PSWD:")
STATUS_MESSAGE = "CTRL+G to enter, MAX 45 CHARS"
displayStatus(STATUS_MESSAGE)
npWin.refresh()
# Takes data
svBox.edit()
passService = svBox.gather()
usBox.edit()
passUser = usBox.gather()
psBox.edit()
passPswd = psBox.gather()
if passService != '' and passUser != '':
if passPswd == '':
passPswd = randString()
# wtf = write to file
wtf = {'service' : passService, 'user' : passUser, 'pswd' : passPswd}
files.append(wtf)
with open(PASFILE, mode='w') as pasfile: with open(PASFILE, mode='w') as pasfile:
csvwriter = csv.DictWriter(pasfile, fields) csvwriter = csv.DictWriter(pasfile, fields)
csvwriter.writeheader() csvwriter.writeheader()
csvwriter.writerows(files) csvwriter.writerows(files)
files.clear() reloadFiles()
with open(PASFILE, mode='r') as pasfile:
# Creates reader object
csvreader=csv.DictReader(pasfile)
for ids in csvreader:
files.append(ids)
# For some reason, KEY_UP is 10, instead of the 343 the debbuger flags... Welp ¯\_(ツ)_/¯
elif c == 10 or c == curses.KEY_ENTER or c == ord('e'): def examine():
# highOpt = Coordinates of the first option's character # highOpt = Coordinates of the first option's character
LINE = highOpt[0] LINE = highOpt[0]
COLUMN = highOpt[1] COLUMN = highOpt[1]
@ -249,8 +237,7 @@ def main(stdscr):
fileWin = curses.newwin(5, 60, LINE+5, COLUMN) fileWin = curses.newwin(5, 60, LINE+5, COLUMN)
# Clears the window # Clears the window
fileWin.border() fileWin.border()
fileWin.border() fileWin.border
passService = files[GLOBAL_CURSOR]['service'][:45] passService = files[GLOBAL_CURSOR]['service'][:45]
passUser = files[GLOBAL_CURSOR]['user'][:45] passUser = files[GLOBAL_CURSOR]['user'][:45]
passPswd = files[GLOBAL_CURSOR]['pswd'][:45] passPswd = files[GLOBAL_CURSOR]['pswd'][:45]
@ -258,36 +245,18 @@ def main(stdscr):
fileWin.addstr(1, 1, "SRVC: " + passService) fileWin.addstr(1, 1, "SRVC: " + passService)
fileWin.addstr(2, 1, "NAME: " + passUser) fileWin.addstr(2, 1, "NAME: " + passUser)
fileWin.addstr(3, 1, "PSWD: " + passPswd) fileWin.addstr(3, 1, "PSWD: " + passPswd)
statusWin.border()
STATUS_MESSAGE = "cmds:(d|DEL)ete,(m)odify, (c)opy " STATUS_MESSAGE = "cmds:(d|DEL)ete,(m)odify, (c)opy "
statusWin.addstr(0,0, STATUS_MESSAGE) displayStatus(STATUS_MESSAGE)
statusWin.refresh()
fileWin.refresh()
# Gets command to act on the highlighted file # Gets command to act on the highlighted file
c = fileWin.getch() c = fileWin.getch()
if c == ord('d') or c == curses.KEY_DC: if c == ord('d') or c == curses.KEY_DC:
dlWin = curses.newwin(3, 22, int(TERM_LINES/2), int(TERM_COLS/2)) delFile()
dlWin.border()
dlWin.refresh()
statusWin.border()
STATUS_MESSAGE = "Delete " + displayList[GLOBAL_CURSOR] + "?"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
dlWin.addstr(1, 1, "Are you sure? (y/N)")
c = dlWin.getch()
if c == ord('y'):
files.pop(GLOBAL_CURSOR)
with open(PASFILE, mode='w') as pasfile:
csvwriter = csv.DictWriter(pasfile, fields)
csvwriter.writeheader()
csvwriter.writerows(files)
files.clear()
with open(PASFILE, mode='r') as pasfile:
# Creates reader object
csvreader=csv.DictReader(pasfile)
for ids in csvreader:
files.append(ids)
elif c == ord('m'): elif c == ord('m'):
modFile()
elif c == ord('c') or c == curses.KEY_F3:
copy()
def modFile():
# Extracts the file to be modified # Extracts the file to be modified
modFile = files[GLOBAL_CURSOR] modFile = files[GLOBAL_CURSOR]
# Removes it from the main file # Removes it from the main file
@ -312,8 +281,7 @@ def main(stdscr):
# Clears the 'modify password' window # Clears the 'modify password' window
modWin.border() modWin.border()
modWin.border() modWin.border
modWin.addstr(0, 1, "Modify password") modWin.addstr(0, 1, "Modify password")
modWin.addstr(1, 1, "SRVC:") modWin.addstr(1, 1, "SRVC:")
modWin.addstr(2, 1, "USER:") modWin.addstr(2, 1, "USER:")
@ -325,23 +293,19 @@ def main(stdscr):
# Takes data # Takes data
STATUS_MESSAGE = "Edit SERVICE field - CTRL+G to enter, leave empty to cancel, MAX 45 CHARS" STATUS_MESSAGE = "Edit SERVICE field - CTRL+G to enter, leave empty to cancel, MAX 45 CHARS"
statusWin.border() displayStatus(STATUS_MESSAGE)
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
svBox.edit() svBox.edit()
passService = svBox.gather() passService = svBox.gather()
STATUS_MESSAGE = "Edit USER field - CTRL+G to enter, leave empty to cancel, MAX 45 CHARS" STATUS_MESSAGE = "Edit USER field - CTRL+G to enter, leave empty to cancel, MAX 45 CHARS"
statusWin.border() displayStatus(STATUS_MESSAGE)
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
usBox.edit() usBox.edit()
passUser = usBox.gather() passUser = usBox.gather()
STATUS_MESSAGE = "Edit PASSWORD field - CTRL+G to enter, leave empty for random string" STATUS_MESSAGE = "Edit PASSWORD field - CTRL+G to enter, leave empty for random string"
statusWin.border() displayStatus(STATUS_MESSAGE)
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
psBox.edit() psBox.edit()
passPswd = psBox.gather() passPswd = psBox.gather()
if passPswd == '':
passPswd = randString()
modFile = {'service' : passService, 'user' : passUser, 'pswd' : passPswd} modFile = {'service' : passService, 'user' : passUser, 'pswd' : passPswd}
files.insert(GLOBAL_CURSOR, modFile) files.insert(GLOBAL_CURSOR, modFile)
with open(PASFILE, mode='w') as pasfile: with open(PASFILE, mode='w') as pasfile:
@ -349,137 +313,124 @@ def main(stdscr):
csvwriter = csv.DictWriter(pasfile, fields) csvwriter = csv.DictWriter(pasfile, fields)
csvwriter.writeheader() csvwriter.writeheader()
csvwriter.writerows(files) csvwriter.writerows(files)
files.clear() reloadFiles()
with open(PASFILE, mode='r') as pasfile:
# Creates reader object
csvreader=csv.DictReader(pasfile)
for ids in csvreader:
files.append(ids)
elif c == ord('c') or c == curses.KEY_F3:
def delFile():
dlWin = curses.newwin(3, 22, int(TERM_LINES/2), int(TERM_COLS/2))
dlWin.border()
dlWin.refresh()
STATUS_MESSAGE = "Delete " + displayList[GLOBAL_CURSOR] + "?"
displayStatus(STATUS_MESSAGE)
dlWin.addstr(1, 1, "Are you sure? (y/N)")
c = dlWin.getch()
if c == ord('y'):
files.pop(GLOBAL_CURSOR)
with open(PASFILE, mode='w') as pasfile:
csvwriter = csv.DictWriter(pasfile, fields)
csvwriter.writeheader()
csvwriter.writerows(files)
reloadFiles()
# Opens a new window with a random string of length 45
def rwin():
ranWin = curses.newwin(3, 49, int(TERM_LINES/2), int(TERM_COLS/2))
ranWin.border()
ranWin.addstr(0, 1, "Random string")
ranWin.addstr(1, 1, randString())
ranWin.refresh()
ranWin.getch()
# Copies password to clipboard
def copy():
if len(files) > 0:
pc.copy(files[GLOBAL_CURSOR]['pswd']) pc.copy(files[GLOBAL_CURSOR]['pswd'])
statusWin.border()
STATUS_MESSAGE = "Copied password for " + files[GLOBAL_CURSOR]['service'] STATUS_MESSAGE = "Copied password for " + files[GLOBAL_CURSOR]['service']
statusWin.addstr(0,0, STATUS_MESSAGE) displayStatus(STATUS_MESSAGE)
statusWin.refresh()
mainwin.getch() mainwin.getch()
elif c == ord('n'):
# Initializes the 'new password' window
npWin = curses.newwin(5, 60,int(TERM_LINES/2)-2, int(TERM_COLS/2)-18)
nwCord = npWin.getbegyx()
# Initializes the windows in which the textboxes will reside for input
svWin = curses.newwin(1, 45, nwCord[0]+1, nwCord[1]+6)
svBox = Textbox(svWin)
usWin = curses.newwin(1, 45, nwCord[0]+2, nwCord[1]+6)
usBox = Textbox(usWin)
psWin = curses.newwin(1, 45, nwCord[0]+3, nwCord[1]+6)
psBox = Textbox(psWin)
# Clears the 'new password' window # Cleans the windows
npWin.border() def cleanWins():
npWin.border() mainwin.clear()
statuswin.clear()
mainwin.border()
statuswin.border()
mainwin.addstr(0, 1, "SteelBox V" + str(version))
mainwin.refresh()
statuswin.refresh()
npWin.addstr(0, 1, "New password")
npWin.addstr(1, 1, "SRVC:")
npWin.addstr(2, 1, "USER:")
npWin.addstr(3, 1, "PSWD:")
STATUS_MESSAGE = "CTRL+G to enter, MAX 45 CHARS"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
npWin.refresh()
# Takes data
svBox.edit()
passService = svBox.gather()
usBox.edit()
passUser = usBox.gather()
psBox.edit()
passPswd = psBox.gather()
if passService != '' and passUser != '': # Displays the items on the screen properly
if passPswd == '': def displayItems():
passPswd = randString() cleanWins()
# wtf = write to file global NROWS
wtf = {'service' : passService, 'user' : passUser, 'pswd' : passPswd} global ITEM_CURSOR
files.append(wtf) # Creates a name list
with open(PASFILE, mode='w') as pasfile: global displayList
csvwriter = csv.DictWriter(pasfile, fields) displayList = []
csvwriter.writeheader() # Appends the names in the CSV to display on the main window
csvwriter.writerows(files) for ps_name in files:
displayList.append(ps_name['service'][:15])
elif c == ord('m'): # Reset global necessities
# Extracts the file to be modified LINE = 0
modFile = files[GLOBAL_CURSOR] COLUMN = 0
# Removes it from the main file currItem = 0
files.pop(GLOBAL_CURSOR) NROWS = 0
# Creates the 'modify password' window global highOpt
modWin = curses.newwin(5, 60,int(TERM_LINES/2)-2, int(TERM_COLS/2)-18) highOpt = ()
# Gets the coordinates for the top left corner of said window # Defines what to display
nwCord = modWin.getbegyx() startDisplay = (CURR_PAGE-1)*MAX_ITEMS
# Creates the fields in which the password will be edited stopDisplay = CURR_PAGE*MAX_ITEMS
svWin = curses.newwin(1, 45, nwCord[0]+1, nwCord[1]+6)
svWin.addstr(0, 0, modFile['service']) for item in displayList[startDisplay:stopDisplay]:
svWin.move(0, 0) # If the item is the one with the cursor, highlight it
svBox = Textbox(svWin) if currItem == ITEM_CURSOR:
usWin = curses.newwin(1, 45, nwCord[0]+2, nwCord[1]+6) mode = curses.A_REVERSE
usWin.addstr(0, 0, modFile['user']) highOpt = mainwin.getyx()
usWin.move(0, 0) else:
usBox = Textbox(usWin) mode = curses.A_NORMAL
psWin = curses.newwin(1, 45, nwCord[0]+3, nwCord[1]+6) mainwin.addstr(1 + LINE, 1 + COLUMN, item, mode)
psWin.addstr(0, 0, modFile['pswd']) LINE+=1
psWin.move(0, 0) currItem+=1
psBox = Textbox(psWin) if LINE >= WINLIMIT:
LINE = 0
COLUMN+=16
NROWS+=1
STATUS_MESSAGE = "PrvPage(F1),NxtPage(F2),(d|el),(e)xamine,(n)ew,(c)opy,(m)odify,(r)andom,(q)uit"
displayStatus(STATUS_MESSAGE)
mainwin.refresh()
# Clears the 'modify password' window # Displays on the status window
modWin.border() def displayStatus(msg):
modWin.border() statuswin.border()
statuswin.addstr(0,0, msg)
statuswin.refresh()
modWin.addstr(0, 1, "Modify password") def sbhelp():
modWin.addstr(1, 1, "SRVC:") helpwin = curses.newwin(TERM_LINES - 1, TERM_COLS - 1, 0, 0)
modWin.addstr(2, 1, "USER:") helpwin.border()
modWin.addstr(3, 1, "PSWD:") helpwin.addstr(1, 1, "Steelbox V." + version)
STATUS_MESSAGE = "CTRL+G to enter, MAX 45 CHARS" line = 2
statusWin.addstr(0,0, STATUS_MESSAGE) with open("sbhelp", mode='r') as sbhfile:
statusWin.refresh() sbh = sbhfile.readlines()
modWin.refresh() for lines in sbh:
svWin.refresh() helpwin.addstr(line, 1, lines)
usWin.refresh() line+=1
psWin.refresh() line+=1
helpwin.addstr(line, 1, "PRESS ANY KEY TO CONTINUE", curses.A_REVERSE)
helpwin.getch()
# Takes data
STATUS_MESSAGE = "Edit SERVICE field"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
svBox.edit()
passService = svBox.gather()
STATUS_MESSAGE = "Edit USER field"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
usBox.edit()
passUser = usBox.gather()
STATUS_MESSAGE = "Edit PASSWORD field"
statusWin.addstr(0,0, STATUS_MESSAGE)
statusWin.refresh()
psBox.edit()
passPswd = psBox.gather()
modFile = {'service' : passService, 'user' : passUser, 'pswd' : passPswd}
files.insert(GLOBAL_CURSOR, modFile)
with open(PASFILE, mode='w') as pasfile:
# Creates writer object and writes to the csv file
csvwriter = csv.DictWriter(pasfile, fields)
csvwriter.writeheader()
csvwriter.writerows(files)
files.clear()
with open(PASFILE, mode='r') as pasfile:
# Creates reader object
csvreader=csv.DictReader(pasfile)
for ids in csvreader:
files.append(ids)
# Returns a random string of length 45
def randString(): def randString():
result = '' result = ''
for _ in range(45): for _ in range(45):
@ -489,4 +440,16 @@ def randString():
result += chr(ascNum) result += chr(ascNum)
return(result) return(result)
wrapper(main)
# Finishes the application
def close(error = ''):
curses.nocbreak()
stdscr.keypad(False)
curses.echo()
curses.endwin()
sys.exit(error)
globals()
steelbox()
close()

@ -1,6 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
version="0.6" version="1.0"
echo Steelbox V$version echo Steelbox V$version

Loading…
Cancel
Save