Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dictionary backend #120

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cork/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
#
# Backends API - used to make backends available for importing
#
from .cork import Cork, JsonBackend, AAAException, UserExists, AuthException, Mailer, FlaskCork, Redirect
from .cork import Cork, DictionaryBackend, JsonBackend, AAAException, UserExists, AuthException, Mailer, FlaskCork, Redirect
1 change: 1 addition & 0 deletions cork/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
:synopsis: Backends API - used to make backends available for importing
"""

from .dictionary_backend import DictionaryBackend
from .json_backend import JsonBackend
from .mongodb_backend import MongoDBBackend
from .sqlalchemy_backend import SqlAlchemyBackend
Expand Down
2 changes: 1 addition & 1 deletion cork/cork.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
except NameError:
basestring = str

from .backends import JsonBackend
from .backends import JsonBackend, DictionaryBackend

is_py3 = (sys.version_info.major == 3)

Expand Down
88 changes: 88 additions & 0 deletions cork/dictionary_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""
.. module:: dict_backend
:synopsis: Dictionary based storage backend.
"""

from logging import getLogger
import sys
from datetime import datetime as dt

from .base_backend import BackendIOException

is_py3 = (sys.version_info.major == 3)

log = getLogger(__name__)

try:
dict.iteritems
py23dict = dict
except AttributeError:
class py23dict(dict):
iteritems = dict.items


class DictionaryBackend(object):
"""Dictionary based storage backend."""

def __init__(self, users=None, roles=None,
pending_registrations=None):
"""Dictionary storage class.

:param users: A dictionary of dictionary containing users and roles, e.g.
{
'mel': {
'hash': cork._hash('mel', 'sugartits'),
'email_addr': '[email protected]',
'role': 'admin',
'creation_data': '2012-10-28 20:50:26.286723',
'desc': 'Cheers!'}
},
# ...
}
:type users: dict
:param roles: A table of roles, e.g. {'admin': 100, 'user': 50}
:type roles: dict
:param pending_registrations: A table of pending registrations.
:type pending_registrations: dict
"""
self.users = py23dict(users) if users is not None else py23dict()
self.roles = py23dict(roles) if roles is not None else py23dict()
self.pending_registrations = py23dict(pending_registrations) \
if pending_registrations is not None else py23dict()

def add_user(self, username, role, hash,
email=None, description=None, creation_date=None, last_login=None):
"""Adds a new user."""
if username in self.users:
raise BackendIOException('The user {} already exists!'.format(username))
if role not in self.roles:
raise BackendIOException('The role {} does not exist!'.format(role))

if creation_date is None:
creation_date = dt.strftime(dt.now(), '%Y-%m-%d %H:%M:%S.%f')
self.users[username] = {
'hash': hash,
'email_addr': email,
'role': role,
'creation_date': creation_date,
'last_login': last_login,
'desc': description
}

def add_role(self, name, priority):
"""Add a new role."""
if name in self.roles:
raise BackendIOException('The role {} already exists!'.format(name))
self.roles[name] = priority

def save_users(self):
"""Does nothing."""
pass

def save_roles(self):
"""Does nothing."""
pass

def save_pending_registrations(self):
"""Does nothing."""
pass
50 changes: 49 additions & 1 deletion tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import time

from cork import Cork, AAAException, AuthException
from cork.backends import DictionaryBackend
from cork.backends import JsonBackend
from cork.backends import MongoDBBackend
from cork.backends import SQLiteBackend
Expand Down Expand Up @@ -83,6 +84,44 @@ def _beaker_session(self):

## Backends

def setup_dictionary_db(request, use_add_interface=True):
if use_add_interface:
b = DictionaryBackend()

# Add roles.
b.add_role('special', 200)
b.add_role('admin', 100)
b.add_role('user', 50)
b.add_role('editor', 60)

# Add users.
b.add_user('admin', 'admin',
hash='69f75f38ac3bfd6ac813794f3d8c47acc867adb10b806e8979316ddbf6113999b6052efe4ba95c0fa9f6a568bddf60e8e5572d9254dbf3d533085e9153265623',
email='[email protected]',
creation_date='2012-04-09 14:22:27.075596',
last_login='2012-10-28 20:50:26.286723')
else:
users = {
"admin": {
"email_addr": "[email protected]",
"desc": None,
"role": "admin",
"hash": "69f75f38ac3bfd6ac813794f3d8c47acc867adb10b806e8979316ddbf6113999b6052efe4ba95c0fa9f6a568bddf60e8e5572d9254dbf3d533085e9153265623",
"creation_date": "2012-04-09 14:22:27.075596",
"last_login": "2012-10-28 20:50:26.286723"
}
}
roles = {
"special": 200,
"admin": 100,
"user": 50,
"editor": 60
}

b = DictionaryBackend(users=users, roles=roles)

return b

def setup_sqlite_db(request):
# in-memory SQLite DB using the SQLiteBackend backend module.
b = SQLiteBackend(':memory:', initialize=True)
Expand Down Expand Up @@ -295,16 +334,25 @@ def fin():
## General fixtures

@pytest.fixture(params=[
'dictionary_init',
'dictionary_add_interface',
'json',
'mongodb',
'mysql',
'postgresql',
'sqlalchemy',
'sqlite',
'sqlite'
])
def backend(tmpdir, request):
# Create backend instances
backend_type = request.param

if backend_type == 'dictionary_init':
return setup_dictionary_db(request, use_add_interface=False)

if backend_type == 'dictionary_add_interface':
return setup_dictionary_db(request, use_add_interface=True)

if backend_type == 'json':
return setup_json_db(request, tmpdir)

Expand Down