def test_authenticate_with_token(): from time import time db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, token_life=3 * 60) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() token = user.get_token() auth_user = auth.authenticate({'token': token}) assert auth_user token = '555' + user.get_token() auth_user = auth.authenticate({'token': token}) assert not auth_user auth_user = auth.authenticate({'token': ''}) assert not auth_user timestamp = int(time()) - auth.token_life + 1 token = user.get_token(timestamp) auth_user = auth.authenticate({'token': token}) assert auth_user timestamp = int(time()) - auth.token_life - 1 token = user.get_token(timestamp) auth_user = auth.authenticate({'token': token}) assert not auth_user
def test_user_has_empty_password(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, password_minlen=0) User = auth.User db.create_all() user = User(login=u'meh', password=u'') db.session.add(user) db.session.commit() assert user.password != u'' auth_user = auth.authenticate({'login': u'meh', 'password': u''}) assert auth_user auth_user = auth.authenticate({}) assert not auth_user auth_user = auth.authenticate({'login': u'meh', 'password': None}) assert not auth_user auth_user = auth.authenticate({'login': u'meh'}) assert not auth_user auth_user = auth.authenticate({'login': u'wtf', 'password': ''}) assert not auth_user auth_user = auth.authenticate({'login': u'meh', 'password': '******'}) assert not auth_user
def _get_flask_app(roles=False, **kwargs): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth( SECRET_KEY, db=db, roles=roles, password_minlen=3, **kwargs) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.add(user) user2 = User(login=u'foo', password='******') db.add(user2) db.commit() app = Flask('test') app.secret_key = os.urandom(32) app.testing = True @app.route('/protected/') @auth.protected() def protected(): return u'Welcome' authcode.setup_for_flask(auth, app) auth.session = {} return auth, app, user
def test_models_mixins(): db = SQLAlchemy('sqlite:///:memory:') class UserMixin(object): email = db.Column(db.Unicode(300)) def __repr__(self): return 'overwrited' class RoleMixin(object): description = db.Column(db.UnicodeText) auth = authcode.Auth(SECRET_KEY, db=db, UserMixin=UserMixin, RoleMixin=RoleMixin) User = auth.User Role = auth.Role db.create_all() user = User(login=u'meh', password='******', email=u'*****@*****.**') db.session.add(user) db.flush() assert User.__tablename__ == 'users' assert user.login == u'meh' assert user.email == u'*****@*****.**' assert hasattr(user, 'password') assert hasattr(user, 'last_sign_in') assert repr(user) == 'overwrited' assert hasattr(Role, 'description')
def test_define_table(): db = SQLAlchemy(URI1) db.Table('foobar', db.Column('foo', db.UnicodeText), db.Column('bar', db.UnicodeText)) db.Table('fizzbuzz', db.metadata, db.Column('fizz', db.Integer), db.Column('buzz', db.Integer)) db.create_all()
def test_replace_hash_password_method(): """Can the library work the same with custom ``has_password`` and ``password_is_valid`` methods? """ class CustomAuth(authcode.Auth): def hash_password(self, secret): secret = self.prepare_password(secret) return secret[::-1] def password_is_valid(self, secret, hashed): secret = self.prepare_password(secret) if secret is None or hashed is None: return False return self.hash_password(secret) == hashed db = SQLAlchemy('sqlite:///:memory:') auth = CustomAuth(SECRET_KEY, db=db) User = auth.User db.create_all() credentials = {'login': u'meh', 'password': '******'} user = User(**credentials) db.session.add(user) db.session.commit() assert user.password == 'foobar'[::-1] assert user.has_password('foobar') auth_user = auth.authenticate(credentials) assert user.login == auth_user.login auth_user = auth.authenticate({}) assert not auth_user
def test_authenticate_with_password(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() credentials = {'login': u'meh', 'password': '******'} user = User(**credentials) db.session.add(user) db.session.commit() auth_user = auth.authenticate(credentials) assert user.login == auth_user.login auth_user = auth.authenticate({}) assert not auth_user auth_user = auth.authenticate({'login': u'meh'}) assert not auth_user auth_user = auth.authenticate({'login': u'wtf', 'password': '******'}) assert not auth_user auth_user = auth.authenticate({'login': u'meh', 'password': '******'}) assert not auth_user
def test_custom_poolclass(): class _CustomPool(pool.StaticPool): _do_return_conn = mock.MagicMock() db = SQLAlchemy(URI1, poolclass=_CustomPool) db.create_all() _CustomPool._do_return_conn.assert_called_once()
def test_automatic_case_insensitiveness(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'MeH', password='******') db.session.add(user) db.session.commit() assert user.login == u'meh' assert User.by_login(u'MEH') == User.by_login(u'MeH') == user
def test_role_model(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, roles=True) Role = auth.Role db.create_all() role = Role(name=u'admin') db.session.add(role) db.commit() assert role.name == u'admin' assert repr(role) == '<Role admin>'
def test_user_model_to_dict(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, roles=True) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.commit() user_dict = user.to_dict() assert user_dict
def test_set_raw_password(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, roles=True) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() assert user.password != 'foobar' user.set_raw_password('foobar') assert user.password == 'foobar'
def test_backwards_compatibility(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.commit() assert user._password == user.password user._password = '******' assert user.password == 'raw'
def test_formset_missing_objs(): db = SQLAlchemy() class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) class Address(db.Model): __tablename__ = 'addresses' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) user = db.relationship('User', backref=db.backref('addresses', lazy='dynamic')) def __repr__(self): return self.email db.create_all() class FormAddress(f.Form): _model = Address email = f.Text(validate=[f.ValidEmail]) def __repr__(self): return '<FormAddress %s>' % (self.email.value,) class FormUser(f.Form): _model = User name = f.Text() addresses = f.FormSet(FormAddress, parent='user') user = User(name=u'John Doe') db.add(user) a1 = Address(email=u'*****@*****.**', user=user) db.add(a1) a2 = Address(email=u'*****@*****.**', user=user) db.add(a2) a3 = Address(email=u'*****@*****.**', user=user) db.add(a3) db.commit() print([(a.id, a.email) for a in user.addresses]) data = { 'name': u'Jane Doe', 'formaddress.1-email': u'*****@*****.**', 'formaddress.3-email': u'*****@*****.**', 'formaddress.4-email': u'*****@*****.**', } form = FormUser(data, user) assert form.is_valid() assert form.addresses.missing_objs == [a2]
def test_id_mixin(): db = SQLAlchemy(URI1) class IDMixin(object): id = db.Column(db.Integer, primary_key=True) class Model(db.Model, IDMixin): field = db.Column(db.String) db.create_all() assert Model.__tablename__ == 'models' assert hasattr(Model, 'id')
def test_get_uhmac(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() assert user.get_uhmac() assert user.get_uhmac() == user.get_uhmac()
def test_custom_templates(): db = SQLAlchemy('sqlite:///:memory:') options = { 'template_sign_in': 'sign-in.html', 'template_sign_out': 'sign-out.html', 'template_reset': 'reset-password.html', 'template_reset_email': 'reset-password-email.html', 'template_change_password': '******', } inbox = [] def send_email(user, subject, msg): inbox.append(msg) auth = authcode.Auth(SECRET_KEY, db=db, **options) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.add(user) db.commit() custom_templates = os.path.join( os.path.dirname(__file__), 'custom_templates' ) app = Flask('test', template_folder=custom_templates) app.secret_key = os.urandom(32) app.testing = True authcode.setup_for_flask(auth, app, send_email=send_email) auth.session = {} client = app.test_client() resp = client.get(auth.url_sign_in) assert resp.data == b'OK SIGN IN' resp = client.get(auth.url_reset_password) assert resp.data == b'OK RESET PASSWORD' data = dict(login=user.login, _csrf_token=auth.get_csrf_token()) resp = client.post(auth.url_reset_password, data=data) assert inbox[0] == 'OK RESET PASSWORD EMAIL' auth.login(user) resp = client.get(auth.url_change_password) assert resp.data == b'OK CHANGE PASSWORD' url = '{0}?_csrf_token={1}'.format(auth.url_sign_out, auth.get_csrf_token()) resp = client.get(url) assert resp.data == b'OK SIGN OUT'
def test_query(): db = SQLAlchemy(URI1) ToDo = create_test_model(db) db.create_all() db.add(ToDo('First', 'The text')) db.add(ToDo('Second', 'The text')) db.flush() titles = ' '.join(x.title for x in db.query(ToDo).all()) assert titles == 'First Second' data = db.query(ToDo).filter(ToDo.title == 'First').all() assert len(data) == 1
def test_flask_sqlalchemy_query(): db = SQLAlchemy(URI1) ToDo = create_test_model(db) db.create_all() db.add(ToDo('First', 'The text')) db.add(ToDo('Second', 'The text')) db.flush() titles = ' '.join(x.title for x in ToDo.query.all()) assert titles == 'First Second' data = ToDo.query.filter(ToDo.title == 'First').all() assert len(data) == 1
def test_automatic_password_hashing(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, hash='pbkdf2_sha512', rounds=10) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() assert user.password assert user.password != 'foobar' assert user.has_password('foobar')
def test_custom_metaclass(): class _CustomMeta(_BoundDeclarativeMeta): def __init__(self, name, bases, dic): _BoundDeclarativeMeta.__init__(self, name, bases, dic) if hasattr(self, 'id'): setattr(self, 'test', 1) db = SQLAlchemy(URI1, metaclass=_CustomMeta) class Model(db.Model): id = db.Column(db.Integer, primary_key=True) db.create_all() assert Model.test == 1
def test_model_helpers(): db = SQLAlchemy() class Row(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(60), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) db.create_all() db.add(Row(name='a')) db.flush() row = db.query(Row).first() assert str(row) == '<Row>' assert dict(row)['name'] == 'a'
def test_user_model(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, roles=True) assert auth.users_model_name == 'User' assert auth.roles_model_name == 'Role' User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.commit() assert user.login == u'meh' assert user.email == user.login assert hasattr(user, 'password') assert hasattr(user, 'last_sign_in') assert repr(user) == '<User meh>'
def test_aggregated_query(): db = SQLAlchemy(URI1) class Unit(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(60)) price = db.Column(db.Integer) db.create_all() db.add(Unit(price=25)) db.add(Unit(price=5)) db.add(Unit(price=10)) db.add(Unit(price=3)) db.commit() res = db.query(db.func.sum(Unit.price).label('price')).first() assert res.price == 43
def test_multiple_databases(): db1 = SQLAlchemy(URI1) db2 = SQLAlchemy(URI2) ToDo1 = create_test_model(db1) ToDo2 = create_test_model(db2) db1.create_all() db2.create_all() db1.add(ToDo1('A', 'a')) db1.add(ToDo1('B', 'b')) db2.add(ToDo2('Q', 'q')) db1.add(ToDo1('C', 'c')) db1.commit() db2.commit() assert db1.query(ToDo1).count() == 3 assert db2.query(ToDo2).count() == 1
def test_login_logout(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() session = {} auth.login(user, session=session) print(session) assert session[auth.session_key] == user.get_uhmac() auth.logout(session=session) assert auth.session_key not in session
def test_save(): db = SQLAlchemy() class Contact(db.Model): id = db.Column(db.Integer, primary_key=True) subject = db.Column(db.Unicode, nullable=False) email = db.Column(db.Unicode) message = db.Column(db.UnicodeText, nullable=False) db.create_all() class MyContactForm(f.Form): _model = Contact subject = f.Text(validate=[f.Required]) email = f.Text(validate=[f.ValidEmail]) message = f.Text(validate=[ f.Required(message=u'write something!') ]) # Create new object data = { 'subject': u'foo', 'message': u'bar', 'email': u'*****@*****.**', } form = MyContactForm(data) assert form.is_valid() contact = form.save() print('contact', contact.__dict__) assert isinstance(contact, Contact) assert contact.id is None assert contact.subject == data['subject'] assert contact.message == data['message'] assert contact.email == data['email'] db.commit() # Update object data['message'] = u'lalala' form = MyContactForm(data, obj=contact) assert form.is_valid() contact = form.save() assert contact.id is not None assert contact.message == data['message'] db.commit()
def test_sql_injection(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, roles=True) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() tests = [ "1'; DELETE FROM users", '1"; DELETE FROM users', "1' --", ] for passw in tests: user.set_raw_password(passw) db.session.commit() assert user.password == passw
def test_prefix_save(): db = SQLAlchemy() class Contact(db.Model): id = db.Column(db.Integer, primary_key=True) subject = db.Column(db.Unicode, nullable=False) email = db.Column(db.Unicode) message = db.Column(db.UnicodeText, nullable=False) db.create_all() class MyContactForm(f.Form): _model = Contact subject = f.Text(validate=[f.Required]) email = f.Text(validate=[f.ValidEmail]) message = f.Text(validate=[ f.Required(message=u'write something!') ]) data = { 'meh-subject': u'Hello', 'meh-message': u'Welcome', } form = MyContactForm(data, prefix='meh') assert form.is_valid() contact = form.save() assert isinstance(contact, Contact) db.commit() assert contact.subject == data['meh-subject'] assert contact.message == data['meh-message'] data = { 'meh-subject': u'foo', 'meh-message': u'bar', } form = MyContactForm(data, obj=contact, prefix='meh') assert form.is_valid() assert form.has_changed form.save() db.commit() assert contact.subject == data['meh-subject'] assert contact.message == data['meh-message']
def test_user_model_methods(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.commit() assert User.by_id(user.id) == user assert User.by_id(33) is None assert User.by_login(u'meh') == user assert User.by_login(u'foobar') is None assert user.has_password('foobar') assert not user.has_password('abracadabra') assert user.get_token() assert user.get_uhmac()
def test_disable_update_on_authenticate(): db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db, hash='pbkdf2_sha512', update_hash=False) User = auth.User db.create_all() credentials = {'login': u'meh', 'password': '******'} user = User(**credentials) db.session.add(user) db.session.commit() deprecated_hash = ph.hex_sha1.encrypt(credentials['password']) assert user.password != deprecated_hash user.set_raw_password(deprecated_hash) db.session.commit() assert user.password == deprecated_hash auth_user = auth.authenticate(credentials) assert auth_user.password == deprecated_hash
def test_get_token(): from time import time, sleep db = SQLAlchemy('sqlite:///:memory:') auth = authcode.Auth(SECRET_KEY, db=db) User = auth.User db.create_all() user = User(login=u'meh', password='******') db.session.add(user) db.session.commit() token1 = user.get_token() sleep(1) token2 = user.get_token() assert token1 != token2 timestamp = time() token1 = user.get_token(timestamp) token2 = user.get_token(timestamp) assert token1 == token2
def test_reconfigure(tmpdir): db = SQLAlchemy(URI1, echo=False) class CustomQuery(BaseQuery): some_attr = 1 class Model(db.Model): id = db.Column(db.Integer, primary_key=True) db.create_all() db.add(Model()) db.commit() tmp_db_file = tmpdir.mkdir('test_reconfigure').join('db.sqlite') uri = 'sqlite:///%s' % tmp_db_file.strpath.replace('\\', '/') db.reconfigure(uri=uri, echo=True, query_cls=CustomQuery) assert not Model.__table__.exists(db.engine) assert (uri, True) == db.connector._connected_for assert isinstance(db.query(Model), CustomQuery) assert db.query(Model).some_attr == 1
def create_test_model(): db = SQLAlchemy('sqlite://') class Item(db.Model): id = db.Column(db.Integer, primary_key=True) class Part(db.Model): id = db.Column(db.Integer, primary_key=True) item_id = db.Column(db.Integer, db.ForeignKey(Item.id)) item = db.relationship('Item', backref='parts') db.create_all() for i in range(1, 26): item = Item() db.add(item) db.commit() item = db.query(Item).first() for j in range(1, 26): db.add(Part(item=item)) db.commit() return db, Item, Part
__tablename__ = 'parent' id = db.Column(Integer, primary_key=True) name = db.Column(String(20)) class Child(db.Model): __tablename__ = "child" id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('parent.id')) child_attr = db.Column(String(20)) parent = relationship('Parent') db.create_all() p1 = Parent(name="Akshay") db.add(p1) c1 = Child(child_attr="Child1") c1.parent_id = p1.id db.add(c1) p2 = Parent(name="Piyush") db.add(p2) c2 = Child(child_attr="Child2") c2.parent_id = p2.id db.add(c2)