how to list an object arguments in python? - python

Consider this code:
import mysql.connector
db = mysql.connector.connect(url = "url", username = "myusername", password = "mysecretpassword")
Is it possible to get the argument of the password parameter from the db object?

Not sure why you would want to, but no you can't. You can read the mysql.connector documentation and see that it does not expose the password as an attribute.
You could also run dir(db) to see what it supports.

Related

"Not a valid password" error when reflecting an encrypted Access database

i'm beginner in sqlalchemy, i want to reflect my table in database to object, but always return invalid password, even though the password is correct. I dont understand why this happend. When i try to inspect they return my table name, so my password, connection string or on create_engine is correct.
when my database have no password is fine i can reflect it to Object, that's so weird.
but why when i reflect database with password it's error, always return "Not a valid password" ??,
My MS. Access Tbl 1
My MS. Access Tbl 2
Error in Reflect but My Table name is returned
This is my Code
because I was curious I also made a test select data, and it turned out to be successful in retrieving the data
it's returned my data and success created connection
when i add some code for testing
I think all it's correct but why cannot reflect??, Please Help.
My Reference connection_string
My Reference SqlAlchemy Automap Reflect
I have just released sqlalchemy-access version 1.1.1 to address this issue. Note that as described in Getting Connected if you want to use a pass-through ODBC connection string with an encrypted database you need to supply the password in two places:
driver = "{Microsoft Access Driver (*.mdb, *.accdb)}"
db_path = r"C:\Users\Public\test\sqlalchemy-access\gord_test.accdb"
pwd = "tiger"
connection_string = (
f"DRIVER={driver};"
f"DBQ={db_path};"
f"PWD={pwd};"
f"ExtendedAnsiSQL=1;"
)
connection_uri = (
f"access+pyodbc://admin:{pwd}#/"
f"?odbc_connect={urllib.parse.quote_plus(connection_string)}"
)
engine = sa.create_engine(connection_uri)

Problem in using getpass with psycog for password management

My goal is to use getpass to hide the entry of my password when I connect to a postgresql database via python3.
I use python3 on jyputer notebook.
This work well :
connect = psycopg2.connect("dbname='db_toto' user='dad' host='xx.xx.xxx.x' port='5432' password='123456'")
cur = connect.cursor()
But when I try to enter the password with a separate variable, it does not work anymore :
pw = getpass.getpass()
####Python ask me to tape password and i tape the same '123456'
To verify :
'123456'
connect=psycopg2.connect("dbname='db_toto' user='dad' host='xx.xx.xxx.x' port='5432' password=pw")
cur=connect.cursor()
" OperationalError: FATAL: password authentication failed for user
FATAL: password authentication failed for user "
received error message
Thanks you for your help
What you're doing is passing a string to the connect function. This string has the value of "dbname='db_toto' user='dad' host='xx.xx.xxx.x' port='5432' password=pw". The psycopg2 module has no way of knowing what pw is. I suspect it will be converted to a string ('pw'), but I'm not sure.
Anyway, the correct approach would be to pass keyword arguments to the connect function like so:
connect = psycopg2.connect(dbname='db_toto' user='dad' host='xx.xx.xxx.x' port='5432' password=pw)
# Notice the lack of double-quotes in the arguments
This way, you will be passing the contents of the pw variable to the function, instead of the name pw.
It is possible to pass the contents of the pw variable in string form as well, like so:
connect = psycopg2.connect("dbname='db_toto' user='dad' host='xx.xx.xxx.x' port='5432' password='{}'".format(pw))
The first form should be preferred.

Python pymysql cant accept special characters in the password string, How to bypass this?

I have code to read the credentials from an external config file,
configParser = ConfigParser.RawConfigParser()
configFilePath = r'docs/credentials.cfg'
configParser.read(configFilePath)
AnD
User = configParser.get('your-config', 'user')
Pswd = configParser.get('your-config','pswd')
Host = configParser.get('your-config','hostdps')
db = pymysql.connect(host=Host, user=User, password=Pswd, db='xyz', charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor,local_infile=True)
The password contains special characters like : #?f8h!3, How to make connect statement understand these chars.?
I have already tried adding backslashes, passing it in connect string, not sure how to get this?
The mistake was adding quotes before the start of password string in the config file.
I was using : configParser = ConfigParser.RawConfigParser() so, it was treating " as part of the password.
Quite silly.

How to query a MySQL database via python using peewee/mysqldb?

I'm creating an iOS client for App.net and I'm attempting to setup a push notification server. Currently my app can add a user's App.net account id (a string of numbers) and a APNS device token to a MySQL database on my server. It can also remove this data. I've adapted code from these two tutorials:
How To Write A Simple PHP/MySQL Web Service for an iOS App - raywenderlich.com
Apple Push Notification Services in iOS 6 Tutorial: Part 1/2 - raywenderlich.com
In addition, I've adapted this awesome python script to listen in to App.net's App Stream API.
My python is horrendous, as is my MySQL knowledge. What I'm trying to do is access the APNS device token for the accounts I need to notify. My database table has two fields/columns for each entry, one for user_id and a one for device_token. I'm not sure of the terminology, please let me know if I can clarify this.
I've been trying to use peewee to read from the database but I'm in way over my head. This is a test script with placeholder user_id:
import logging
from pprint import pprint
import peewee
from peewee import *
db = peewee.MySQLDatabase("...", host="localhost", user="...", passwd="...")
class MySQLModel(peewee.Model):
class Meta:
database = db
class Active_Users(MySQLModel):
user_id = peewee.CharField(primary_key=True)
device_token = peewee.CharField()
db.connect()
# This is the placeholder user_id
userID = '1234'
token = Active_Users.select().where(Active_Users.user_id == userID)
pprint(token)
This then prints out:
<class '__main__.User'> SELECT t1.`id`, t1.`user_id`, t1.`device_token` FROM `user` AS t1 WHERE (t1.`user_id` = %s) [u'1234']
If the code didn't make it clear, I'm trying to query the database for the row with the user_id of '1234' and I want to store the device_token of the same row (again, probably the wrong terminology) into a variable that I can use when I send the push notification later on in the script.
How do I correctly return the device_token? Also, would it be easier to forgo peewee and simply query the database using python-mysqldb? If that is the case, how would I go about doing that?
The call User.select().where(User.user_id == userID) returns a User object but you are assigning it to a variable called token as you're expecting just the device_token.
Your assignment should be this:
matching_users = Active_Users.select().where(Active_Users.user_id == userID) # returns an array of matching users even if there's just one
if matching_users is not None:
token = matching_users[0].device_token

SQLAlchemy & PassLib

tl;dr -- How do I use a Python-side library such as PassLib to hash passwords before inserting them into a MySQL DB with SQLAlchemy?
Alright, so I've been banging my head on my desk for a day or two trying to figure this out, so here it goes:
I am writing a web application using Pyramid/SQLAlchemy and I'm trying to interface with my MySQL database's Users table.
Ultimately, I want to do something like the following:
Compare a password to the hash:
if user1.password == 'supersecret'
Insert a new password:
user2.password = 'supersecret'
I'd like to be able to use PassLib to hash my passwords before they go to the database, and I'm not really a fan of using the built-in MySQL SHA2 function since it's not salted.
However, just to try it, I do have this working using the SQL-side function:
from sqlalchemy import func, TypeDecorator, type_coerce
from sqlalchemy.dialects.mysql import CHAR, VARCHAR, INTEGER
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column
class SHA2Password(TypeDecorator):
"""Applies the SHA2 function to incoming passwords."""
impl = CHAR(64)
def bind_expression(self, bindvalue):
return func.sha2(bindvalue, 256)
class comparator_factory(CHAR.comparator_factory):
def __eq__(self, other):
local_pw = type_coerce(self.expr, CHAR)
return local_pw == func.sha2(other, 256)
class User(Base):
__tablename__ = 'Users'
_id = Column('userID', INTEGER(unsigned=True), primary_key=True)
username = Column(VARCHAR(length=64))
password = Column(SHA2Password(length=64))
def __init__(self, username, password):
self.username = username
self.password = password
This was copied from the example 2 at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DatabaseCrypt
So that works and allows me to use the built-in MySQL SHA2 function (by calling func.sha2()) and do exactly what I want. However, now I'm trying to replace this with PassLib on the Python side.
PassLib presents two functions: one to create a new password hash, and one to verify a password:
from passlib.hash import sha256_crypt
new_password = sha256_crypt.encrypt("supersecret")
sha256_crypt.verify("supersecret", new_password)
I can't quite figure out how to actually implement this. Having read all the documentation, I think it is either a different form of TypeDecorator, a custom type declaration, a hybrid value, or a hybrid property. I tried following this, but it doesn't really make sense to me nor does the code suggested there actually run.
So, to sum up my question -- how do I overload the = and == operators so that they run things through the appropriate hash functions?
PasswordType from sqlalchemy-utils should be the best fit for this issue. It uses passlib. Snipped from the docs:
The following usage will create a password column that will automatically hash new passwords as pbkdf2_sha512 but still compare passwords against pre-existing md5_crypt hashes. As passwords are compared; the password hash in the database will be updated to be pbkdf2_sha512.
class Model(Base):
password = sa.Column(PasswordType(
schemes=[
'pbkdf2_sha512',
'md5_crypt'
],
deprecated=['md5_crypt']
))
Verifying password is as easy as:
target = Model()
target.password = 'b'
# '$5$rounds=80000$H.............'
target.password == 'b'
# True
As I understand it, what you want is this:
Encrypt the user's password when creating the account. Use your salt and algorithm
When the user logs in, hash the incoming password the same way you did when you stored it
Compare the two hashes using regular string comparison in your db request
So, something like this for the login code:
from passlib.hash import sha256_crypt
passHash = sha256_crypt.encrypt(typed_password)
// call your sqlalchemy code to query the db with this value (below)
// In your SQLAlchemy code assuming "users" is your users table
// and "password" is your password field
s = users.select(and_(users.username == typed_username, users.password == passHash))
rs = s.execute()
rs would be the resultset of matching users (should be zero or one of course).
Disclaimer - I did not test any of this
Edit:
Thank you for pointing out that PassLib uses a different salt each time it's run. Your best bet in that case, since there doesn't seem to be a straightforward way to do it with sqlalchemy, is the below:
s=users.select(users.username == typed_username)
rs = s.execute()
userRow = rs.fetchone()
if (sha256_crypt.verify(userRow.password)):
# you have a match
Also, to address your request for abstracting: a common methodology for handling this operation is to create a "security" utility class for getting the user (object) that matches the passed login credentials.
The problem with your current setup is that the User constructor has two different operational goals that, though related, are not necessarily the same thing: authenticating a user and getting a User object (for, say, a list of users in a group). The constructor becomes needlessly complex in that case. It's better to put that logic where it can be encapsulated with other security or login-related functionality such as logging in a user via session ID or SSO token instead of username/password:
security.loginUser(username, password)
# or security.loginUser(single_sign_on_token), etc. for polymorphic Security
loggedInUser = security.getLoggedInUser()
... later ...
otherUser = User(username) #single job, simple, clean

Categories