Skip to content

Commit

Permalink
gonna new version
Browse files Browse the repository at this point in the history
  • Loading branch information
marazmiki committed Jan 21, 2015
2 parents 627d404 + 806494e commit 0fe3eeb
Show file tree
Hide file tree
Showing 25 changed files with 645 additions and 351 deletions.
File renamed without changes.
18 changes: 9 additions & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,32 @@ python:


env:
- DJANGO=django==1.4.15
- DJANGO=django==1.5.10
- DJANGO=django==1.6.7
- DJANGO=django==1.7
- DJANGO=django==1.4.18
- DJANGO=django==1.5.12
- DJANGO=django==1.6.10
- DJANGO=django==1.7.3


matrix:
exclude:
- python: "2.6"
env: DJANGO=django==1.7
env: DJANGO=django==1.7.3
- python: "3.3"
env: DJANGO=django==1.4.15
env: DJANGO=django==1.4.18
- python: "3.4"
env: DJANGO=django==1.4.15
env: DJANGO=django==1.4.18


install:
- pip install -q $DJANGO
- pip install -q flake8
- pip install -q flake8 coverage coveralls
- python setup.py install

before_script:
- make flake8

script:
- make test
- make coverage

after_success:
- make coveralls
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Changes
=======

0.1
---

* Permissions for disguise now linked with User model;
* Using django system check framework in newest versions;
* Disguise widget become a template tag; earlier it added into page with middleware;
* Migrated to CBV views;
* Code imporvements (pep8);
* Added coverage support;
* Added signals;
* Removed the ``update_user_login`` feature prior to custom signal handling;


0.0.3
-----

* Travis CI integration
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
test:
python setup.py test


release:
python setup.py sdist --format=zip,bztar,gztar register upload
python setup.py bdist_wheel register upload


flake8:
flake8 --ignore=E501 disguise
flake8 --ignore=E501 tests.py
flake8 --ignore=E501 setup.py
flake8 \
disguise \
tests.py \
setup.py


coverage:
coverage run --include=disguise/*.py setup.py test
coverage run --rcfile=.coveragerc --include=disguise/*.py setup.py test
coverage html


coveralls:
coveralls --config_file=coverage.rc
coveralls

clean:
rm -rf *.egg *.egg-info
Expand Down
6 changes: 6 additions & 0 deletions disguise/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# coding: utf-8

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
25 changes: 25 additions & 0 deletions disguise/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# coding: utf-8

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division


try:
from django.contrib.auth import get_user_model
except ImportError:
from django.contrib.auth.models import User
get_user_model = lambda: User

try:
from django.core import checks
assert hasattr(checks, 'Error')
except (ImportError, AssertionError):
from django.core.exceptions import ImproperlyConfigured

class Checks(object):
class Error(object):
def __init__(self, message, hint='', error='', id=''):
raise ImproperlyConfigured(message, id)
checks = Checks()
14 changes: 14 additions & 0 deletions disguise/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# coding: utf-8

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from django.contrib.auth import SESSION_KEY, BACKEND_SESSION_KEY

KEYNAME = 'django_disguise:original_user'
TAGNAME = 'body'
BACKEND = 'django.contrib.auth.backends.ModelBackend'

__all__ = ['KEYNAME', 'TAGNAME', 'SESSION_KEY', 'BACKEND_SESSION_KEY',
'BACKEND']
41 changes: 23 additions & 18 deletions disguise/forms.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,37 @@
# coding: utf-8

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from django import forms
from django.utils.translation import ugettext_lazy as _
from disguise.compat import get_user_model


try:
from django.contrib.auth import get_user_model
User = get_user_model()
except ImportError:
from django.contrib.auth.models import User
User = get_user_model()


class DisguiseForm(forms.Form):
"""
Disguise form
"""
username = forms.CharField(label=_('User name'),
required=False)
user_id = forms.IntegerField(label=_('User ID'),
required=False)
update_last_login = forms.BooleanField(label=_('Update last login'),
required=False)
username = forms.CharField(label=_('User name'), required=False)
user_id = forms.IntegerField(label=_('User ID'), required=False)

def clean_username(self):
"""
Cleans username field
"""
username = self.cleaned_data.get('username')

if not username:
return None

qset = User.objects.filter(username=username)

if len(qset) == 1:
return qset[0]
if qset.exists():
return qset.get()
raise forms.ValidationError(_('No such username'))

def clean_user_id(self):
Expand All @@ -43,16 +44,21 @@ def clean_user_id(self):
return None
qset = User.objects.filter(pk=user_id)

if len(qset) == 1:
return qset[0]
if qset.exists():
return qset.get()
raise forms.ValidationError(_('No such user id'))

def clean(self):
"""
Clears whole form totally
"""
if not getattr(self, 'cleaned_data'):
raise forms.ValidationError(_('No such username or user id'))
cleaned_data = getattr(self, 'cleaned_data', {})

if not cleaned_data.get('user_id') and \
not cleaned_data.get('username'):
raise forms.ValidationError(
_('Please enter either username or user id')
)
return self.cleaned_data

def get_user(self):
Expand All @@ -67,4 +73,3 @@ def get_user(self):
if not isinstance(user, User):
continue
return user
raise ValueError('Cannot retrieve user')
98 changes: 9 additions & 89 deletions disguise/middleware.py
Original file line number Diff line number Diff line change
@@ -1,110 +1,30 @@
# coding: utf-8

from django.template import RequestContext
from django.template.loader import render_to_string
from disguise.forms import DisguiseForm
import warnings


try:
from django.utils.encoding import smart_unicode as smart_text
except ImportError:
from django.utils.encoding import smart_text


try:
from django.contrib.auth import get_user_model
except ImportError:
from django.contrib.auth.models import User
get_user_model = lambda: User


KEYNAME = 'django_disguise:original_user'
TAGNAME = '</body>'


def replace_insensitive(string, target, replacement):
"""
Similar to string.replace() but is case insensitive
Code borrowed from: http://forums.devshed.com/python-programming-11/case-insensitive-string-replace-490921.html
"""
no_case = string.lower()
index = no_case.rfind(target.lower())
if index >= 0:
return string[:index] + replacement + string[index + len(target):]
else: # no results so return the original string
return string
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from disguise.compat import get_user_model
from disguise.utils import can_disguise
from disguise.const import KEYNAME


class DisguiseMiddleware(object):
"""
Disguise user middleware
"""

def test_disguise(self, request):
if KEYNAME in request.session:
return True

if hasattr(request, 'original_user'):
return True

if request.user.has_perm('disguire.can_disguise'):
return True

return False

def get_original_user(self, request):
if KEYNAME in request.session:
return get_user_model().objects.get(pk=request.session[KEYNAME])
return request.user

def process_request(self, request):
"""
Runs during each request
Injects the `original_user` attribute into HttpRequest object
"""
if not hasattr(request, 'user'):
warnings.warn("DisguiseMiddleware must be installed after "
"django.contrib.auth.middleware.AuthenticationMiddleware")
return

if not hasattr(request, 'session'):
warnings.warn("DisguiseMiddleware must be installed after "
"django.contrib.sessions.middleware.SessionMiddleware")
return

if not request.user.is_authenticated():
return

if not self.test_disguise(request):
if not can_disguise(request):
return

request.original_user = self.get_original_user(request)

def process_response(self, request, response):
"""
Runs during responding
"""
if not request.user.is_authenticated():
return response

if not response.status_code == 200:
return response

if not response.get('content-type', '').startswith('text/html'):
return response

if self.test_disguise(request):
# Render HTML code that helps to select disguise
html = render_to_string('disguise/form.html', {
'form': DisguiseForm(),
'original_user': getattr(request, 'original_user', None),
'disguise_user': getattr(request, 'user'),
}, RequestContext(request))

# Insert this code before </body>
response.content = replace_insensitive(
smart_text(response.content), # Subject
TAGNAME, # Search
smart_text(html + TAGNAME) # Replace
)
return response
31 changes: 18 additions & 13 deletions disguise/models.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
# coding: utf-8

from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from __future__ import division
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models.signals import post_save, post_syncdb
from django.utils.translation import ugettext_lazy as _
from disguise.compat import get_user_model


def create_perms(sender, **kwargs):
perms = (
('can_disguise', 'Can disguise'),
('can_disguise', _('Can disguise')),
)

# create a content type for the app if it doesn't already exist
content_type, created = ContentType.objects.get_or_create(
model='',
app_label='disguise',
defaults={'name': 'disguise'})
content_type = ContentType.objects.get_for_model(get_user_model())

for codename, title in perms:
# create a permission if it doesn't already exist
Permission.objects.get_or_create(codename=codename,
content_type__pk=content_type.id,
defaults={
'name': title,
'content_type': content_type
})
Permission.objects.get_or_create(
codename=codename,
content_type=content_type,
defaults={
'name': title,
})


post_save.connect(create_perms, Permission)
post_syncdb.connect(create_perms, sender=__import__('disguise'))

0 comments on commit 0fe3eeb

Please sign in to comment.