Skip to content

Commit

Permalink
Init
Browse files Browse the repository at this point in the history
  • Loading branch information
SamuelMarks committed Jul 31, 2014
0 parents commit 2d0910a
Show file tree
Hide file tree
Showing 6 changed files with 370 additions and 0 deletions.
268 changes: 268 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
*.pyproj
web.config
obj/

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml

# Translations
*.mo

# Mr Developer
.mr.developer.cfg
.project
.pydevproject

# Rope
.ropeproject

# Django stuff:
*.log
*.pot

# Sphinx documentation
docs/_build/



### PyCharm ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm

## Directory-based project format
.idea/
# if you remove the above rule, at least ignore user-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# and these sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml

## File-based project format
*.ipr
*.iws
*.iml

## Additional for IntelliJ
out/

# generated by mpeltonen/sbt-idea plugin
.idea_modules/

# generated by JIRA plugin
atlassian-ide-plugin.xml

# generated by Crashlytics plugin (for Android Studio and Intellij)
com_crashlytics_export_strings.xml


### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.

# User-specific files
*.suo
*.user
*.sln.docstates

# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
x64/
build/
bld/
[Bb]in/
[Oo]bj/

# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*

#NUNIT
*.VisualState.xml
TestResult.xml

# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c

*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc

# Chutzpah Test files
_Chutzpah*

# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile

# Visual Studio profiler
*.psess
*.vsp
*.vspx

# TFS 2012 Local Workspace
$tf/

# Guidance Automation Toolkit
*.gpState

# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user

# JustCode is a .NET coding addin-in
.JustCode

# TeamCity is a build add-in
_TeamCity*

# DotCover is a Code Coverage Tool
*.dotCover

# NCrunch
*.ncrunch*
_NCrunch_*
.*crunch*.local.xml

# MightyMoose
*.mm.*
AutoTest.Net/

# Web workbench (sass)
.sass-cache/

# Installshield output folder
[Ee]xpress/

# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html

# Click-Once directory
publish/

# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml

# NuGet Packages Directory
packages/
## TODO: If the tool you use requires repositories.config uncomment the next line
#!packages/repositories.config

# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
!packages/build/

# Windows Azure Build Output
csx/
*.build.csdef

# Windows Store app package directory
AppPackages/

# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/

# RIA/Silverlight projects
Generated_Code/

# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm

# SQL Server files
*.mdf
*.ldf

# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings

# Microsoft Fakes
FakesAssemblies/
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
user-api
========

Bottle REST API for handling users.
42 changes: 42 additions & 0 deletions namespace_user_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from bottle import Bottle, response, request
from mongoengine.errors import NotUniqueError, ValidationError
from oauth2_bottle_app import oauth2_app, oauth2_secured
from rfc6749.oauth2_errors import OAuth2Error, error
from rfc6749.Tokens import AccessToken
from namespace_models.User import User
from namespace_utils.bottle_helpers import from_params_or_json

user_api = Bottle(catchall=False, autojson=True)
user_api.merge(oauth2_app)

__version__ = '0.0.1'


@user_api.hook('after_request')
def enable_cors():
response.headers['Access-Control-Allow-Origin'] = '*'


@oauth2_secured()
@user_api.route('/api/v1/user')
@user_api.route('/api/v1/user/<email>')
def profile(email=None):
if email:
# TODO: RBAC here
if email != AccessToken().email_from_token(from_params_or_json(request, 'access_token')):
return error(response, 'access_denied', 'You cannot access another user\'s profile')
else:
email = AccessToken().email_from_token(from_params_or_json(request, 'access_token'))

try:
return {'user': User.objects(email=email).first().email}
except (ValidationError, NotUniqueError) as e:
return error(response, 'server_error', e.message)
except OAuth2Error as e:
message = dict(e.message)
response.status = message.pop('status_code')
return message


if __name__ == '__main__':
user_api.run(host='0.0.0.0', port=5555, debug=True)
6 changes: 6 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
bottle
webtest
mongoengine
git+https://github.com/ng-bottle-libraries/utils#egg=namespace_utils
git+https://github.com/ng-bottle-libraries/oauth2-rfc6749#egg=rfc6749
git+https://github.com/ng-bottle-libraries/models#egg=namespace_models
7 changes: 7 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from setuptools import setup
from namespace_user_api import __version__

if __name__ == '__main__':
setup(name='namespace_user_api', version=__version__,
author='Samuel Marks', license='MIT', py_modules=['namespace_user_api'],
test_suite='tests')
43 changes: 43 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from unittest import TestCase, main as unittest_main

from webtest import TestApp
from namespace_utils import test_funs as test

from namespace_user_api import oauth2_app as oauth2_bottle_app, user_api


class TestUserApi(TestCase):
app = TestApp(user_api)
oauth2_app = TestApp(oauth2_bottle_app)
users = ({'email': '[email protected]', 'password': 'bar'},
{'email': '[email protected]', 'password': 'haz'},
{'email': '[email protected]', 'password': 'can'})
access_token = ''

@classmethod
def setUpClass(cls):
register_or_login_resp = cls.oauth2_app.put('/api/oauth2/register_or_login', cls.users[0])
test.assertEqual(register_or_login_resp.content_type, 'application/json')
test.assertEqual(register_or_login_resp.status_code, 200)
test.assertIn('access_token', register_or_login_resp.json)
test.assertIn('expires_in', register_or_login_resp.json)
cls.access_token = register_or_login_resp.json['access_token']

def test_get_profile_failure(self):
k = 'access_token'
self.assertNotEqual(self.app.get('/api/v1/user', {k: getattr(TestUserApi, k)}).json,
{'user': self.users[1]['email']})

def test_get_profile_success(self):
k = 'access_token'
self.assertEqual(self.app.get('/api/v1/user', {k: getattr(TestUserApi, k)}).json,
{'user': self.users[0]['email']})

@classmethod
def tearDownClass(cls):
unregister_resp = cls.oauth2_app.delete('/api/oauth2/unregister', params=cls.users[0])
test.assertEqual(got=unregister_resp.content_type, expect=None)


if __name__ == '__main__':
unittest_main()

0 comments on commit 2d0910a

Please sign in to comment.