Python problem with if-elif-else and/or string comparison problem - python

I'm new to Python (and stackoverflow :D) and in school we got the task to create (normal users and with sudo rights) and delete users on a linux system (Ubuntu 18.04 in my case). I'm using Pycharm for coding and Python 3.7 as interpreter.
I have already searched for an answer but couldn't find one.
So I'm not sure what exactly causes this problems so sorry for the may confusing title.
I'll try to explain it as good as possible.
I want to ask a question if the user wants to create or delete an user..
def useradministration():
parameters.question_user ##input("User add (a) or delete (d)?: ").strip()
...followed by:
#a for adding an user
if parameters.question_user == 'a':
def usercreate():
parameters.question_role ##input("Role for the user: administrator (a) or normal user (n)? ").strip()
# n for normal user - creating via useradd
if parameters.question_role == 'n':
.....
# a for administrator - same as a but with usermod for sudo
elif parameters.question_role == 'a':
.....
#error if its neither n or a
else:
print("Error: wrong specification for role.")
usercreate()
#d for deleting an user
elif parameters.question_user == 'd':
def userdelete():
........
#error if its neither a or d
else:
print("Error: wrong specification for user.")
First question.
An example output:
User add (a) or delete (d)?: r
Role for the user: administrator (a) or normal user (n)? u
Select username:g
Error: wrong specification for user.
It gives the right output with "Error: wrong specification for user." - but why is it still going through all the questions if the first if isn't true? Is it a problem with my script or is the input comparison not working, or something else?
User add (a) or delete (d)?: r
Error: wrong specification for user.
That would be the output I've hoped for.
Another question for the deleting part. We have to log everything into a file. My userdelete looks like this:
def userdelete():
parameters.username ##username = input("Select username:")
#try to delete if it exists, print and log it
try:
os.system("sudo userdel -r " + parameters.username)
print("User " + parameters.username + " deleted.")
logging.info("User " + parameters.username + " deleted.")
#exception for when user doesn't exist, just printing and logging it
except OSError:
print("User " + parameters.username + " doesnt exist.")
logging.critical("User " + parameters.username + " doesnt exist.")
pass
userdelete()
An example output:
User add (a) or delete (d)?: d
Role for the user: administrator (a) or normal user (n)? o
Select username:abc
User abc deleted.
userdel: user 'abc' does not exist
The script is actually deleting the user if it exists.
But why is it asking the Role question and why isn't it using the except statement if the user doesn't exist (because abc doesn't exist)? Am I using it wrong in this case?
I hope someone can help me.
Thanks.
EDIT
parameters.question_user is from another .py file called parameters.py (I've imported it in the main.py file) and just contains
question_user = input("User add (a) or delete (d)?: ").strip()
question_role = input("Role for the user: administrator (a) or normal user (n)? ").strip()
username = input("Select username:")

Related

Why is request module closing after giving an input?

I am working on a project that finds if a user is available or not on Instagram, (Basically that's only one of the functions.)
To do that I use this code from requests:
def start():
clear() # Clears the previous input through the OS module
print(inp + cut + "Stress them is booting...") # Inp + Cut are optional strings
use = input("Who do you want to attack? Enter here: >> ") # We take the input from here (Specifically the user)
response = requests.get("https://www.instagram.com/"+xuse+"/") # Check if the user exists, this does not work if you put # in the beginning.
if response.status_code == 404 :
PrintFatalError("User could not be found, try again.") # The user wasn't found
# Here the program stops and returns to the main program / input where I ask the user for a command.
elif response.status_code == 200 :
PrintFatalError("User " + use + " has been detected ! Proceed with the tool? ") # The user was found
f = input(" ") # This is the point
if f in "y":
print ("Beginning")
else:
print("Not a valid option, aborting.") # I abort since I don't want a loop in this phase.
Some other info that might help:
The program is fully CLI, I don't use a GUI.
This program uses while loops instead of for loops, for many reasons.
NOTE: PrintFatalError is a variable I created to display messages in red / green color. It still does not work with the classic print("string") way through.

How do I compare two variables which both contain strings in python?

I'm making a account login system in python by having the username and password stored in a separate file and the program access it, then read the password and compare it with what the user has entered. It can read the password in the file but for some reason when it compares it to what the user has entered, it always says it's wrong.
I've tried comparing the actual password to the user's input and I know it's reading the file right as I made it print out what it read and it printed the correct password. I've also made it print the user's input to make sure that's right and that was working too.
Just so you know, the file already exists which contains the password on the second line and it finds the right file as the file is named after the account that it's for.
Account = str(input("Enter the username. "))
Account_Password = str(input("Enter the password. "))
AccountFileName = (Account + ".txt")
with open(AccountFileName,"r") as AF:
for x, line in enumerate(AF):
if x == 1:
Account_Password_Check = (line)
if Account_Password == Account_Password_Check:
print("Welcome, " + Account + "!")
else:
print("Either the username or password were incorrect.")
If the user input is the same as the password, it should print, "Welcome (username here)!" and if they're different then it should print, "Either the username or password were incorrect."
If you know what's wrong, please let me know.
Thanks.
In comments to your question, you will find the first reason why it doesn't work, but:
for x, line in enumerate(AF):
if x == 1:
Account_Password_Check = (line)
Is also not fully correct, enumerate start count from zero, but condition checks 1 line, it means that you will compare your current user password from previous. The correct version will be
for x, line in enumerate(AF):
if x == 0:
Account_Password_Check = line.strip()
break

How to create a python dictionary that will store the username and password for multiple accounts

The problem I have right now is that for my dictionary that uses a key:value to store username:password is that every time I rerun the program, the current key:value is reset and the dictionary is set to empty again. The goal of my program is to have a person log in with a username and password and be able to store notes and passwords (I did this with python .txt files). Then the next person can come along, create an account and do the same. Here is my code (I have commented every line of code pertaining to my problem):
def userPass():
checkAccount = input("Do you have an account (Y or N)?")
if (checkAccount == 'N' or checkAccount == 'n'):
userName = input("Please Set Your New Username: ")
password = input("Please Set Your New Password: ")
// if (userName in dictAcc):
print("Username is taken")
userPass()
else:
// dictAcc[userName] = password
print("Congratulations! You have succesfully created an account!")
time.sleep(1.5)
dataInput()
elif(checkAccount == 'Y' or checkAccount == 'y'):
login()
else:
print("Invalid answer, try again")
userPass()
def login():
global userName
global password
global tries
loginUserName = input("Type in your Username: ")
loginPass = input("Type in your Password: ")
if (tries < 3):
// for key in dictAcc:
// if (loginUserName == key and loginPass == dictAcc[key]):
// print("You have successfully logged in!")
dataInput()
else:
print("Please try again")
tries += 1
login()
if (tries >= 3):
print("You have attempted to login too many times. Try again later.")
time.sleep(300)
login()
userPass()
As others have mentioned, you need to have your dictionary saved into a file and load it when you restart your program. I adjusted your code to work for me and created two functions, one to save the dictionary (savedict) and another to load it (loaddict). The except IOError part is just so that it creates a new file if it doesn't exist.
Note that in general, storing passwords in a text file is a very bad idea. You can clearly see the reason why if you try to open the "dictAcc.txt" file (it will have all passwords there).
import pickle
import time
def loaddict():
try:
with open("dictAcc.txt", "rb") as pkf:
return pickle.load(pkf)
except IOError:
with open("dictAcc.txt", "w+") as pkf:
pickle.dump(dict(), pkf)
return dict()
def savedict(dictAcc):
with open("dictAcc.txt", "wb") as pkf:
pickle.dump(dictAcc, pkf)
def userPass():
dictAcc = loaddict() #Load the dict
checkAccount = raw_input("Do you have an account (Y or N)?")
if (checkAccount == 'N' or checkAccount == 'n'):
userName = raw_input("Please Set Your New Username: ")
password = raw_input("Please Set Your New Password: ")
if (userName in dictAcc):
print("Username is taken")
userPass()
else:
dictAcc[userName] = password
print("Congratulations! You have succesfully created an account!")
savedict(dictAcc) #Save the dict
time.sleep(1.5)
# dataInput() Code ends
elif(checkAccount == 'Y' or checkAccount == 'y'):
login()
else:
print("Invalid answer, try again")
userPass()
def login():
global userName
global password
global tries
loginUserName = raw_input("Type in your Username: ")
loginPass = raw_input("Type in your Password: ")
dictAcc = loaddict() #Load the dict
if (tries < 3):
for key in dictAcc:
if (loginUserName == key and loginPass == dictAcc[key]):
print("You have successfully logged in!")
# dataInput() Code ends
else:
print("Please try again")
tries += 1
login()
if (tries >= 3):
print("You have attempted to login too many times. Try again later.")
time.sleep(3)
tries=1 #To restart the tries counter
login()
global tries
tries=1
userPass()
There are different ways to do this. I'll mention two.
As you noticed, all variables created by your program are erased when the program finishes executing.
One way to keep those variables alive is to keep the program running indefinately; something like a background process. This could be achieved very simply by running the script within a while loop while True:, although there are more effective ways to do it too. Then, it's variables can continue to exist because the program never terminates.
However that is only useful in occasions when you want to have something running all the time, such as a user interface waiting for input. Most of the time, you want your script to run and be able to complete.
You can therefore output your needed data to a text file. Then, when you start your program, read that text file and organize the info into your dictionary. This will make use of open("Your_username_file") and reading that file's data. If you need help on how to do that, there are many tutorials about how to read information from files in Python.
How you will store it doesn't matter too much in your case, so it's better to keep things simple and store it in something like a text file. In anycase, you don't want to store the accounts in memory, because you will need to keep it running forever.
Since this is also running locally, no matter how you choose to store your passwords, it'll be accessible to anyone who uses it. So User_a can check User_b's account and password.
So you'll need to encrypt the password before storing them. It's not as hard as it sound. Actually, Python has built-in libraries to deal with it.
A quick google search returned a simple tutorial explaning all this step by step, check it out. You'll probably be able to implement it into your code very quickly.

local vs global variables Python

I am new to programming and am wondering if this is possible. I am trying to create a password protected script, where the password is entered once and then required to progress the script the next time the script is opened. I am storing and encrypting the password in a file, and then checking to see if the file exists the next time the script is opened. The problem I am running into is checking to see if the passwords match, since the original password is in a function as a local variable.
def createFile():
pw = input('Enter Password: ')
pw2 = input('ReType Password: ')
if pw == pw2:
newPw = encrypt(pw, 10) #encodes the string with a key in a seperate encrypt function
pwFile = open('PW.txt', 'a')
pwFile.write(newPw)
pwFile.close()
else:
print('The passwords do not match')
createFile()
if os.path.isfile('PW.txt'):
print('File exists')
pwCheck = input('What is the password? ')
#I can not check pwCheck == pw since pw is a local var.
#progression of script here
else:
createFile()
I know that it is considered bad for to make a local variable global. Is there a way to restructure what I have so far to make this work? As I wrote this, I think I may have came up with a possible solution but I do not have time to test it now. Do I run the same encrypt function with the same key for pwCheck and then check if it is == to the first line of PW.txt? Is that correct and/or are there other solutions?
Thank you.
Using Windows, Python 3.4
Instead of "encrypt", perhaps use a 1-way hash.. Then, you can hash the subsequently entered password and check it versus the hash stored in the file... Something like:
def createFile():
pw = input('Enter Password: ')
pw2 = input('ReType Password: ')
if pw == pw2:
newPw = sha.new(pw).digest
pwFile = open('PW.txt', 'a')
pwFile.write(newPw)
pwFile.close()
else:
print('The passwords do not match')
createFile()
if os.path.isfile('PW.txt'):
print('File exists')
pwCheck = input('What is the password? ')
previous = open('PW.txt', 'r')
prevPass = previous.read()
hashed = sha.new(pwCheck).digest()
if (hashed==prevPass):
#progression of script here
else:
createFile()
I really hope that this is just an exercise, because if you care about security, you should be using some other authentication mechanism to gate access. Most obviously, unix permissions, and sudo to gate access.
Assuming it is an exercise only, simply have a function which checks the input against the file. Something like:
def doAuth():
isAuthed = getPassInput() == getPassFromFile()
if isAuthed:
return True
else:
raise HellNoException("Passwords differ")

Python - Multiple Login Combinations

Basically, I've made a basic login program that accepts user input. But, it currently only allows one username and password combo. I'm trying to make it accept multiple usernames and passwords but don't know how to. I am new to python and I know my code is terrible/messy. This is what I've been trying to get it to accept multiple login combinations:
output = open("logfile.txt", 'a')
login = input("please enter the correct username and password\n")
a = ("username password")("username1 password1")
if a in login:
print("successfully logged in")
import time
localtime = time.asctime(time.localtime(time.time()))
output.write("Somebody successfully logged in at ")
output.write(localtime)
output.write("\n")
output.close()
else:
print("access denied.")
import time
output = open("logfile.txt", "a")
localtime = time.asctime(time.localtime(time.time()))
output.write("Somebody unsuccessfully logged at ")
output.write(localtime)
output.write("\n")
output.close()
`
When I just add another 'if' block, it runs the else block aswell. Also, when I just have 'a' value "username password" it works. The problem is when I try to have multiple values I believe.
Try
a = set(("username password","username1 password1"))
if login in a:
and it should work as you expect.
Why is left as an exercise (hint: print the value of a).
You don't want a = ("username password")("username1 password1") and if a in login:.
You want to set a to an iterable of some sort, the code you currently have actually produces a TypeError because you are trying to call a string (putting something in brackets doesn't make it a tuple, you need to add a trailing comma).
What you want instead is something like a = ["username password", "username1 password1"], doe create a list with all the valid usernames and passwords. You then want to check if the input - login - is in that list, so do if login in a: instead.

Categories