Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
D
django-rest-framework
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
django-rest-framework
Commits
eff54c00
Commit
eff54c00
authored
Jan 24, 2011
by
tom christie tom@tomchristie.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added authenicators. Awesome.
parent
e95198a1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
84 additions
and
24 deletions
+84
-24
docs/index.rst
+8
-2
flywheel/authenticators.py
+44
-0
flywheel/resource.py
+32
-22
No files found.
docs/index.rst
View file @
eff54c00
...
...
@@ -3,9 +3,15 @@ FlyWheel Documentation
This is the online documentation for FlyWheel - A REST framework for Django.
Some of FlyWheel's features:
* Clean, simple, class-based views for Resources.
* Easy input validation using Forms and ModelForms.
* Self describing APIs, with HTML and Plain Text outputs.
* Support for ModelResources with nice default implementations and input validation.
* Automatically provides a browse-able self-documenting API.
* Pluggable Emitters, Parsers and Authenticators - Easy to customise.
* Content type negotiation using Accept headers.
* Optional support for forms as input validation.
* Modular architecture - Easy to extend and modify.
.. toctree::
:maxdepth: 1
...
...
flywheel/authenticators.py
0 → 100644
View file @
eff54c00
from
django.contrib.auth
import
authenticate
import
base64
class
BaseAuthenticator
(
object
):
"""All authenticators should extend BaseAuthenticator."""
def
__init__
(
self
,
resource
):
"""Initialise the authenticator with the Resource instance as state,
in case the authenticator needs to access any metadata on the Resource object."""
self
.
resource
=
resource
def
authenticate
(
self
,
request
):
"""Authenticate the request and return the authentication context or None.
The default permission checking on Resource will use the allowed_methods attribute
for permissions if the authentication context is not None, and use anon_allowed_methods otherwise.
The authentication context is passed to the method calls eg Resource.get(request, auth) in order to
allow them to apply any more fine grained permission checking at the point the response is being generated.
This function must be overridden to be implemented."""
return
None
class
BasicAuthenticator
(
BaseAuthenticator
):
"""Use HTTP Basic authentication"""
def
authenticate
(
self
,
request
):
if
'HTTP_AUTHORIZATION'
in
request
.
META
:
auth
=
request
.
META
[
'HTTP_AUTHORIZATION'
]
.
split
()
if
len
(
auth
)
==
2
and
auth
[
0
]
.
lower
()
==
"basic"
:
uname
,
passwd
=
base64
.
b64decode
(
auth
[
1
])
.
split
(
':'
)
user
=
authenticate
(
username
=
uname
,
password
=
passwd
)
if
user
is
not
None
and
user
.
is_active
:
return
user
return
None
class
UserLoggedInAuthenticator
(
BaseAuthenticator
):
"""Use Djagno's built-in request session for authentication."""
def
authenticate
(
self
,
request
):
if
request
.
user
and
request
.
user
.
is_active
:
return
request
.
user
return
None
flywheel/resource.py
View file @
eff54c00
...
...
@@ -2,7 +2,7 @@ from django.contrib.sites.models import Site
from
django.core.urlresolvers
import
reverse
from
django.http
import
HttpResponse
from
flywheel
import
emitters
,
parsers
from
flywheel
import
emitters
,
parsers
,
authenticators
from
flywheel.response
import
status
,
Response
,
ResponseException
from
decimal
import
Decimal
...
...
@@ -48,6 +48,10 @@ class Resource(object):
parsers
=
(
parsers
.
JSONParser
,
parsers
.
XMLParser
,
parsers
.
FormParser
)
# List of all authenticating methods to attempt
authenticators
=
(
authenticators
.
UserLoggedInAuthenticator
,
authenticators
.
BasicAuthenticator
)
# Optional form for input validation and presentation of HTML formatted responses.
form
=
None
...
...
@@ -81,7 +85,6 @@ class Resource(object):
""""""
# Setup the resource context
self
.
request
=
request
self
.
auth_context
=
None
self
.
response
=
None
self
.
form_instance
=
None
...
...
@@ -123,7 +126,7 @@ class Resource(object):
# """Return an list of all the media types that this resource can emit."""
# return [parser.media_type for parser in self.parsers]
#def de
af
ult_parser(self):
#def de
fa
ult_parser(self):
# return self.parsers[0]
...
...
@@ -133,31 +136,22 @@ class Resource(object):
return
self
.
add_domain
(
reverse
(
view
,
args
=
args
,
kwargs
=
kwargs
))
def
authenticate
(
self
,
request
):
"""TODO"""
return
None
# user = ...
# if DEBUG and request is from localhost
# if anon_user and not anon_allowed_methods raise PermissionDenied
# return auth_context
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
def
get
(
self
,
request
,
auth
,
*
args
,
**
kwargs
):
"""Must be subclassed to be implemented."""
self
.
not_implemented
(
'GET'
)
def
post
(
self
,
request
,
content
,
*
args
,
**
kwargs
):
def
post
(
self
,
request
,
auth
,
content
,
*
args
,
**
kwargs
):
"""Must be subclassed to be implemented."""
self
.
not_implemented
(
'POST'
)
def
put
(
self
,
request
,
content
,
*
args
,
**
kwargs
):
def
put
(
self
,
request
,
auth
,
content
,
*
args
,
**
kwargs
):
"""Must be subclassed to be implemented."""
self
.
not_implemented
(
'PUT'
)
def
delete
(
self
,
request
,
*
args
,
**
kwargs
):
def
delete
(
self
,
request
,
auth
,
*
args
,
**
kwargs
):
"""Must be subclassed to be implemented."""
self
.
not_implemented
(
'DELETE'
)
...
...
@@ -196,12 +190,28 @@ class Resource(object):
return
method
def
check_method_allowed
(
self
,
method
):
def
authenticate
(
self
,
request
):
"""Attempt to authenticate the request, returning an authentication context or None"""
for
authenticator
in
self
.
authenticators
:
auth_context
=
authenticator
(
self
)
.
authenticate
(
request
)
if
auth_context
:
return
auth_context
return
None
def
check_method_allowed
(
self
,
method
,
auth
):
"""Ensure the request method is acceptable for this resource."""
# If anonoymous check permissions and bail with no further info if disallowed
if
auth
is
None
and
not
method
in
self
.
anon_allowed_methods
:
raise
ResponseException
(
status
.
HTTP_403_FORBIDDEN
,
{
'detail'
:
'You do not have permission to access this resource. '
+
'You may need to login or otherwise authenticate the request.'
})
if
not
method
in
self
.
callmap
.
keys
():
raise
ResponseException
(
status
.
HTTP_501_NOT_IMPLEMENTED
,
{
'detail'
:
'Unknown or unsupported method
\'
%
s
\'
'
%
method
})
if
not
method
in
self
.
allowed_methods
:
raise
ResponseException
(
status
.
HTTP_405_METHOD_NOT_ALLOWED
,
{
'detail'
:
'Method
\'
%
s
\'
not allowed on this resource.'
%
method
})
...
...
@@ -376,10 +386,10 @@ class Resource(object):
# Typically the context will be a user, or None if this is an anonymous request,
# but it could potentially be more complex (eg the context of a request key which
# has been signed against a particular set of permissions)
self
.
auth_context
=
self
.
authenticate
(
request
)
auth_context
=
self
.
authenticate
(
request
)
# Ensure the requested operation is permitted on this resource
self
.
check_method_allowed
(
method
)
self
.
check_method_allowed
(
method
,
auth_context
)
# Get the appropriate create/read/update/delete function
func
=
getattr
(
self
,
self
.
callmap
.
get
(
method
,
None
))
...
...
@@ -391,10 +401,10 @@ class Resource(object):
data
=
parser
(
self
)
.
parse
(
request
.
raw_post_data
)
self
.
form_instance
=
self
.
get_form
(
data
)
data
=
self
.
cleanup_request
(
data
,
self
.
form_instance
)
response
=
func
(
request
,
data
,
*
args
,
**
kwargs
)
response
=
func
(
request
,
auth_context
,
data
,
*
args
,
**
kwargs
)
else
:
response
=
func
(
request
,
*
args
,
**
kwargs
)
response
=
func
(
request
,
auth_context
,
*
args
,
**
kwargs
)
# Allow return value to be either Response, or an object, or None
if
isinstance
(
response
,
Response
):
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment