1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 from oauthlib
.common
import Request
19 from oauthlib
.oauth1
import RequestValidator
21 from mediagoblin
import oauth
22 from mediagoblin
.db
.models
import NonceTimestamp
, Client
, RequestToken
, AccessToken
24 class GMGRequestValidator(RequestValidator
):
28 def __init__(self
, data
=None, *args
, **kwargs
):
30 super(GMGRequestValidator
, self
).__init
__(*args
, **kwargs
)
32 def check_nonce(self
, nonce
):
34 This checks that the nonce given is a valid nonce
36 RequestValidator.check_nonce checks that it's between a maximum and
37 minimum length which, not only does pump.io not do this from what
38 I can see but there is nothing in rfc5849 which suggests a maximum or
39 minium length should be required so I'm removing that check
41 # Check the nonce only contains a subset of the safe characters.
42 return set(nonce
) <= self
.safe_characters
44 def save_request_token(self
, token
, request
):
45 """ Saves request token in db """
46 client_id
= self
.POST
[u
"oauth_consumer_key"]
48 request_token
= RequestToken(
49 token
=token
["oauth_token"],
50 secret
=token
["oauth_token_secret"],
52 request_token
.client
= client_id
53 if u
"oauth_callback" in self
.POST
:
54 request_token
.callback
= self
.POST
[u
"oauth_callback"]
57 def save_verifier(self
, token
, verifier
, request
):
58 """ Saves the oauth request verifier """
59 request_token
= RequestToken
.query
.filter_by(token
=token
).first()
60 request_token
.verifier
= verifier
["oauth_verifier"]
63 def save_access_token(self
, token
, request
):
64 """ Saves access token in db """
65 access_token
= AccessToken(
66 token
=token
["oauth_token"],
67 secret
=token
["oauth_token_secret"],
69 access_token
.request_token
= request
.oauth_token
70 request_token
= RequestToken
.query
.filter_by(token
=request
.oauth_token
).first()
71 access_token
.actor
= request_token
.actor
74 def get_realms(*args
, **kwargs
):
75 """ Currently a stub - called when making AccessTokens """
78 def validate_timestamp_and_nonce(self
, client_key
, timestamp
,
79 nonce
, request
, request_token
=None,
81 # RFC5849 (OAuth 1.0) section 3.3 says the timestamp is going
82 # to be seconds after the epoch, we need to convert for postgres
84 timestamp
= datetime
.datetime
.fromtimestamp(float(timestamp
))
86 # Well, the client must have passed up something ridiculous
89 nc
= NonceTimestamp
.query
.filter_by(timestamp
=timestamp
, nonce
=nonce
)
96 def validate_client_key(self
, client_key
, request
):
97 """ Verifies client exists with id of client_key """
98 client_query
= Client
.query
.filter(Client
.id != oauth
.DUMMY_CLIENT_ID
)
99 client
= client_query
.filter_by(id=client_key
).first()
105 def validate_verifier(self
, token
, verifier
):
106 """ Verifies the verifier token is correct. """
107 request_token
= RequestToken
.query
.filter_by(token
=token
).first()
108 if request_token
is None:
111 if request_token
.verifier
!= verifier
:
116 def validate_access_token(self
, client_key
, token
, request
):
117 """ Verifies token exists for client with id of client_key """
118 # Get the client for the request
119 client_query
= Client
.query
.filter(Client
.id != oauth
.DUMMY_CLIENT_ID
)
120 client
= client_query
.filter_by(id=client_key
).first()
122 # If the client is invalid then it's invalid
126 # Look up the AccessToken
127 access_token_query
= AccessToken
.query
.filter(
128 AccessToken
.token
!= oauth
.DUMMY_ACCESS_TOKEN
130 access_token
= access_token_query
.filter_by(token
=token
).first()
132 # If there isn't one - we can't validate.
133 if access_token
is None:
136 # Check that the client matches the on
137 request_token_query
= RequestToken
.query
.filter(
138 RequestToken
.token
!= oauth
.DUMMY_REQUEST_TOKEN
,
139 RequestToken
.token
== access_token
.request_token
141 request_token
= request_token_query
.first()
143 if client
.id != request_token
.client
:
148 def validate_realms(self
, *args
, **kwargs
):
149 """ Would validate reals however not using these yet. """
150 return True # implement when realms are implemented
153 def get_client_secret(self
, client_key
, request
):
154 """ Retrives a client secret with from a client with an id of client_key """
155 client
= Client
.query
.filter_by(id=client_key
).first()
158 def get_access_token_secret(self
, client_key
, token
, request
):
159 access_token
= AccessToken
.query
.filter_by(token
=token
).first()
160 return access_token
.secret
163 def dummy_client(self
):
164 return oauth
.DUMMY_CLIENT_ID
167 def dummy_request_token(self
):
168 return oauth
.DUMMY_REQUEST_TOKEN
171 def dummy_access_token(self
):
172 return oauth
.DUMMY_ACCESS_TOKEN
174 class GMGRequest(Request
):
176 Fills in data to produce a oauth.common.Request object from a
177 werkzeug Request object
180 def __init__(self
, request
, *args
, **kwargs
):
182 :param request: werkzeug request object
184 any extra params are passed to oauthlib.common.Request object
186 kwargs
["uri"] = kwargs
.get("uri", request
.url
)
187 kwargs
["http_method"] = kwargs
.get("http_method", request
.method
)
188 kwargs
["body"] = kwargs
.get("body", request
.data
)
189 kwargs
["headers"] = kwargs
.get("headers", dict(request
.headers
))
191 super(GMGRequest
, self
).__init
__(*args
, **kwargs
)