-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from rest_framework import serializers
from sorl.thumbnail import default
from django.core.urlresolvers import reverse
-from paypal.rest import user_is_subscribed
+from club.models import Membership
class AbsoluteURLField(serializers.ReadOnlyField):
super(UserPremiumField, self).__init__(*args, source='*', **kwargs)
def to_representation(self, value):
- return user_is_subscribed(value)
+ return Membership.is_active_for(value)
class ThumbnailField(serializers.FileField):
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
self.signed('/api/epub/grandchild/').status_code,
403)
- with patch('api.fields.user_is_subscribed', return_value=True):
+ with patch('club.models.Membership.is_active_for', return_value=True):
self.assertEqual(
self.signed_json('/api/username/'),
{"username": "test", "premium": True})
- with patch('paypal.permissions.user_is_subscribed', return_value=True):
with patch('django.core.files.storage.Storage.open',
return_value=BytesIO(b"<epub>")):
self.assertEqual(
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from rest_framework.permissions import DjangoModelPermissionsOrAnonReadOnly
from rest_framework.response import Response
from rest_framework import status
-from paypal.permissions import IsSubscribed
from api.handlers import read_tags
from api.utils import vary_on_auth
from .helpers import books_after, order_books
from catalogue.forms import BookImportForm
from catalogue.models import Book, Collection, Tag, Fragment, BookMedia
from catalogue.models.tag import prefetch_relations
+from club.permissions import IsClubMember
from wolnelektury.utils import re_escape
class EpubView(RetrieveAPIView):
queryset = Book.objects.all()
lookup_field = 'slug'
- permission_classes = [IsSubscribed]
+ permission_classes = [IsClubMember]
def get(self, *args, **kwargs):
return HttpResponse(self.get_object().get_media('epub'))
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from catalogue.helpers import get_audiobook_tags
from catalogue.models import Book, BookMedia, Fragment, Tag, Source
from catalogue.constants import LICENSES
-from paypal.rest import user_is_subscribed
+from club.models import Membership
from picture.models import Picture
register = template.Library()
def status(book, user):
if not book.preview:
return 'open'
- elif user_is_subscribed(user):
+ elif Membership.is_active_for(user):
return 'preview'
else:
return 'closed'
from django.utils.translation import ugettext as _, ugettext_lazy
from ajaxable.utils import AjaxableFormView
+from club.models import Membership
from pdcounter import views as pdcounter_views
-from paypal.rest import user_is_subscribed
from picture.models import Picture, PictureArea
from ssify import ssi_included, ssi_expect, SsiVariable as Var
from catalogue import constants
def book_text(request, slug):
book = get_object_or_404(Book, slug=slug)
- if book.preview and not user_is_subscribed(request.user):
+ if book.preview and not Membership.is_active_for(request.user):
return HttpResponseRedirect(book.get_absolute_url())
if not book.has_html_file():
media_file = book.get_media(format_)
if not book.preview:
return HttpResponseRedirect(media_file.url)
- if not user_is_subscribed(request.user):
+ if not Membership.is_active_for(request.user):
return HttpResponseRedirect(book.get_absolute_url())
return HttpResponse(media_file, content_type=constants.EBOOK_CONTENT_TYPES[format_])
def validate_object(self, obj, request):
book = obj
- if book.preview and not user_is_subscribed(request.user):
+ if book.preview and not Membership_is_active_for(request.user):
return HttpResponseRedirect(book.get_absolute_url())
return super(CustomPDFFormView, self).validate_object(obj, request)
def get_payment_method(self):
return method_by_slug[self.method]
-
def is_expired(self):
return self.expires_at is not None and self.expires_at < now()
def __str__(self):
return u'tow. ' + str(self.user)
+ @classmethod
+ def is_active_for(self, user):
+ if user.is_anonymous:
+ return False
+ return Schedule.objects.filter(
+ models.Q(expires_at=None) | models.Q(expires_at__lt=now()),
+ membership__user=user,
+ is_active=True,
+ ).exists()
+
class ReminderEmail(models.Model):
days_before = models.SmallIntegerField(_('days before'))
--- /dev/null
+from rest_framework.permissions import BasePermission
+from .models import Membership
+
+
+class IsClubMember(BasePermission):
+ def has_permission(self, request, view):
+ return Membership.is_active_for(request.user)
+++ /dev/null
-from rest_framework.permissions import BasePermission
-from .rest import user_is_subscribed
-
-
-class IsSubscribed(BasePermission):
- def has_permission(self, request, view):
- return request.user.is_authenticated and user_is_subscribed(request.user)
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.contrib.auth.models import User
+from unittest import skip
from unittest.mock import MagicMock, Mock, patch, DEFAULT
from catalogue.test_utils import WLTestCase
from .models import BillingAgreement, BillingPlan
def tearDownClass(cls):
cls.user.delete()
+ @skip("Changing the flow.")
def test_paypal_form(self):
response = self.client.get('/paypal/form/')
self.assertEqual(response.status_code, 200)
+ @skip("Changing the flow.")
def test_paypal_form_unauthorized(self):
"""Legacy flow: only allow payment for logged-in users."""
response = self.client.post('/paypal/form/', {"amount": "0"})
self.assertEqual(response.status_code, 403)
+ @skip("Changing the flow.")
def test_paypal_form_invalid(self):
"""Paypal form: error on bad input."""
self.client.login(username='test', password='test')
len(response.context['form'].errors['amount']),
1)
+ @skip("Changing the flow.")
@patch.multiple('paypalrestsdk',
BillingPlan=BillingPlanMock,
BillingAgreement=BillingAgreementMock,
# No BillingAgreement created in our DB yet.
self.assertEqual(BillingAgreement.objects.all().count(), 0)
+ @skip("Changing the flow.")
@patch('paypalrestsdk.BillingPlan', BillingPlanMock)
def test_paypal_form_error(self):
"""On PayPal error, plan does not get created."""
# But now the plan should be created.
self.assertEqual(BillingPlan.objects.all().count(), 1)
+ @skip("Changing the flow.")
@patch.multiple('paypalrestsdk',
BillingPlan=BillingPlanMock,
BillingAgreement=BillingAgreementMock,
-# -*- coding: utf-8 -*-
# This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
# Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
#
from django.conf.urls import url
+from django.views.generic import RedirectView
from . import views
urlpatterns = (
- url(r'^form/$', views.paypal_form, name='paypal_form'),
- url(r'^app-form/$', views.paypal_form, kwargs={'app': True}, name='paypal_app_form'),
+ url(r'^form/$', RedirectView.as_view(url='/towarzystwo/dolacz/')),
+ url(r'^app-form/$', RedirectView.as_view(url='/towarzystwo/dolacz/app/')),
+
url(r'^return/$', views.paypal_return, name='paypal_return'),
url(r'^app-return/$', views.paypal_return, kwargs={'app': True}, name='paypal_app_return'),
url(r'^cancel/$', views.paypal_cancel, name='paypal_cancel'),