Skip to content

Instantly share code, notes, and snippets.

@jasalt
Created February 26, 2013 12:10
Show Gist options
  • Save jasalt/5038009 to your computer and use it in GitHub Desktop.
Save jasalt/5038009 to your computer and use it in GitHub Desktop.
import web
from oauthlib.oauth1 import Server
from oauthlib.common import safe_string_equals
urls = ("/.*", "hello")
app = web.application(urls, globals())
class OAuthProvider(Server):
''' https://oauthlib.readthedocs.org/en/latest/server.html '''
nonces_and_timestamps_database = [
(u'foo', 1234567890, u'rannoMstrInghere', u'bar')
]
clients_database = [u'foo']
request_token_database = [(u'foo', u'bar')]
access_token_database = []
redirect_uris = {
u'foo': [u'https://some.fance.io/callback']
}
# Realms are useful when restricting scope.
assigned_realms = {
u'foo': [u'photos']
}
realms = {
(u'foo', u'bar'): u'photos'
}
#Verifiers are assigned to a client after the resource owner (user) has authorized access. They will thus only be present (and valid) in access token request.
verifiers = {
(u'foo', u'request_token'): u'randomVerifierString'
}
client_secrets_database = {
u'foo': u'fooshizzle',
u'user1': u'password1',
u'dummy_client': u'dummy-secret'
}
request_token_secrets_database = {
(u'foo', u'someResourceOwner'): u'seeeecret',
(u'dummy_client', 'dummy_resource_owner'): u'dummy-owner-secret'
}
rsa_public_keys = {
u'foo' : u'-----BEGIN PUBLIC KEY-----MIGfMA0GCSqG....',
u'dummy_client' : u'-----BEGIN PUBLIC KEY-----e1Sb3fKQIDAQA....'
}
dummy_cl = "dummy_client"
def validate_timestamp_and_nonce(self, client_key, timestamp, nonce,
request_token=None, access_token=None):
''' For preventing replay attacks. Check nonce and timestamp, which are
associated with a client key and possibly a token, and immediately fail
the request if the nonce/timestamp pair has been used before. '''
return ((client_key, timestamp, nonce, request_token or access_token)
in self.nonces_and_timestamps_database)
def validate_client_key(self, client_key):
''' Ensure that the provided key is associated with a registered client '''
# Dummy client and dummy tokens must validate to false and do so without affecting the execution time of the client validation
if client_key == self.dummy_cl:
return False
return client_key in self.clients_database
def validate_request_token(self, client_key, request_token):
''' Ensure that the provided token is associated with a registered client''' # TODO: right?
return (client_key, request_token) in self.request_token_database
def validate_requested_realm(self, client_key, realm):
return realm in self.assigned_realms.get(client_key)
def validate_realm(self, client_key, access_token, uri=None, required_realm=None):
if required_realm:
return self.realms.get((client_key, access_token)) in required_realm
else:
# Use the URI to figure out if the associated realm is valid
return # TODO
def validate_verifier(self, client_key, request_token, verifier):
'''Constant time string comparison validation for verifier'''
return safe_string_equals(verifier, self.verifiers.get((client_key, request_token)))
def get_client_secret(self, client_key):
''' Fetches the client secret associated with client key from your database. Note that your database should include a dummy key associated with your dummy user mentioned previously. '''
return self.client_secrets_database.get(client_key)
def get_request_token_secret(self, client_key, request_token):
'''Fetches the resource owner secret associated with client key and token. Similar to get_client_secret the database should include a dummy resource owner secret.'''
return self.request_token_secrets.get((client_key, request_token))
def get_rsa_key(self, client_key):
'''If RSA signatures are used the Server must fetch the public key associated with the client.'''
return self.rsa_public_keys.get(client_key)
# Dummy values are used to enable the verification to execute in near
# constant time even if the client key or token is invalid.
# Use of these dummy values effectively eliminate the chance of an attacker
# guessing tokens and secrets by measuring the response time of request verification
@property
def dummy_client(self):
return u'dummy_client'
@property
def dummy_resource_owner(self):
return u'dummy_resource_owner'
def validate_redirect_uri(self, client_key, redirect_uri):
return (client_key in self.redirect_uris and
redirect_uri in self.redirect_uris.get(client_key))
class hello:
def GET(self):
data = ""
data = web.input()
return ('Hello, world! ' + str(data))
if __name__ == "__main__":
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment