Implemented IP authentication
libraries get associated with a library_block table (IP ranges) moved superlogin here IP stuff mostly copied from https://github.com/benliles/django-ipauth/blob/master/ipauth/models.py The model is that you need to be in an allowed IP range to "join" a library. Once you've joined, you can use your login from anywhere. to use that library. Asign IP ranges in adminpull/1/head
parent
2f703a7815
commit
439169a1ab
5
admin.py
5
admin.py
|
@ -41,8 +41,8 @@ from regluit.core.lookups import (
|
|||
OwnerLookup,
|
||||
EditionLookup
|
||||
)
|
||||
from regluit.libraryauth.models import Library
|
||||
from regluit.libraryauth.admin import LibraryAdmin
|
||||
from regluit.libraryauth.models import Library, Block
|
||||
from regluit.libraryauth.admin import LibraryAdmin, BlockAdmin
|
||||
|
||||
class RegluitAdmin(AdminSite):
|
||||
login_template = 'registration/login.html'
|
||||
|
@ -214,6 +214,7 @@ admin_site = RegluitAdmin("Admin")
|
|||
|
||||
admin_site.register(User, UserAdmin)
|
||||
admin_site.register(Library, LibraryAdmin)
|
||||
admin_site.register(Block, BlockAdmin)
|
||||
admin_site.register(models.Work, WorkAdmin)
|
||||
admin_site.register(models.Claim, ClaimAdmin)
|
||||
admin_site.register(models.RightsHolder, RightsHolderAdmin)
|
||||
|
|
|
@ -13,7 +13,6 @@ from django import forms
|
|||
from django.conf import settings
|
||||
from django.conf.global_settings import LANGUAGES
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.forms import AuthenticationForm
|
||||
from django.core.validators import validate_email
|
||||
from django.db import models
|
||||
from django.forms.widgets import RadioSelect
|
||||
|
@ -622,14 +621,6 @@ class FeedbackForm(forms.Form):
|
|||
|
||||
return cleaned_data
|
||||
|
||||
class AuthForm(AuthenticationForm):
|
||||
def __init__(self, request=None, *args, **kwargs):
|
||||
if request and request.method == 'GET':
|
||||
saved_un= request.COOKIES.get('un', None)
|
||||
super(AuthForm, self).__init__(initial={"username":saved_un},*args, **kwargs)
|
||||
else:
|
||||
super(AuthForm, self).__init__(*args, **kwargs)
|
||||
|
||||
class MsgForm(forms.Form):
|
||||
msg = forms.CharField(widget=forms.Textarea(), error_messages={'required': 'Please specify a message.'})
|
||||
|
||||
|
|
|
@ -84,9 +84,9 @@ function highlightTarget(targetdiv) {
|
|||
{% with supporter.profile.tagline as tagline %}{% if tagline %}{{ tagline }}{% else %} {% endif %}{% endwith %}
|
||||
</span>
|
||||
{% if supporter.library.group in request.user.groups.all %}
|
||||
<i>This is MY Library!</i>
|
||||
<i>This is {{ request.user }}'s Library!</i>
|
||||
{% else %}
|
||||
<a href="{% url join_library supporter.username %}" class="fakeinput">Make this my Library</a>
|
||||
{% include supporter.library.join_template %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ function highlightTarget(targetdiv) {
|
|||
{% block topsection %}
|
||||
<div id="locationhash">{{ activetab }}</div>
|
||||
{% if supporter.library %}
|
||||
<div class="launch_top pale">{{ supporter.username }} is a Library participating in Unglue.it. <a href="{% url library supporter.username %}">Click here</a> to use {{ supporter.username }}'s books.
|
||||
<div class="launch_top pale">{{ supporter.username }} is a Library participating in Unglue.it. <a href="{% url join_library supporter.username %}">Click here</a> to use {{ supporter.username }}'s books.
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
|
|
@ -49,9 +49,7 @@ urlpatterns = patterns(
|
|||
url(r"^supporter/(?P<supporter_username>[^/]+)/$", "supporter", {'template_name': 'supporter.html'}, name="supporter"),
|
||||
url(r"^supporter/(?P<userlist>[^/]+)/marc/$", "marc", name="user_marc"),
|
||||
url(r"^library/(?P<supporter_username>[^/]+)/$", "supporter", {'template_name': 'library.html'}, name="library"),
|
||||
url(r"^library/(?P<library>[^/]+)/join/$", "join_library", name="join_library"),
|
||||
url(r"^accounts/manage/$", login_required(ManageAccount.as_view()), name="manage_account"),
|
||||
url(r'^accounts/superlogin/$', 'superlogin', name='superlogin'),
|
||||
url(r"^search/$", "search", name="search"),
|
||||
url(r"^privacy/$", TemplateView.as_view(template_name="privacy.html"),
|
||||
name="privacy"),
|
||||
|
|
|
@ -107,7 +107,6 @@ from regluit.frontend.forms import (
|
|||
WorkForm,
|
||||
OtherWorkForm,
|
||||
MsgForm,
|
||||
AuthForm,
|
||||
PressForm,
|
||||
KindleEmailForm,
|
||||
MARCUngluifyForm,
|
||||
|
@ -136,6 +135,7 @@ from regluit.payment.parameters import (
|
|||
|
||||
from regluit.utils.localdatetime import now, date_today
|
||||
from regluit.booxtream.exceptions import BooXtreamError
|
||||
from regluit.libraryauth.views import Authenticator
|
||||
from regluit.libraryauth.models import Library
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -297,18 +297,6 @@ def stub(request):
|
|||
def acks(request, work):
|
||||
return render(request,'front_matter.html', {'campaign': work.last_campaign()})
|
||||
|
||||
def superlogin(request, **kwargs):
|
||||
extra_context = None
|
||||
if request.method == 'POST' and request.user.is_anonymous():
|
||||
username=request.POST.get("username", "")
|
||||
try:
|
||||
user=models.User.objects.get(username=username)
|
||||
extra_context={"socials":user.profile.social_auths}
|
||||
except:
|
||||
pass
|
||||
if request.GET.has_key("add"):
|
||||
request.session["add_wishlist"]=request.GET["add"]
|
||||
return login(request, extra_context=extra_context, authentication_form=AuthForm, **kwargs)
|
||||
|
||||
@login_required
|
||||
def social_auth_reset_password(request):
|
||||
|
@ -317,15 +305,6 @@ def social_auth_reset_password(request):
|
|||
request.user.save()
|
||||
return password_reset(request)
|
||||
|
||||
def join_library(request, library):
|
||||
library=get_object_or_404(Library, user__username=library)
|
||||
if library.authenticate(request.user):
|
||||
request.user.groups.add(library.group)
|
||||
return HttpResponseRedirect(reverse('library',args=[str(library)]))
|
||||
else:
|
||||
return library.authenticator(request)
|
||||
return render(request, 'join_library.html', {'library': library})
|
||||
|
||||
def work(request, work_id, action='display'):
|
||||
work = safe_get_work(work_id)
|
||||
if action == "acks":
|
||||
|
@ -1871,6 +1850,10 @@ def supporter(request, supporter_username, template_name):
|
|||
librarything_id = None
|
||||
|
||||
process_kindle_email(request)
|
||||
try:
|
||||
authenticator = Authenticator(request,supporter.library)
|
||||
except Library.DoesNotExist:
|
||||
authenticator=None
|
||||
|
||||
context = {
|
||||
"supporter": supporter,
|
||||
|
@ -1888,7 +1871,8 @@ def supporter(request, supporter_username, template_name):
|
|||
"goodreads_auth_url": reverse('goodreads_auth'),
|
||||
"goodreads_id": goodreads_id,
|
||||
"librarything_id": librarything_id,
|
||||
"activetab": activetab
|
||||
"activetab": activetab,
|
||||
"authenticator": authenticator
|
||||
}
|
||||
|
||||
return render(request, template_name, context)
|
||||
|
|
|
@ -1,5 +1,37 @@
|
|||
'''import logging
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponseRedirect
|
||||
from .views import superlogin
|
||||
|
||||
from . import backends
|
||||
|
||||
def authenticate(user,library):
|
||||
backend= getattr(backends, library.backend + '_authenticate')
|
||||
return backend(user, library)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Authenticator:
|
||||
request=None
|
||||
library=None
|
||||
|
||||
def __init__(self, request, library):
|
||||
self.request=request
|
||||
self.library=library
|
||||
|
||||
def process(self, success_url, deny_url):
|
||||
logger.info('authenticator for %s at %s.'%(self.request.user, self.library))
|
||||
if self.library.has_user(self.request.user):
|
||||
return HttpResponseRedirect(success_url)
|
||||
backend_test= getattr(backends, self.library.backend + '_authenticate')
|
||||
if backend_test(self.request, self.library):
|
||||
if self.request.user.is_authenticated():
|
||||
self.library.add_user(self.request.user)
|
||||
return HttpResponseRedirect(success_url)
|
||||
else:
|
||||
return superlogin(self.request, extra_context={'library':self.library}, template_name='libraryauth/library_login.html')
|
||||
|
||||
else:
|
||||
backend_authenticator= getattr(backends, self.library.backend + '_authenticator')
|
||||
return backend_authenticator(self.request, self.library, success_url, deny_url)
|
||||
|
||||
def allowed(self):
|
||||
backend_test= getattr(backends, self.library.backend + '_authenticate')
|
||||
return backend_test(self.request, self.library)
|
||||
'''
|
|
@ -28,4 +28,7 @@ class LibraryAdmin(ModelAdmin):
|
|||
form = LibraryAdminForm
|
||||
search_fields = ['user__username']
|
||||
|
||||
class BlockAdmin(ModelAdmin):
|
||||
list_display = ('library', 'lower', 'upper',)
|
||||
search_fields = ('library__user__username', 'lower', 'upper',)
|
||||
|
||||
|
|
|
@ -1,6 +1,32 @@
|
|||
import logging
|
||||
from django.db.models import Q
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render
|
||||
|
||||
def IP_authenticate(user, library):
|
||||
from .models import Block, IP
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def ip_authenticate(request, library):
|
||||
try:
|
||||
ip = IP(request.META['REMOTE_ADDR'])
|
||||
print str(ip)
|
||||
blocks = Block.objects.filter(Q(lower=ip) | Q(lower__lte=ip, upper__gte=ip))
|
||||
for block in blocks:
|
||||
if block.library==library:
|
||||
logger.info('%s authenticated for %s from %s'%(request.user, library, ip))
|
||||
return True
|
||||
return False
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
def ip_authenticator(request, library, success_url, deny_url):
|
||||
return HttpResponseRedirect(deny_url)
|
||||
|
||||
def cardnum_authenticate(request, library):
|
||||
# test params
|
||||
return True
|
||||
|
||||
def cardnum_authenticate(user, library):
|
||||
return True
|
||||
def cardnum_authenticator(request, library, success_url, deny_url):
|
||||
#send a form
|
||||
return render(request, 'cardnum.html', context)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
from django.contrib.auth.forms import AuthenticationForm
|
||||
|
||||
class AuthForm(AuthenticationForm):
|
||||
def __init__(self, request=None, *args, **kwargs):
|
||||
if request and request.method == 'GET':
|
||||
saved_un= request.COOKIES.get('un', None)
|
||||
super(AuthForm, self).__init__(initial={"username":saved_un},*args, **kwargs)
|
||||
else:
|
||||
super(AuthForm, self).__init__(*args, **kwargs)
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core import validators
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.forms import IPAddressField as BaseIPAddressField
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
|
||||
def ip_to_long(value):
|
||||
validators.validate_ipv4_address(value)
|
||||
|
||||
lower_validator = validators.MinValueValidator(0)
|
||||
upper_validator = validators.MinValueValidator(255)
|
||||
|
||||
value = value.split('.')
|
||||
output = 0
|
||||
|
||||
for i in range(0, 4):
|
||||
validators.validate_integer(value[i])
|
||||
lower_validator(value[i])
|
||||
upper_validator(value[i])
|
||||
output += int(value[i]) * (256**(3-i))
|
||||
|
||||
return output
|
||||
|
||||
def long_to_ip(value):
|
||||
validators.validate_integer(value)
|
||||
value = int(value)
|
||||
|
||||
validators.MinValueValidator(0)(value)
|
||||
validators.MaxValueValidator(4294967295)(value)
|
||||
|
||||
return '%d.%d.%d.%d' % (value >> 24, value >> 16 & 255,
|
||||
value >> 8 & 255, value & 255)
|
||||
|
||||
class IP(object):
|
||||
def __init__(self, value):
|
||||
self.int = value
|
||||
|
||||
def _set_int(self, value):
|
||||
if isinstance(value, IP):
|
||||
self._int = IP.int
|
||||
|
||||
try:
|
||||
self._int = int(value)
|
||||
except ValueError:
|
||||
self._int = ip_to_long(value)
|
||||
except (TypeError, ValidationError):
|
||||
self._int = None
|
||||
|
||||
def _get_int(self):
|
||||
return self._int
|
||||
|
||||
int = property(_get_int, _set_int)
|
||||
|
||||
def _get_str(self):
|
||||
if self.int:
|
||||
return long_to_ip(self.int)
|
||||
return ''
|
||||
|
||||
string = property(_get_str, _set_int)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, IP):
|
||||
try:
|
||||
other = IP(other)
|
||||
except:
|
||||
return False
|
||||
|
||||
return self.int == other.int
|
||||
|
||||
def __cmp__(self, other):
|
||||
if not isinstance(other, IP):
|
||||
other = IP(other)
|
||||
|
||||
if self.int and other.int:
|
||||
return self.int.__cmp__(other.int)
|
||||
|
||||
raise ValueError('Invalid arguments')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.string
|
||||
|
||||
def __str__(self):
|
||||
return self.string
|
||||
|
||||
class IPAddressFormField(BaseIPAddressField):
|
||||
default_validators = []
|
||||
|
||||
def prepare_value(self, value):
|
||||
if isinstance(value, IP):
|
||||
return value.string
|
||||
|
||||
try:
|
||||
return IP(value).string
|
||||
except:
|
||||
pass
|
||||
|
||||
return value
|
||||
|
||||
def to_python(self, value):
|
||||
if value in validators.EMPTY_VALUES:
|
||||
return None
|
||||
|
||||
try:
|
||||
return IP(value)
|
||||
except ValidationError:
|
||||
raise ValidationError(self.default_error_messages['invalid'],
|
||||
code='invalid')
|
||||
|
||||
class IPAddressModelField(models.IPAddressField):
|
||||
__metaclass__ = models.SubfieldBase
|
||||
empty_strings_allowed = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
models.Field.__init__(self, *args, **kwargs)
|
||||
|
||||
def get_internal_type(self):
|
||||
return "PositiveIntegerField"
|
||||
|
||||
def get_prep_value(self, value):
|
||||
if not value:
|
||||
return value
|
||||
|
||||
if isinstance(value, IP):
|
||||
return value.int
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, IP):
|
||||
return value
|
||||
try:
|
||||
return IP(value)
|
||||
except ValidationError:
|
||||
return None
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'form_class': IPAddressFormField}
|
||||
defaults.update(kwargs)
|
||||
return super(models.IPAddressField, self).formfield(**defaults)
|
||||
|
||||
|
||||
class Range(models.Model):
|
||||
user = models.ForeignKey(User, related_name='+')
|
||||
lower = IPAddressModelField(db_index=True, unique=True)
|
||||
upper = IPAddressModelField(db_index=True, blank=True, null=True)
|
||||
|
||||
def clean(self):
|
||||
if self.upper and self.upper.int:
|
||||
try:
|
||||
if self.lower >= self.upper:
|
||||
raise ValidationError('Lower end of the range must be less '
|
||||
'than the upper end')
|
||||
except ValueError, e:
|
||||
pass
|
||||
|
||||
others = Range.objects.exclude(pk=self.pk)
|
||||
query = Q(lower__lte=self.lower, upper__gte=self.lower) | \
|
||||
Q(lower=self.lower)
|
||||
if self.upper and self.upper.int:
|
||||
textual = u'%s-%s' % (self.lower, self.upper)
|
||||
query = query | Q(lower__range=(self.lower, self.upper)) | \
|
||||
Q(lower__lte=self.upper, upper__gte=self.upper)
|
||||
else:
|
||||
textual = str(self.lower)
|
||||
|
||||
query = others.filter(query)
|
||||
|
||||
if query.exists():
|
||||
values = query.distinct().values_list('user__username', flat=True)
|
||||
raise ValidationError('%s overlaps a range in in use by: %s' % (textual,
|
||||
', '.join(list(frozenset(values))[:5])))
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
if self.upper and self.upper.int:
|
||||
return u'%s %s-%s' % (self.user.get_full_name(), self.lower,
|
||||
self.upper)
|
||||
return u'%s %s' % (self.user.get_full_name(), self.lower)
|
||||
|
||||
class Meta:
|
||||
ordering = ['lower',]
|
|
@ -12,15 +12,27 @@ class Migration(SchemaMigration):
|
|||
db.create_table('libraryauth_library', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('user', self.gf('django.db.models.fields.related.OneToOneField')(related_name='library', unique=True, to=orm['auth.User'])),
|
||||
('backend', self.gf('django.db.models.fields.CharField')(default='IP', max_length=10)),
|
||||
('backend', self.gf('django.db.models.fields.CharField')(default='ip', max_length=10)),
|
||||
))
|
||||
db.send_create_signal('libraryauth', ['Library'])
|
||||
|
||||
# Adding model 'Block'
|
||||
db.create_table('libraryauth_block', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('library', self.gf('django.db.models.fields.related.ForeignKey')(related_name='block', to=orm['libraryauth.Library'])),
|
||||
('lower', self.gf('regluit.libraryauth.models.IPAddressModelField')(unique=True, db_index=True)),
|
||||
('upper', self.gf('regluit.libraryauth.models.IPAddressModelField')(db_index=True, null=True, blank=True)),
|
||||
))
|
||||
db.send_create_signal('libraryauth', ['Block'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'Library'
|
||||
db.delete_table('libraryauth_library')
|
||||
|
||||
# Deleting model 'Block'
|
||||
db.delete_table('libraryauth_block')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
|
@ -59,9 +71,16 @@ class Migration(SchemaMigration):
|
|||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'libraryauth.block': {
|
||||
'Meta': {'ordering': "['lower']", 'object_name': 'Block'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'library': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'block'", 'to': "orm['libraryauth.Library']"}),
|
||||
'lower': ('regluit.libraryauth.models.IPAddressModelField', [], {'unique': 'True', 'db_index': 'True'}),
|
||||
'upper': ('regluit.libraryauth.models.IPAddressModelField', [], {'db_index': 'True', 'null': 'True', 'blank': 'True'})
|
||||
},
|
||||
'libraryauth.library': {
|
||||
'Meta': {'object_name': 'Library'},
|
||||
'backend': ('django.db.models.fields.CharField', [], {'default': "'IP'", 'max_length': '10'}),
|
||||
'backend': ('django.db.models.fields.CharField', [], {'default': "'ip'", 'max_length': '10'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'library'", 'unique': 'True', 'to': "orm['auth.User']"})
|
||||
}
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
from . import authenticate
|
||||
# IP address part of this of this copied from https://github.com/benliles/django-ipauth/blob/master/ipauth/models.py
|
||||
|
||||
from django.contrib.auth.models import User, Group
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core import validators
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.forms import IPAddressField as BaseIPAddressField
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class Library(models.Model):
|
||||
'''
|
||||
name and other things derive from the User
|
||||
'''
|
||||
user = models.OneToOneField(User, related_name='library')
|
||||
backend = models.CharField(max_length=10, default='IP')
|
||||
|
||||
def authenticate(self, enduser):
|
||||
for group in enduser.groups.all():
|
||||
if enduser.username == group.name:
|
||||
return true
|
||||
return authenticate(enduser, self)
|
||||
backend = models.CharField(max_length=10, default='ip')
|
||||
|
||||
@property
|
||||
def group(self):
|
||||
|
@ -24,4 +23,191 @@ class Library(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.user.username
|
||||
|
||||
def add_user(self, user):
|
||||
user.groups.add(self.group)
|
||||
|
||||
def has_user(self, user):
|
||||
return self.group in user.groups.all()
|
||||
|
||||
@property
|
||||
def join_template(self):
|
||||
return 'libraryauth/' + self.backend + '_join.html'
|
||||
|
||||
|
||||
def ip_to_long(value):
|
||||
validators.validate_ipv4_address(value)
|
||||
|
||||
lower_validator = validators.MinValueValidator(0)
|
||||
upper_validator = validators.MinValueValidator(255)
|
||||
|
||||
value = value.split('.')
|
||||
output = 0
|
||||
|
||||
for i in range(0, 4):
|
||||
validators.validate_integer(value[i])
|
||||
lower_validator(value[i])
|
||||
upper_validator(value[i])
|
||||
output += int(value[i]) * (256**(3-i))
|
||||
|
||||
return output
|
||||
|
||||
def long_to_ip(value):
|
||||
validators.validate_integer(value)
|
||||
value = int(value)
|
||||
|
||||
validators.MinValueValidator(0)(value)
|
||||
validators.MaxValueValidator(4294967295)(value)
|
||||
|
||||
return '%d.%d.%d.%d' % (value >> 24, value >> 16 & 255,
|
||||
value >> 8 & 255, value & 255)
|
||||
|
||||
class IP(object):
|
||||
def __init__(self, value):
|
||||
self.int = value
|
||||
|
||||
def _set_int(self, value):
|
||||
if isinstance(value, IP):
|
||||
self._int = IP.int
|
||||
|
||||
try:
|
||||
self._int = int(value)
|
||||
except ValueError:
|
||||
self._int = ip_to_long(value)
|
||||
except (TypeError, ValidationError):
|
||||
self._int = None
|
||||
|
||||
def _get_int(self):
|
||||
return self._int
|
||||
|
||||
int = property(_get_int, _set_int)
|
||||
|
||||
def _get_str(self):
|
||||
if self.int!=None:
|
||||
return long_to_ip(self.int)
|
||||
return ''
|
||||
|
||||
string = property(_get_str, _set_int)
|
||||
|
||||
def __eq__(self, other):
|
||||
if not isinstance(other, IP):
|
||||
try:
|
||||
other = IP(other)
|
||||
except:
|
||||
return False
|
||||
|
||||
return self.int == other.int
|
||||
|
||||
def __cmp__(self, other):
|
||||
if not isinstance(other, IP):
|
||||
other = IP(other)
|
||||
|
||||
if self.int and other.int:
|
||||
return self.int.__cmp__(other.int)
|
||||
|
||||
raise ValueError('Invalid arguments')
|
||||
|
||||
def __unicode__(self):
|
||||
return self.string
|
||||
|
||||
def __str__(self):
|
||||
return self.string
|
||||
|
||||
class IPAddressFormField(BaseIPAddressField):
|
||||
default_validators = []
|
||||
|
||||
def prepare_value(self, value):
|
||||
if isinstance(value, IP):
|
||||
return value.string
|
||||
|
||||
try:
|
||||
return IP(value).string
|
||||
except:
|
||||
pass
|
||||
|
||||
return value
|
||||
|
||||
def to_python(self, value):
|
||||
if value==0:
|
||||
return IP(0)
|
||||
if value in validators.EMPTY_VALUES:
|
||||
return None
|
||||
|
||||
try:
|
||||
return IP(value)
|
||||
except ValidationError:
|
||||
raise ValidationError(self.default_error_messages['invalid'],
|
||||
code='invalid')
|
||||
|
||||
class IPAddressModelField(models.IPAddressField):
|
||||
__metaclass__ = models.SubfieldBase
|
||||
empty_strings_allowed = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
models.Field.__init__(self, *args, **kwargs)
|
||||
|
||||
def get_internal_type(self):
|
||||
return "PositiveIntegerField"
|
||||
|
||||
def get_prep_value(self, value):
|
||||
if not value:
|
||||
return value
|
||||
|
||||
if isinstance(value, IP):
|
||||
return value.int
|
||||
|
||||
def to_python(self, value):
|
||||
if isinstance(value, IP):
|
||||
return value
|
||||
try:
|
||||
return IP(value)
|
||||
except ValidationError:
|
||||
return None
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
defaults = {'form_class': IPAddressFormField}
|
||||
defaults.update(kwargs)
|
||||
return super(models.IPAddressField, self).formfield(**defaults)
|
||||
|
||||
class Block(models.Model):
|
||||
library = models.ForeignKey(Library, related_name='block')
|
||||
lower = IPAddressModelField(db_index=True, unique=True)
|
||||
upper = IPAddressModelField(db_index=True, blank=True, null=True)
|
||||
|
||||
def clean(self):
|
||||
if self.upper and self.upper.int:
|
||||
try:
|
||||
if self.lower > self.upper:
|
||||
raise ValidationError('Lower end of the Block must be less '
|
||||
'than or equal to the upper end')
|
||||
except ValueError, e:
|
||||
pass
|
||||
|
||||
others = Block.objects.exclude(pk=self.pk)
|
||||
query = Q(lower__lte=self.lower, upper__gte=self.lower) | \
|
||||
Q(lower=self.lower)
|
||||
if self.upper and self.upper.int:
|
||||
textual = u'%s-%s' % (self.lower, self.upper)
|
||||
query = query | Q(lower__range=(self.lower, self.upper)) | \
|
||||
Q(lower__lte=self.upper, upper__gte=self.upper)
|
||||
else:
|
||||
textual = str(self.lower)
|
||||
|
||||
query = others.filter(query)
|
||||
|
||||
if query.exists():
|
||||
values = query.distinct().values_list('library__user__username', flat=True)
|
||||
raise ValidationError('%s overlaps a block in in use by: %s' % (textual,
|
||||
', '.join(list(frozenset(values))[:5])))
|
||||
|
||||
|
||||
def __unicode__(self):
|
||||
if self.upper and self.upper.int:
|
||||
return u'%s %s-%s' % (self.library, self.lower, self.upper)
|
||||
return u'%s %s' % (self.library, self.lower)
|
||||
|
||||
class Meta:
|
||||
ordering = ['lower',]
|
||||
|
||||
from south.modelsinspector import add_introspection_rules
|
||||
add_introspection_rules([], ["^regluit\.libraryauth\.models\.IPAddressModelField"])
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Denied authentication for {{ request.user }} at {{ request.META.REMOTE_ADDR }}
|
|
@ -0,0 +1,5 @@
|
|||
{% if authenticator.allowed %}
|
||||
<a href="{% url join_library authenticator.library %}?next={% url join_library authenticator.library %}" class="fakeinput">Make this my Library</a>
|
||||
{% else %}
|
||||
You can't join {{ authenticator.library }} at your current location.
|
||||
{% endif %}
|
|
@ -0,0 +1 @@
|
|||
{{params.library}}
|
|
@ -0,0 +1,2 @@
|
|||
{% extends "registration/from_pledge.html" %}
|
||||
{% block login_pitch %}<h3>Before you can join {{library}} on unglue.it, please login or make an unglue.it account. </h3>{% endblock %}
|
|
@ -0,0 +1,11 @@
|
|||
from django.conf.urls.defaults import *
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.views.generic.simple import direct_to_template
|
||||
from . import views
|
||||
|
||||
urlpatterns = patterns(
|
||||
"",
|
||||
url(r"^libraryauth/(?P<library>[^/]+)/join/$", views.join_library, name="join_library"),
|
||||
url(r"^libraryauth/(?P<library>[^/]+)/deny/$", direct_to_template, {'template':'libraryauth/denied.html'}, name="bad_library"),
|
||||
url(r'^accounts/superlogin/$', 'superlogin', name='superlogin'),
|
||||
)
|
|
@ -0,0 +1,59 @@
|
|||
import logging
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.contrib.auth.views import login
|
||||
from django.http import HttpResponseRedirect
|
||||
from . import backends
|
||||
|
||||
from .models import Library
|
||||
from .forms import AuthForm
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def join_library(request, library):
|
||||
library=get_object_or_404(Library, user__username=library)
|
||||
return Authenticator(request,library).process(
|
||||
reverse('library',args=[str(library)]),
|
||||
reverse('bad_library',args=[str(library)]),
|
||||
)
|
||||
|
||||
def superlogin(request, extra_context=None, **kwargs):
|
||||
if request.method == 'POST' and request.user.is_anonymous():
|
||||
username=request.POST.get("username", "")
|
||||
try:
|
||||
user=models.User.objects.get(username=username)
|
||||
extra_context={"socials":user.profile.social_auths}
|
||||
except:
|
||||
pass
|
||||
if request.GET.has_key("add"):
|
||||
request.session["add_wishlist"]=request.GET["add"]
|
||||
return login(request, extra_context=extra_context, authentication_form=AuthForm, **kwargs)
|
||||
|
||||
class Authenticator:
|
||||
request=None
|
||||
library=None
|
||||
|
||||
def __init__(self, request, library):
|
||||
self.request=request
|
||||
self.library=library
|
||||
|
||||
def process(self, success_url, deny_url):
|
||||
logger.info('authenticator for %s at %s.'%(self.request.user, self.library))
|
||||
if self.library.has_user(self.request.user):
|
||||
return HttpResponseRedirect(success_url)
|
||||
backend_test= getattr(backends, self.library.backend + '_authenticate')
|
||||
if backend_test(self.request, self.library):
|
||||
if self.request.user.is_authenticated():
|
||||
self.library.add_user(self.request.user)
|
||||
return HttpResponseRedirect(success_url)
|
||||
else:
|
||||
return superlogin(self.request, extra_context={'library':self.library}, template_name='libraryauth/library_login.html')
|
||||
|
||||
else:
|
||||
backend_authenticator= getattr(backends, self.library.backend + '_authenticator')
|
||||
return backend_authenticator(self.request, self.library, success_url, deny_url)
|
||||
|
||||
def allowed(self):
|
||||
backend_test= getattr(backends, self.library.backend + '_authenticate')
|
||||
return backend_test(self.request, self.library)
|
4
urls.py
4
urls.py
|
@ -4,7 +4,8 @@ from django.conf.urls.defaults import *
|
|||
from django.views.generic.simple import direct_to_template
|
||||
|
||||
from frontend.forms import ProfileForm
|
||||
from frontend.views import superlogin, social_auth_reset_password
|
||||
from frontend.views import social_auth_reset_password
|
||||
from libraryauth.views import superlogin
|
||||
from regluit.admin import admin_site
|
||||
from regluit.core.sitemaps import WorkSitemap, PublisherSitemap
|
||||
|
||||
|
@ -40,6 +41,7 @@ urlpatterns = patterns('',
|
|||
(r'^api/', include('regluit.api.urls')),
|
||||
(r'', include('regluit.frontend.urls')),
|
||||
(r'', include('regluit.payment.urls')),
|
||||
(r'', include('regluit.libraryauth.urls')),
|
||||
(r'^selectable/', include('selectable.urls')),
|
||||
url(r'^admin/', include(admin_site.urls)),
|
||||
(r'^comments/', include('django.contrib.comments.urls')),
|
||||
|
|
Loading…
Reference in New Issue