I'm new to Python and trying to test myself with general code that features things I know or causes me to go searching for answers and solutions as to why what I'm trying to do doesn't work. Unfortunately, I've hit a dead-end in my current attempt.
I got lasered in on the concept of creating a small authorization program inside a single script, and while trying to limit the number of failed log-in attempts the user was allotted, I ran into an issue with the following code:
def attempts(n):
a = n - 1
while a > 0:
result = a
return result
Username = input('Please enter a New Username: ')
Password = input('Please enter a New Password: ')
logu = Username
logp = Password
LoginU = input('Please enter your Username: ')
if LoginU != logu:
while LoginU != logu:
LoginRetry = input('Please try again')
att = attempts(3)
att
print(att)
else:
print('Welcome to the Environment!')
pass
print('Exiting Environment. Have a good day.')
Good practice and ugly code aside, my chief issue lies in getting the (n) to reduce inside the loop with each iterative attempt. As of right now, when I execute the script and intentionally enter the wrong username, it loops
Please try again:
2
Please try again:
2
until I enter the correct username. Under proper operation, I'd like it to spit
Please try again:
2
Please try again:
1
Please try again:
Exiting Environment. Have a good day.
I'd appreciate any and all solutions, or advice people can give.
Here's one approach you can take. A few notes:
Instead of subtracting from a counter, loop over an iterable to count. for loops are genrally easier to think about than while loops. Whenever you want to do something a certain number of times, use a for loop. You can always break out of them if you need to.
The best way to approach breaking your code into functions is to try to make all of the "actions" of your program into their own functions.
import sys
def login(username, password):
username_input = input('Please enter your Username: ')
password_input = input('Please enter your Password: ')
return username == username_input and password == password_input
def login_n_tries(n, username, password):
for i in reversed(range(n)):
if login(username, password):
return True
print(f"You have {i} attempts remaining")
return False
username = input('Please enter a New Username: ')
password = input('Please enter a New Password: ')
if not login_n_tries(3, username, password):
print("Login failed")
sys.exit(1) # End program
... # Rest of program
Related
I want to create a login page script with the username and password as the data account from db. n then when my input is doesn't match the else didn't execute while username and password is did not exist in db. so what should i do to fix this. any somebody help me please
def logindb():
print ("=="*15+"\nPlease insert your username and password.")
username = input ("Username : ")
password = input ("Password : ")
cursor.execute(f"SELECT * FROM data WHERE username='{username}' and password='{password}'")
result = cursor.fetchall()
for i in result:
if (i[0]) == username and (i[1]) == password:
print ("=="*15+"\n\tLogin Success.\n"+"=="*15)
else:
print ("=="*15+"\nUsername or password is wrong.\n"+"=="*15)
In your code snippet, the statement can NEVER be else!
You query for a database entries matching username and password. For every entry (with the matching username and password) you again check if these credentials are correct.
I guess what you want, is to check if there are records found.
Something like this:
result = cursor.fetchall()
if (len(result) > 0):
print ("=="*15+"\n\tLogin Success.\n"+"=="*15)
else:
print ("=="*15+"\nUsername or password is wrong.\n"+"=="*15)
Side note: you really should hash the password instead of saving it as plain text in the database.
Try changing:
cursor.execute(f"SELECT * FROM data WHERE username='{username}' and password='{password}'")
To:
cursor.execute(f"SELECT username, password FROM data WHERE username='{username}' and password='{password}'")
You're selecting ALL* columns, and if your 0 index column is not username, and your 1 index column is not password, your query result will not match up your submitted username and password.
if (i[0]) == username and (i[1]) == password:
It's also not a good idea to run your SELECT statements wide open if you don't need to. Retrieve only the columns explicitly that you need to retrieve.
You should really use a parameterized query.
But if you are going to use this method of data retrieval then I would go one step further then Griv's answer
cursor.execute(f"SELECT userid FROM data WHERE username='{username}' and password='{password}'")
I would never fetch the username or password. Instead, check for its existence by fetching the primary key of the table.
Then check if that value is null or not.
I am not familiar with python, I assume the f"SELECT is not a typo
I am using qt to create a user login. I am using Sqlite as my database and am stuck for some reason it is not working properly. I was able to corectly bypass the login screen only when typing in the first row from the database. Any other user cannot log in (row 2, 3,4 ... in database). I have been reading all kinds of posts for the past days and have not come to a proper solution. Here is my code. I have also tried creating a query through QSqlQuery and passing it into the QSQlQueryModel Object which did not work at all.
void MainWindow::on_login_clicked()
{
QSqlDatabase m_db;
QString path = "C:/Users/annea/Summer2019Database.db";
m_db = QSqlDatabase::addDatabase("QSQLITE");
m_db.setDatabaseName(path);
m_db.open();
if (!m_db.open())
{
qDebug() << "Error: connection with database fail";
}
else
{
qDebug() << "Database: connection ok";
}
QString username = ui->username->text();
QString password = ui->password->text();
QSqlQueryModel *queryModel = new QSqlQueryModel;
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
queryModel->query().exec(); //execute it (not really sure why or what this does
if(queryModel->record(0).value(1).toString()== password) //if a row is found check column 2 for password
{
destroy(); //destroy current window
if(queryModel->record(0).value(3).toString()== 1) //if id is equal to one log in as user
{
user.showMaximized();
}
else {
dbManager.showMaximized();
}
}
else {
qWarning("Wrong Password or Username");
}
}
I think your query is wrong. Instead of writing like this:
queryModel->setQuery("SELECT * FROM [User Database] WHERE Username= username"); //select the row of where the Username == username
You might want writing like this:
queryModel->setQuery(QString("SELECT * FROM [User Database] WHERE Username = '%1'").arg(username)); //select the row of where the Username == username
Why? Because you are writing a query, and you probably want to check against the user name entered, not the string "username". Also, don't forget apostrophes when comparing.
In order to find more information which might help with your problem, you should read Qt's documentation regarding its' classes. Also, it would be beneficial to take a look into the SQLite WHERE clause and how strings are represented when writing queries:
https://doc.qt.io/qt-5/qsqlquerymodel.html#setQuery
https://doc.qt.io/qt-5/qsqlquery.html#QSqlQuery-1
http://www.sqlitetutorial.net/sqlite-where/
https://www.sqlite.org/datatype3.html
I am writing a chef resource, which will generate a password, and I am calling that resource in a recipe with the list of inputs.
Following is my scenario: Once my resource got executed, a new set of passwords will be generated in a folder, and I want to retrieve that password which is newly generated. But I am unable to retrieve that password because the value I am trying to retrieve is executing at the convergence phase.
Simple code block to explain my scenario:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
The code above will create new passwords in a folder.
Later, I am trying to take the passwords through a JSON Parser:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
The #{new_password_dir} is the directory location of the newly created password.json file.
I am trying to use the value of "new_wls_password" in the another resource like below:
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{new_wls_password}"
end
Here, the new password which I am trying to retrieve is empty, since the following three lines are executed in the first place:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
So, by that time, the new passwords resource has not been run.
I tried many stack overflow suggestions, like:
putting those three lines in a ruby_block like this
ruby_block "new_password" do
block do
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
node.set[:new_wls_password] = data_hash['rase_wlsadmin_pwd']
end
end
Then I tried fetching the value into the resource as below
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{node[:new_wls_password]"
end
With the above approach still the value is empty
Trying the value with lazy and calling that value.
Passing the value from one ruby block to another ruby block, which I can do, but not with the resources.
Please, can you help?
EDIT #1 :
I need to pass the value from the resource to the template.
Something like this, after running the following resource:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
A new set of passwords will be generated in a folder, like the /tmp/password.json file.
After the resource execution above I am writing a template like:
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables
({ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => "#{new_wls_password}" })
end
Here, how can I parse the newly created value of "new_wls_password" ?
You can use lazy attribute like below:-
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password lazy { JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }
end
Template resource can be written as:-
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables (lazy{{ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }})
end
Output:-
* template[/tmp/kitchen/cache/domain.properties] action create
- create new file /tmp/kitchen/cache/domain.properties
- update content in file /tmp/kitchen/cache/domain.properties from none to fa22e0
--- /tmp/kitchen/cache/domain.properties 2017-01-12 03:30:13.002968715 +0000
+++ /tmp/kitchen/cache/.chef-domain20170112-11387-1ytkyk2.properties 2017-01-12 03:30:13.002968715 +0000
## -1 +1,4 ##
+domain_name= mmm
+admin_url= nnn
+new_wls_password= xH#3zIS9Q4Hc#B
item = test.query('SELECT userName FROM Database.Users WHERE userName = "user"', function (err,result){
if(err) throw err;
else if('user' == / something correct /){
console.log("TRUE");
}
console.log(result[0]);
});
What I want to do is to check if the user gives a valid username, like you would when logging in to a form of some sort. Now I might have taken the wrong approach but I've tried the following.
I tried to basically check if there is a user with username 'user', which exists in the mysql database. Then I want to simple check that the fixed input 'user' exists by comparing to the result that one gets from querying the DB. However it doesn't seem to work as the console never prints out "TRUE". However when I print out result[0] i get:
{ userName: 'user' }
Which is expected yet I can't manage to retrieve the string 'user'.
The query won't fail if there isn't a record with that username. It will only return an empty result set. Take out all the error stuff and check for number of records. You could also do a SELECT count(*) as recCnt where user = '$usr' and check the value of the returned recCnt variable.
You can try to use results[0].userName in your console.log
I've received an old application which completely lacks user input sanitization and is vulnerable to sql injection. To prove gravity of the situation i need to give client an example and what can be better to scare him than the login process. I've tried standard techniques but the problem with them is that they return multiple rows and due to nature of the code it returns an error instead of logging him in. What sql should i inject so that only a single row is returned and the execution reaches "return $access" line in order to pass the value of this "access" column to code calling this login function. The request is made via POST method and magic quotes are off on the server. Please let me know if you need any other information.
function login($username, $pw)
{
global $dbname, $connection, $sqluser, $sqlpw;
$db = mysql_connect($connection,$sqluser,$sqlpw);
mysql_select_db($dbname);
if(!($dba = mysql_query("select * from users where username = '$username' AND password = '$pw'"))){
printf("%s", sprintf("internal error5 %d:%s\n", mysql_errno(), mysql_error()));
exit();
}
$row = mysql_fetch_array($dba);
$access = $row['access'];
if ($access != ''){
return $access;
} else {
return "error occured";
}
mysql_close ($db);
}
Note: it turns out that magic_quotes_gpc is turned on and the php version is 5.2.17
Thanks
Starting with the goal query:
SELECT *
FROM users
WHERE username = '' OR '1'='1'
AND password = '' OR 1=1 LIMIT 1;#'
We get username is ' OR '1'='1 and password is ' OR 1=1 LIMIT 1;#
It depends what values the login function is called with. If there's sanitation before passing it to the function it might actually be safe. However it's better to filter it right before the query so you can see that your built query is safe.
However if you have something like this:
login($_POST['user'], $_POST['pass']);
In that case just put foo' OR 1=1 OR ' in the user field in the login form :)