Move authorize endpoint to OAuthlib.
[wolnelektury.git] / src / api / request_validator.py
1 # -*- coding: utf-8 -*-
2 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
3 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 #
5 import time
6 from oauthlib.oauth1 import RequestValidator
7 from piston.models import Consumer, Nonce, Token
8
9
10 class PistonRequestValidator(RequestValidator):
11     timestamp_threshold = 300
12
13     dummy_access_token = '!'
14     realms = ['API']
15
16     # Just for the tests.
17     # It'd be a little more kosher to use test client with secure=True.
18     enforce_ssl = False
19
20     # iOS app generates 8-char nonces.
21     nonce_length = 8, 250
22
23     # Because piston.models.Token.key is char(18).
24     access_token_length = 18, 32
25
26     def check_client_key(self, client_key):
27         """We control the keys anyway."""
28         return True
29
30     def get_access_token_secret(self, client_key, token, request):
31         return request.token.secret
32
33     def get_default_realms(self, client_key, request):
34         return ['API']
35
36     def validate_access_token(self, client_key, token, request):
37         try:
38             token = Token.objects.get(
39                 token_type=Token.ACCESS,
40                 consumer__key=client_key,
41                 key=token
42             )
43         except Token.DoesNotExist:
44             return False
45         else:
46             request.token = token
47             return True
48
49     def validate_timestamp_and_nonce(self, client_key, timestamp, nonce,
50                                      request, request_token=None, access_token=None):
51         if abs(time.time() - int(timestamp)) > self.timestamp_threshold:
52             return False
53         token = request_token or access_token
54         # Yes, this is what Piston did.
55         if token is None:
56             return True
57
58         nonce, created = Nonce.objects.get_or_create(consumer_key=client_key,
59                                                      token_key=token,
60                                                      key=nonce)
61         return created
62
63     def validate_client_key(self, client_key, request):
64         try:
65             request.oauth_consumer = Consumer.objects.get(key=client_key)
66         except Consumer.DoesNotExist:
67             return False
68         return True
69
70     def validate_realms(self, client_key, token, request, uri=None, realms=None):
71         return True
72
73     def validate_requested_realms(self, *args, **kwargs):
74         return True
75
76     def validate_redirect_uri(self, *args, **kwargs):
77         return True
78
79     def get_client_secret(self, client_key, request):
80         return request.oauth_consumer.secret
81
82     def save_request_token(self, token, request):
83         Token.objects.create(
84             token_type=Token.REQUEST,
85             timestamp=request.timestamp,
86             key=token['oauth_token'],
87             secret=token['oauth_token_secret'],
88             consumer=request.oauth_consumer,
89         )
90
91     def verify_request_token(self, token, request):
92         return Token.objects.filter(
93             token_type=Token.REQUEST, key=token, is_approved=False
94         ).exists()
95
96     def get_realms(self, *args, **kwargs):
97         return []
98
99     def save_verifier(self, token, verifier, request):
100         Token.objects.filter(
101             token_type=Token.REQUEST,
102             key=token,
103             is_approved=False
104         ).update(
105             is_approved=True,
106             user=verifier['user']
107         )
108
109     def get_redirect_uri(self, token, request):
110         return request.redirect_uri