(1) is this way : http://code.google.com/intl/en/appengine/articles/djangoforms.html
(2) is write by self :
#/usr/bin/env python2.5
#----------------------------
# Datastore models for user & signup
#----------------------------
from base64 import b64encode as b64
from hashlib import md5, sha256
from random import randint
from time import time
from google.appengine.ext import db
N_SALT = 8 # length of the password salt
def salt_n_hash(password, salt=None):
"""
Generate a salt and return in base64 encoding the hash of the
password with the salt and the character '$' prepended to it.
"""
salt = salt or b64( ''.join(chr(randint(0, 0xff)) for _ in range(N_SALT)) )
return salt + '$' + b64( sha256(salt+password.encode("ascii")).digest() )
class User(db.Model):
nickname = db.StringProperty(required=True)
email = db.EmailProperty(required=True)
pwd = db.StringProperty(required=True)
suspended = db.BooleanProperty(default=True)
#classmethod
def authenticate(klass, nickname, password):
"""Return an User() entity instance if password is correct"""
user = klass.get_by_key_name(nickname)
if user:
n_salt = user.pwd.index('$')
if user.pwd == salt_n_hash(password, salt=user.pwd[:n_salt]):
return user
def __eq__(self, other):
return self.nickname == other.nickname
def signup_id(nickname):
return md5( nickname + repr(time()) ).hexdigest()
class UserSignup(db.Model):
user = db.ReferenceProperty(User, required=True)
date = db.DateProperty(auto_now_add=True)
which way is better ,
or did you have better way to do this , ex: a simply form Validation framework,
thanks
If you're using Django, djangoforms is definitely the way to go. If tipfy or other light-weight frameworks, try wtforms (it's also in the tipfy source tree).
Related
backend = default_backend()
salt = b'2444'
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
backend=backend
)
This is the kdf setup.
def getMasterPassword():
checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
global encryptionKey
encryptionKey = base64.urlsafe_b64encode(kdf.derive(txt.get().encode()))
cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
return cursor.fetchall()
def checkPassword():
password = getMasterPassword()
if password:
vaultScreen()
else:
txt.delete(0, 'end')
This is my hash algorithm
in derive
raise AlreadyFinalized("PBKDF2 instances can only be used once.")
cryptography.exceptions.AlreadyFinalized: PBKDF2 instances can only be used once.
This is the error I am getting when input a wrong password and then try to re-enter it.
Libraries used:
sqlite
hashlib
tkinter
customtkinter
functools
uuid
pyperclip
base64
cryptography
this should work correctly. basically what i found out is that you can't have "encryptionKey = base64.urlsafe_b64encode(kdf.derive(txt.get().encode())" being ran more than once so you basically need to put it somewhere that it can only be accessed once and in this instance it's only when your password is correct. creating a logout system would be difficult to do but not impossible.
def getMasterPassword():
global Pss
Pss = txt.get().encode()
checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
return cursor.fetchall()
def checkPassword():
password = getMasterPassword()
if password:
vaultScreen()
global encryptionKey
global Pss
encryptionKey = base64.urlsafe_b64encode(kdf.derive(Pss))
else:
txt.delete(0, 'end')
Instead of using the same "PBKDF2" instance, you can change "kdf" variable into a function that initializes a new "PBKDF2" instance for every login attempt:
def kdf():
return PBKDF2HMAC(algorithm=hashes.SHA256(), length=32, salt=salt, iterations=100000, backend=backend)
Then your "getMasterPassword" function should be changed to:
def getMasterPassword():
checkHashedPassword = hashPassword(txt.get().encode('utf-8'))
global encryptionKey
encryptionKey = base64.urlsafe_b64encode(kdf().derive(txt.get().encode()))
cursor.execute('SELECT * FROM masterpassword WHERE id = 1 AND password = ?', [(checkHashedPassword)])
return cursor.fetchall()
Not sure if this approach has any cons that you should be aware of, but it should work as intended.
I want to create some users just to populate my database, so using decorators I created a method inside a class for it. I returned the results into a list and used the information without a problem. But after a while I thought that once I was working with classes wouldn't be dumb to use lists? I feel that I am kind of moving backwards since, at least in my understanding, it might be possible to access those values directly.. But the truth is I struggled on attempting to instantiate dynamically and access those instances. So, how could I do that properly? Here is the code I wrote in the first attempt:
class User:
def __init__(self, user_name, password, email, i=0):
self.user_name = user_name
self.password = password
self.email = email
#classmethod
def from_generate(cls, amount):
user_name = 'user' + str(amount)
password = 'password000.' + str(amount)
email = 'user' + str(amount) + "#whatever.com"
return cls(user_name, password, email)
in another file:
def user_generator(user_qty=0):
user_list = []
for i in range(1, user_qty + 1):
# call the class method to generate users
instance = User.from_generate(i)
user_list.append(instance)
return(user_list)
users = user_generator(5)
if __name__ == "__user_generator__":
user_generator()
I am trying to simulate a system access portal using classes and methods. I want to be able to ask the user for their username using input(), check if that input is an object of class User and if so, check if the password is correct for the username. When I use instance of it is returning false. How can I modify this to work?
class User():
def __init__(self, username, password):
self.username = username
self.password = password
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon","AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(isinstance(input_user, User))
User inputs are strings. Always. Period. So you can not "check if that input is an object of class User" - it will never be.
The solution here is to maintain a collection of User instances, and use the input string to search for a matching user.
class UsersCollection(object):
def __init__(self):
# we store users in a dict, with user.usernale as key
self._users = {}
def add(self, user):
if user.username in self._users:
raise ValueError("username '{}' already in used".format(user.username))
self._users[user.username] = user
def get(self, username):
return self._users.get(username)
users = UsersCollection()
users.add(User("jshannon","AbC!23"))
input_user = input("What is your username? ").strip()
userfound = users.get(input_user)
if userfound:
# you can do something with your user
else:
print("sorry, we don't know you")
Note that this is only suitable as a toy project of course.
If you are using Python 3.x (which I'm going to assume), input returns a string so isinstance(input_user, User) will always be False.
You will need to keep track of all User objects created and search for the object with the inputted name.
There are several different ways to do that. I'm going to assume that usernames are unique so I will use them in a shared set:
class User:
users = set()
def __init__(self, username, password):
self.username = username
self.password = password
self.users.add(username)
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon", "AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(input_user in User.users)
# will output True if input_user is jshannon, otherwise False
Note that this is just an example, and it is not bullet-proof nor the best design (one may argue if the users set even belongs to the User class Hint: probably not). If an object's username changes after the initialization the set will not be updated and you may get wrong results. This particular problem can be solved by changing self.username to a property but I suppose that is out of scope of this Q&A.
I am not sure if this is what you want to do but you cant try this
add a list to your class list_of_usernames = []
and then in __init__() append username to the list_of_usernames and at the end
print(input_user in User.list_of_usernames)
so your code will look like this
class User():
list_of_usernames = []
def __init__(self, username, password):
self.username = username
self.password = password
self.list_of_usernames.append(username)
def change_pw(self, new_password):
self.password = new_password
jshannon = User("jshannon","AbC!23")
print(jshannon.username)
print(jshannon.password)
jshannon.change_pw("(i*u&y1")
print(jshannon.password)
input_user = input("What is your username? ")
print(input_user in User.list_of_usernames)
I want visitors of my page to be able to create entries without registering first. When they register later I want everything they have created within that session to belong to their user account.
To achieve that I just want to create blank users with random usernames when entries from non users are made.
What is the most elegant way to create a unique username randomly avoiding any collision?
Should I just make a while loop that generates usernames and tries to save them to the db with a break upon success or is there a better way?
Most scripts I've seen just create a random string, but that has the danger of a collision. Is there any Django function that creates random usernames based on which usernames are already taken?
No, django doesn't have such function. So you have to check for the existence of the generated username in the loop.
I created a mixin that creates a random username based on firstname, lastname and makes sure this username doesnt already exist in db User model:
random_username_mixin.py
import random
import string
from core.models import CustomUser
class RandomUsernameMixin:
"""
using firstname & lastname
create a random username (all lower case)
that doesnt already exist in db
"""
num_of_random_letters = 3
num_of_random_numbers = 2
user_model = CustomUser
def get_username(self, firstname=None, lastname=None):
username = ''
if firstname and lastname \
and firstname != '' and lastname != '':
username = firstname[0] + lastname[0]
while True:
random_letters = string.ascii_lowercase
random_numbers = string.digits
username += self.get_random_char(
random_letters, self.num_of_random_letters
)
username += self.get_random_char(
random_numbers, self.num_of_random_numbers
)
if self.username_exist_in_db(username) is False:
return username
def username_exist_in_db(self, username):
"""
:return: True if username already exist in db
else False
"""
q = self.user_model.objects.filter(username=username)
return q.exists()
def get_random_char(self, ip_str, n):
return (''.join(
random.choice(ip_str)
for i in range(n)
))
Following is the testing code. It tests the above code:
test_random_username_mixin.py
from django.test import TestCase
from miscellaneous.mixins.random_username_mixin import RandomUsernameMixin
class TestRandomUsernameMixin(RandomUsernameMixin,
TestCase):
def test_username_with_fn_ln(self):
fn = 'aseem'
ln = 'hegshetye'
username = self.get_username(
firstname=fn, lastname=ln
)
len_of_initials = 2
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
def test_username_without_fn_ln(self):
username = self.get_username()
len_of_initials = 0
len_of_username = self.num_of_random_numbers + \
self.num_of_random_letters + \
len_of_initials
self.assertEqual(len(username), len_of_username)
print(username)
I have the following example code which uses either MongoEngine and Peewee as DB backends.
import mongoengine, peewee
from mongomodels import *
from mysqlmodels import *
class Parser(object):
def __init__(self, line, dbBackend):
if dbBackend in ["MongoDB","MySQL"]:
self.line = line
self.DB = dbBackend
user = self.createUser()
car = self.createCar(user)
parking = self.createParking(car)
else:
raise Exception()
def createUser(self):
if self.DB == "MongoDB":
newUserID = self._createMongoUser(self.line['firstname'], self.line['lastname'], '...')
else:
newUserID = self._createMySQLUser(self.line['firstname'], self.line['lastname'], '...')
return newUserID
def _createMongoUser(self, firstname, lastname, '...'):
try:
_user = MongoUserModel.objects.get(firstname=firstname, lastname=lastname)
except mongoengine.errors.DoesNotExist as e:
user = MongoUserModel(firstname=firstname, password)
_user = user.save()
finally:
return _user
def _createMySQLUser(self, firstname, lastname, '...'):
try:
_user = MySQLUserModel.get(MySQLUserModel.fistname == firstname, MySQLUserModel.lastname == lastname )
except Exception as e:
user = MySQLUserModel(fistname=fistname, lastname=lastname)
_user = user.save()
finally:
return _user
def createCar(self, user):
pass
def createParking(self, car):
pass
Is there any good practice / trick / module to keep my code DRY and to avoid redefining two methods to create my Models?
Should I can create a new abstraction class 'UserModel' as does PDO in PHP?
This is something I went through recently - I swapped from a mongo backend to postgres. When I set up the original project I had some models and a DataLayer. The datalayer (dl) had quite a simple interface that I used throughout my app.
# note: this is half python / half pseudocode
class Model1(object):
__collection__ = 'model1'
__tablename__ = 'model1'
# field definitions etc
class MongoDataLayer(object):
def __init__(self, mongo_db_connection):
self.conn = mongo_db_connection
def load(self, model, conditions):
raw = self.conn[model.__collection__].find(...)
return model(**raw)
def persist(self, obj):
self.conn[obj.__collection__].save(obj.as_dict())
class SQLDataLayer(object):
def __init__(self, sa_session_factory):
self.Session = sa_session_factory
self.session = self.Session()
def load(self, model, conditions):
return self.session.query(model).find_by(conditions).one() # ...etc
def persist(self, obj):
self.conn[obj.__collection__].save(obj)
# connections - mongo and postgres (I use SQLAlchemy)
dl_mongo = MongoDataLayer(db...)
dl_sql = SQLDataLayer(Session...)
# using them - you don't care which one you have
m = dl_mongo.load(models.Model1)
dl_mongo.persist(m)
m = dl_sql.load(models.Model1)
dl_sql.persist(m)
In my app I load up the dl in the initial load and then inject it into the app whenever data access needs to happen. The app itself then knows about models but not the details of how to load / save them.
Maybe not the best way to do it but it's worked well for me. Would be interested to hear how other people deal with it.