Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sneridagh committed Dec 13, 2011
0 parents commit 93999d5
Show file tree
Hide file tree
Showing 26 changed files with 638 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
*.db
*.log
*.pyc
*.egg-info
*.DS_Store
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
0.0
---

- Initial version
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include *.txt *.ini *.cfg *.rst
recursive-include osiris *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml
1 change: 1 addition & 0 deletions README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
osiris README
49 changes: 49 additions & 0 deletions development.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[app:main]
use = egg:osiris

pyramid.reload_templates = true
pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.debug_templates = true
pyramid.default_locale_name = en
pyramid.includes = pyramid_debugtoolbar

mongodb.url = mongodb://localhost
mongodb.db_name = osiris

[server:main]
use = egg:Paste#http
host = 0.0.0.0
port = 6543

# Begin logging configuration

[loggers]
keys = root, osiris

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_osiris]
level = DEBUG
handlers =
qualname = osiris

[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s

# End logging configuration
45 changes: 45 additions & 0 deletions osiris/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from pyramid.config import Configurator
from pyramid.events import subscriber
from pyramid.events import NewRequest

from osiris.resources import Root

from pyramid_who.whov2 import WhoV2AuthenticationPolicy
from pyramid.authorization import ACLAuthorizationPolicy

import pymongo


def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
whoconfig_file = 'who.ini'
identifier_id = 'auth_tkt'
authn_policy = WhoV2AuthenticationPolicy(whoconfig_file, identifier_id)
authz_policy = ACLAuthorizationPolicy()

config = Configurator(root_factory=Root,
settings=settings,
authentication_policy=authn_policy,
authorization_policy=authz_policy)
config.add_static_view('static', 'osiris:static', cache_max_age=3600)

# MongoDB
def add_mongo_db(event):
settings = event.request.registry.settings
url = settings['mongodb.url']
db_name = settings['mongodb.db_name']
db = settings['mongodb_conn'][db_name]
event.request.db = db
db_uri = settings['mongodb.url']
MongoDB = pymongo.Connection
if 'pyramid_debugtoolbar' in set(settings.values()):
class MongoDB(pymongo.Connection):
def __html__(self):
return 'MongoDB: <b>{}></b>'.format(self)
conn = MongoDB(db_uri)
config.registry.settings['mongodb_conn'] = conn
config.add_subscriber(add_mongo_db, NewRequest)

config.scan('osiris')
return config.make_wsgi_app()
17 changes: 17 additions & 0 deletions osiris/authorization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from pyramid.interfaces import IAuthenticationPolicy
from osiris.errorhandling import OAuth2ErrorHandler
from osiris.resources import issue_token


def password_authorization(request, username, password, scope):

policy = request.registry.queryUtility(IAuthenticationPolicy)
authapi = policy._getAPI(request)
credentials = {'login': username, 'password': password}

identity, headers = authapi.login(credentials)

if not identity:
return OAuth2ErrorHandler.error_unauthorized_user()
else:
issue_token(request, username, password, scope)
43 changes: 43 additions & 0 deletions osiris/endpoints.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from pyramid.view import view_config
from osiris.errorhandling import OAuth2ErrorHandler
from osiris.resources import Root
from osiris.authorization import password_authorization


@view_config(context=Root,
name='token',
renderer='json',
request_method='POST',
http_cache=0)
def token_endpoint(request):
"""
The token endpoint is used by the client to obtain an access token by
presenting its authorization grant or refresh token. The token
endpoint is used with every authorization grant except for the
implicit grant type (since an access token is issued directly).
"""
#request = OAuth2Request(request)
import ipdb;ipdb.set_trace()

grant_type = request.params.get('grant_type')

# Authorization Code Grant
if grant_type == 'authorization_code':
return OAuth2ErrorHandler.error_unsupported_grant_type()
# Implicit Grant
elif grant_type == 'implicit':
return OAuth2ErrorHandler.error_unsupported_grant_type()
# Client Credentials
elif grant_type == 'client_credentials':
return OAuth2ErrorHandler.error_unsupported_grant_type()
# Client Credentials Grant
elif grant_type == 'password':
scope = request.params.get('scope', '') # Optional
username = request.params.get('username', None)
password = request.params.get('password', None)
if username is None or password is None:
return OAuth2ErrorHandler.error_invalid_request()

return password_authorization(request, username, password, scope)
else:
return OAuth2ErrorHandler.error_unsupported_grant_type()
79 changes: 79 additions & 0 deletions osiris/errorhandling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from pyramid.httpexceptions import HTTPUnauthorized


class OAuth2ErrorHandler(object):

@staticmethod
def error_invalid_request():
"""
The request is missing a required parameter, includes an
unsupported parameter or parameter value, repeats a
parameter, includes multiple credentials, utilizes more
than one mechanism for authenticating the client, or is
otherwise malformed.
"""
return dict(error='invalid_request',
error_description="")

@staticmethod
def error_invalid_client():
"""
Client authentication failed (e.g. unknown client, no
client authentication included, multiple client
authentications included, or unsupported authentication
method). The authorization server MAY return an HTTP 401
(Unauthorized) status code to indicate which HTTP
authentication schemes are supported. If the client
attempted to authenticate via the "Authorization" request
header field, the authorization server MUST respond with
an HTTP 401 (Unauthorized) status code, and include the
"WWW-Authenticate" response header field matching the
authentication scheme used by the client.
"""
return dict(error='invalid_client',
error_description="")

@staticmethod
def error_invalid_grant():
"""
The provided authorization grant is invalid, expired,
revoked, does not match the redirection URI used in the
authorization request, or was issued to another client.
"""
return dict(error='invalid_grant',
error_description="")

@staticmethod
def error_unauthorized_user():
"""
The authenticated user is not authorized to use this
authorization grant type.
"""
return dict(error='unauthorized_client',
error_description="")

@staticmethod
def error_unsupported_grant_type():
"""
The authorization grant type is not supported by the
authorization server.
"""
return dict(error='unsupported_grant_type',
error_description="")

@staticmethod
def error_invalid_scope():
"""
The requested scope is invalid, unknown, malformed, or
exceeds the scope granted by the resource owner.
"""
return dict(error='invalid_scope',
error_description="")

@staticmethod
def error_invalid_token(token_type):
"""
The specific handling of this error is based on the token
type used, i.e. bearer or MAC.
"""
raise HTTPUnauthorized('todo') # TODO: add correct error handling for bearer
42 changes: 42 additions & 0 deletions osiris/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from osiris.generators import generate_token
from random import choice


ACCESS_TOKEN_LENGTH = 10
REFRESH_TOKEN_LENGTH = 10
CLIENT_KEY_LENGTH = 8
CLIENT_SECRET_LENGTH = 20
ALLOWED_CHARACTERS = 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ0123456789'


class Root(object):
def __init__(self, request):
self.request = request


def issue_token(request, username, password, scope):

token = oAuth2AccessToken()


class oAuth2AccessToken(object):
"""Wrapper of the token collection objects"""

collection = 'tokens'

schema = [
'username',
'token',
'scope',
'issued_at',
'expires_at',
'revoked_at'
]

def __init__(self, token=None):
if token is not None:
self.generate_token()

def generate_token(self, length=ACCESS_TOKEN_LENGTH, allowed_chars=ALLOWED_CHARACTERS):
# We assume that the token will be enough random, otherwise we need to make sure of it
return ''.join([choice(allowed_chars) for i in range(length)])
Binary file added osiris/static/favicon.ico
Binary file not shown.
Binary file added osiris/static/footerbg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added osiris/static/headerbg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions osiris/static/ie6.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
* html img,
* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')",
this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')",
this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
);}
#wrap{display:table;height:100%}
Binary file added osiris/static/middlebg.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
65 changes: 65 additions & 0 deletions osiris/static/pylons.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;/* 16px */
vertical-align:baseline;background:transparent;}
body{line-height:1;}
ol,ul{list-style:none;}
blockquote,q{quotes:none;}
blockquote:before,blockquote:after,q:before,q:after{content:'';content:none;}
:focus{outline:0;}
ins{text-decoration:none;}
del{text-decoration:line-through;}
table{border-collapse:collapse;border-spacing:0;}
sub{vertical-align:sub;font-size:smaller;line-height:normal;}
sup{vertical-align:super;font-size:smaller;line-height:normal;}
ul,menu,dir{display:block;list-style-type:disc;margin:1em 0;padding-left:40px;}
ol{display:block;list-style-type:decimal-leading-zero;margin:1em 0;padding-left:40px;}
li{display:list-item;}
ul ul,ul ol,ul dir,ul menu,ul dl,ol ul,ol ol,ol dir,ol menu,ol dl,dir ul,dir ol,dir dir,dir menu,dir dl,menu ul,menu ol,menu dir,menu menu,menu dl,dl ul,dl ol,dl dir,dl menu,dl dl{margin-top:0;margin-bottom:0;}
ol ul,ul ul,menu ul,dir ul,ol menu,ul menu,menu menu,dir menu,ol dir,ul dir,menu dir,dir dir{list-style-type:circle;}
ol ol ul,ol ul ul,ol menu ul,ol dir ul,ol ol menu,ol ul menu,ol menu menu,ol dir menu,ol ol dir,ol ul dir,ol menu dir,ol dir dir,ul ol ul,ul ul ul,ul menu ul,ul dir ul,ul ol menu,ul ul menu,ul menu menu,ul dir menu,ul ol dir,ul ul dir,ul menu dir,ul dir dir,menu ol ul,menu ul ul,menu menu ul,menu dir ul,menu ol menu,menu ul menu,menu menu menu,menu dir menu,menu ol dir,menu ul dir,menu menu dir,menu dir dir,dir ol ul,dir ul ul,dir menu ul,dir dir ul,dir ol menu,dir ul menu,dir menu menu,dir dir menu,dir ol dir,dir ul dir,dir menu dir,dir dir dir{list-style-type:square;}
.hidden{display:none;}
p{line-height:1.5em;}
h1{font-size:1.75em;line-height:1.7em;font-family:helvetica,verdana;}
h2{font-size:1.5em;line-height:1.7em;font-family:helvetica,verdana;}
h3{font-size:1.25em;line-height:1.7em;font-family:helvetica,verdana;}
h4{font-size:1em;line-height:1.7em;font-family:helvetica,verdana;}
html,body{width:100%;height:100%;}
body{margin:0;padding:0;background-color:#ffffff;position:relative;font:16px/24px "NobileRegular","Lucida Grande",Lucida,Verdana,sans-serif;}
a{color:#1b61d6;text-decoration:none;}
a:hover{color:#e88f00;text-decoration:underline;}
body h1,
body h2,
body h3,
body h4,
body h5,
body h6{font-family:"NeutonRegular","Lucida Grande",Lucida,Verdana,sans-serif;font-weight:normal;color:#373839;font-style:normal;}
#wrap{min-height:100%;}
#header,#footer{width:100%;color:#ffffff;height:40px;position:absolute;text-align:center;line-height:40px;overflow:hidden;font-size:12px;vertical-align:middle;}
#header{background:#000000;top:0;font-size:14px;}
#footer{bottom:0;background:#000000 url(footerbg.png) repeat-x 0 top;position:relative;margin-top:-40px;clear:both;}
.header,.footer{width:750px;margin-right:auto;margin-left:auto;}
.wrapper{width:100%}
#top,#top-small,#bottom{width:100%;}
#top{color:#000000;height:230px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;}
#top-small{color:#000000;height:60px;background:#ffffff url(headerbg.png) repeat-x 0 top;position:relative;}
#bottom{color:#222;background-color:#ffffff;}
.top,.top-small,.middle,.bottom{width:750px;margin-right:auto;margin-left:auto;}
.top{padding-top:40px;}
.top-small{padding-top:10px;}
#middle{width:100%;height:100px;background:url(middlebg.png) repeat-x;border-top:2px solid #ffffff;border-bottom:2px solid #b2b2b2;}
.app-welcome{margin-top:25px;}
.app-name{color:#000000;font-weight:bold;}
.bottom{padding-top:50px;}
#left{width:350px;float:left;padding-right:25px;}
#right{width:350px;float:right;padding-left:25px;}
.align-left{text-align:left;}
.align-right{text-align:right;}
.align-center{text-align:center;}
ul.links{margin:0;padding:0;}
ul.links li{list-style-type:none;font-size:14px;}
form{border-style:none;}
fieldset{border-style:none;}
input{color:#222;border:1px solid #ccc;font-family:sans-serif;font-size:12px;line-height:16px;}
input[type=text],input[type=password]{width:205px;}
input[type=submit]{background-color:#ddd;font-weight:bold;}
/*Opera Fix*/
body:before{content:"";height:100%;float:left;width:0;margin-top:-32767px;}
Binary file added osiris/static/pyramid-small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added osiris/static/pyramid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added osiris/static/transparent.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 93999d5

Please sign in to comment.