Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
tiberiuichim committed Feb 25, 2017
0 parents commit a28c4a3
Show file tree
Hide file tree
Showing 24 changed files with 689 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[run]
source = jwtlogin
omit = jwtlogin/test*
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
jwtlogin/static/node_modules/*
*.pyc
*~
__pycache__
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 jwtlogin *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Facebook + Pyramid JWT minimal demo

This is a minimal tech demo showing how to exchange a Facebook user access
token (generated from a Facebook login) for a JWT token that can be used to
authenticate against Pyramid apps.

Getting Started
---------------

- cd <directory containing this file>

- Run ./install.sh

You need to have virtualenv installed on your system. If you don't have it,
look at the ``make_virtualenv.sh`` script in this folder, then adjust
install.sh

Register your Facebook app
---------------------------

You need to register for a new Facebook app, at https://developer.facebook.com
Enter your appid in the development.ini file.
68 changes: 68 additions & 0 deletions development.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
###
# app configuration
# http://docs.pylonsproject.org/projects/pyramid/en/1.8-branch/narr/environment.html
###

[app:main]
use = egg:jwtlogin

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

jwt.private_key = my_secret_private_key
jwt.public_key = my_secret_private_key
jwt.algorithm = HS512
# 60 seconds expiration time
jwt.expiration = 5
jwt.http_header = Authorization
facebook.appid = 11111111111111

# By default, the toolbar only appears for clients from IP addresses
# '127.0.0.1' and '::1'.
# debugtoolbar.hosts = 127.0.0.1 ::1

###
# wsgi server configuration
###

[server:main]
use = egg:waitress#main
listen = 127.0.0.1:6543 [::1]:6543

###
# logging configuration
# http://docs.pylonsproject.org/projects/pyramid/en/1.8-branch/narr/logging.html
###

[loggers]
keys = root, jwtlogin

[handlers]
keys = console

[formatters]
keys = generic

[logger_root]
level = INFO
handlers = console

[logger_jwtlogin]
level = DEBUG
handlers =
qualname = jwtlogin

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

[formatter_generic]
format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
6 changes: 6 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/sh

virtualenv .
bin/pip install -r requirements.txt
bin/pip install -e .
npm install --prefix=jwtlogin/static/
46 changes: 46 additions & 0 deletions jwtlogin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from pyramid.config import Configurator
from pyramid.interfaces import IAuthorizationPolicy
from zope.interface import implementer
import logging

logger = logging.getLogger('jwtlogin')


@implementer(IAuthorizationPolicy)
class CustomAuthorizationPolicy(object):

def permits(self, context, principals, permission):
""" Return ``True`` if any of the ``principals`` is allowed the
``permission`` in the current ``context``, else return ``False``
"""
if 'system.Authenticated' in principals:
logger.info("Hello %r", principals)
return True

def principals_allowed_by_permission(self, context, permission):
""" Return a set of principal identifiers allowed by the
``permission`` in ``context``. This behavior is optional; if you
choose to not implement it you should define this method as
something which raises a ``NotImplementedError``. This method
will only be called when the
``pyramid.security.principals_allowed_by_permission`` API is
used."""
raise NotImplementedError


def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(settings=settings)

# Pyramid requires an authorization policy to be active.
config.set_authorization_policy(CustomAuthorizationPolicy())
config.include('pyramid_jwt') # Enable JWT authentication.
config.set_jwt_authentication_policy('secret')

config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.add_route('check-token', '/check_token')
config.add_route('something-protected', '/something-protected')
config.scan()
return config.make_wsgi_app()
9 changes: 9 additions & 0 deletions jwtlogin/events.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from pyramid.renderers import get_renderer
from pyramid.interfaces import IBeforeRender
from pyramid.events import subscriber


@subscriber(IBeforeRender)
def globals_factory(event):
master = get_renderer('templates/master.pt').implementation()
event['master'] = master
75 changes: 75 additions & 0 deletions jwtlogin/static/login.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// This is called with the results from from FB.getLoginStatus().
function statusChangeCallback(response) {
console.log('statusChangeCallback', response);
if (response.status === 'connected') {
login(response);
} else if (response.status === 'not_authorized') {
alert('Please log into this app');
} else {
alert('Please log into Facebook');
}
}


function getProtectedPage(token) {
var settings = {
url: '/something-protected',
headers: {
'Authorization': 'JWT ' + token
},
};
$.ajax(settings).then(function(resp){
$("#protected").html(resp)
}).catch(function(err){
console.log(err);
$("#protected").html('There was an error: <br/>' + err.responseText);
});
}


function login(response){
var userId = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
$.post('/login',
{access_token: accessToken, user_id: userId},
function(resp) {
if (resp.result === 'ok') {
$('#check_jwt textarea').html(resp.token);
$('#login-button').hide();
$('#restricted').attr('disabled', false).click(function(event){
event.stopPropagation();
getProtectedPage(resp.token);
return false;
});
} else {
alert('Bad response from backend');
}
}
)
}

// This function is called when someone finishes with the Login
// Button. See the onlogin handler attached to it in the sample
// code below.
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}

$(document).ready(function(){

$.getScript('//connect.facebook.net/en_US/sdk.js', function(){
FB.init({
appId: appid,
version: 'v2.7' // or v2.1, v2.2, v2.3, ...
});
$('#loginbutton,#feedbutton').removeAttr('disabled');
FB.getLoginStatus(statusChangeCallback);
});

$('#login-button').click(function(){
FB.login(statusChangeCallback, {scope: 'public_profile,email'});
return false;
});
});
14 changes: 14 additions & 0 deletions jwtlogin/static/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "hello_test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"css-social-buttons": "^1.1.1"
}
}
Binary file added jwtlogin/static/pyramid-16x16.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 jwtlogin/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.
Loading

0 comments on commit a28c4a3

Please sign in to comment.