Created
February 11, 2014 21:21
-
-
Save jproby/8944448 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# API authentication | |
from social.apps.django_app.utils import strategy | |
from rest_framework.authtoken.models import Token | |
from rest_framework.views import APIView | |
from rest_framework import parsers | |
from rest_framework import renderers | |
from rest_framework.authentication import get_authorization_header | |
from rest_framework.response import Response | |
from rest_framework import status | |
from rest_framework.authtoken.serializers import AuthTokenSerializer | |
@strategy() | |
def register_by_access_token(request, backend): | |
backend = request.strategy.backend | |
# Split by spaces and get the array | |
auth = get_authorization_header(request).split() | |
if not auth or auth[0].lower() != b'token': | |
msg = 'No token header provided.' | |
return msg | |
if len(auth) == 1: | |
msg = 'Invalid token header. No credentials provided.' | |
return msg | |
access_token = auth[1] | |
user = backend.do_auth(access_token) | |
return user | |
# Pour une vraie integration au rest framework | |
class ObtainAuthToken(APIView): | |
throttle_classes = () | |
permission_classes = () | |
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) | |
renderer_classes = (renderers.JSONRenderer,) | |
serializer_class = AuthTokenSerializer | |
model = Token | |
# Accepte un backend en parametre : 'auth' pour un login / pass classique | |
def post(self, request, backend): | |
serializer = self.serializer_class(data=request.DATA) | |
if backend == 'auth': | |
if serializer.is_valid(): | |
token, created = Token.objects.get_or_create(user=serializer.object['user']) | |
return Response({'token': token.key}) | |
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) | |
else: | |
user = register_by_access_token(request, backend) | |
if user and user.is_active: | |
token, created = Token.objects.get_or_create(user=user) | |
return Response({'id': user.id, 'name': user.username, 'firstname': user.first_name, 'userRole': 'user', 'token': token.key}) | |
class ObtainUser(APIView): | |
throttle_classes = () | |
permission_classes = () | |
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) | |
renderer_classes = (renderers.JSONRenderer,) | |
serializer_class = AuthTokenSerializer | |
model = Token | |
# Renvoi le user si le token est valide | |
def get(self, request): | |
serializer = self.serializer_class(data=request.DATA) | |
if request.META.get('HTTP_AUTHORIZATION'): | |
auth = request.META.get('HTTP_AUTHORIZATION').split() | |
if not auth or auth[0].lower() != b'token' or len(auth) != 2: | |
msg = 'Invalid token header. No credentials provided.' | |
return Response(msg, status=status.HTTP_401_UNAUTHORIZED) | |
token = Token.objects.get(key=auth[1]) | |
if token and token.user.is_active: | |
return Response({'id': token.user_id, 'name': token.user.username, 'firstname': token.user.first_name, 'userRole': 'user', 'token': token.key}) | |
else: | |
return Response(serializer.errors, status=status.HTTP_401_UNAUTHORIZED) | |
class ObtainLogout(APIView): | |
throttle_classes = () | |
permission_classes = () | |
parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) | |
renderer_classes = (renderers.JSONRenderer,) | |
serializer_class = AuthTokenSerializer | |
model = Token | |
# Logout le user | |
def get(self, request): | |
return Response({'User': ''}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('myApp', [ | |
// login service | |
'loginService', | |
// components | |
'ngAnimate', | |
'restangular' | |
]) | |
.config(function ($urlRouterProvider, RestangularProvider) { | |
RestangularProvider.setBaseUrl('http://127.0.0.1:8000/api'); | |
RestangularProvider.setRequestSuffix('/'); | |
$urlRouterProvider.otherwise('/discover'); | |
}) | |
.run(function ($rootScope) { | |
/** | |
* $rootScope.doingResolve is a flag useful to display a spinner on changing states. | |
* Some states may require remote data so it will take awhile to load. | |
*/ | |
var resolveDone = function () { $rootScope.doingResolve = false; }; | |
$rootScope.doingResolve = false; | |
$rootScope.$on('$stateChangeStart', function () { | |
$rootScope.doingResolve = true; | |
}); | |
$rootScope.$on('$stateChangeSuccess', resolveDone); | |
$rootScope.$on('$stateChangeError', resolveDone); | |
$rootScope.$on('$permissionError', resolveDone); | |
}) | |
.controller('AppCtrl', function ($scope, $state, $stateParams, loginService, $http) { | |
// Expose $state and $stateParams to the <body> tag | |
$scope.$state = $state; | |
$scope.$stateParams = $stateParams; | |
// loginService exposed and a new Object containing login user/pwd | |
$scope.ls = loginService; | |
$scope.login = { | |
working: false | |
}; | |
$scope.loginBK = function (backend) { | |
if (backend == 'facebook') { | |
OAuth.popup('facebook', function(error, success) { | |
if (error) { | |
} | |
else { | |
var token = "Token " + success.access_token | |
var loginPromise = $http({method:'POST', url: 'http://127.0.0.1:8000/api-token/login/' + backend + '/', headers: {'Authorization': token}}); | |
$scope.login.working = true; | |
loginService.loginUser(loginPromise); | |
loginPromise.success(function () { | |
$scope.login = { working: false }; | |
}); | |
loginPromise.finally(function () { | |
$scope.login.working = false; | |
}); | |
} | |
}); | |
} | |
}; | |
$scope.logoutMe = function () { | |
loginService.logoutUser($http.get('http://127.0.0.1:8000/api-token/logout')); | |
}; | |
// Changement du dynamique du titre | |
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ | |
if ( angular.isDefined( toState.data.pageTitle ) ) { | |
$scope.pageTitle = toState.data.pageTitle + ' | Welcome' ; | |
} | |
}); | |
// initilization de oauth.io | |
OAuth.initialize('your oauth.io key'); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: UTF-8 -*- | |
"""Common settings and globals.""" | |
from os.path import abspath, basename, dirname, join, normpath | |
from sys import path | |
from django.utils.translation import gettext_lazy as _ | |
########## PATH CONFIGURATION | |
# Absolute filesystem path to the Django project directory: | |
DJANGO_ROOT = dirname(dirname(abspath(__file__))) | |
# Absolute filesystem path to the top-level project folder: | |
SITE_ROOT = dirname(DJANGO_ROOT) | |
# Site name: | |
SITE_NAME = basename(DJANGO_ROOT) | |
# Add our project to our pythonpath, this way we don't need to type our project | |
# name in our dotted import paths: | |
path.append(DJANGO_ROOT) | |
########## END PATH CONFIGURATION | |
########## DEBUG CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#debug | |
DEBUG = False | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-debug | |
TEMPLATE_DEBUG = DEBUG | |
########## END DEBUG CONFIGURATION | |
########## MANAGER CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#admins | |
ADMINS = ( | |
('Your Name', '[email protected]'), | |
) | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#managers | |
MANAGERS = ADMINS | |
########## END MANAGER CONFIGURATION | |
########## DATABASE CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#databases | |
DATABASES = { | |
'default': { | |
'ENGINE': 'django.db.backends.', | |
'NAME': '', | |
'USER': '', | |
'PASSWORD': '', | |
'HOST': '', | |
'PORT': '', | |
} | |
} | |
########## END DATABASE CONFIGURATION | |
########## GENERAL CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#time-zone | |
TIME_ZONE = 'Europe/Paris' | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#language-code | |
LANGUAGE_CODE = 'fr' | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id | |
SITE_ID = 1 | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-i18n | |
USE_I18N = True | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-l10n | |
USE_L10N = True | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#use-tz | |
USE_TZ = True | |
LANGUAGES = ( | |
('fr', _('Français')), | |
('en', _('Anglais')), | |
) | |
DEFAULT_LANGUAGE = 1 | |
########## END GENERAL CONFIGURATION | |
########## MEDIA CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-root | |
MEDIA_ROOT = normpath(join(SITE_ROOT, 'media')) | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#media-url | |
MEDIA_URL = '/media/' | |
########## END MEDIA CONFIGURATION | |
########## STATIC FILE CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-root | |
STATIC_ROOT = normpath(join(SITE_ROOT, 'assets')) | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#static-url | |
STATIC_URL = '/static/' | |
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:setting-STATICFILES_DIRS | |
STATICFILES_DIRS = ( | |
normpath(join(SITE_ROOT, 'static')), | |
) | |
# See: https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#staticfiles-finders | |
STATICFILES_FINDERS = ( | |
'django.contrib.staticfiles.finders.FileSystemFinder', | |
'django.contrib.staticfiles.finders.AppDirectoriesFinder', | |
) | |
########## END STATIC FILE CONFIGURATION | |
########## SECRET CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#secret-key | |
# Note: This key only used for development and testing. | |
SECRET_KEY = r"secret" | |
########## END SECRET CONFIGURATION | |
########## FIXTURE CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-FIXTURE_DIRS | |
FIXTURE_DIRS = ( | |
normpath(join(SITE_ROOT, 'fixtures')), | |
) | |
########## END FIXTURE CONFIGURATION | |
########## TEMPLATE CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-context-processors | |
TEMPLATE_CONTEXT_PROCESSORS = ( | |
'django.contrib.auth.context_processors.auth', | |
'django.core.context_processors.debug', | |
'django.core.context_processors.i18n', | |
'django.core.context_processors.media', | |
'django.core.context_processors.static', | |
'django.core.context_processors.tz', | |
'django.contrib.messages.context_processors.messages', | |
'django.core.context_processors.request', | |
'social.apps.django_app.context_processors.backends', | |
'social.apps.django_app.context_processors.login_redirect', | |
'account.context_processors.account', | |
) | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-loaders | |
TEMPLATE_LOADERS = ( | |
'django.template.loaders.filesystem.Loader', | |
'django.template.loaders.app_directories.Loader', | |
) | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#template-dirs | |
TEMPLATE_DIRS = ( | |
normpath(join(SITE_ROOT, 'templates')), | |
) | |
########## END TEMPLATE CONFIGURATION | |
########## MIDDLEWARE CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#middleware-classes | |
MIDDLEWARE_CLASSES = ( | |
# Default Django middleware. | |
'django.middleware.common.CommonMiddleware', | |
'django.contrib.sessions.middleware.SessionMiddleware', | |
'django.middleware.csrf.CsrfViewMiddleware', | |
'django.contrib.auth.middleware.AuthenticationMiddleware', | |
'django.contrib.messages.middleware.MessageMiddleware', | |
'django.middleware.locale.LocaleMiddleware', | |
'corsheaders.middleware.CorsMiddleware', | |
'social.apps.django_app.middleware.SocialAuthExceptionMiddleware', | |
"account.middleware.TimezoneMiddleware" | |
) | |
########## END MIDDLEWARE CONFIGURATION | |
########## URL CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#root-urlconf | |
ROOT_URLCONF = '%s.urls' % SITE_NAME | |
########## END URL CONFIGURATION | |
########## APP CONFIGURATION | |
INSTALLED_APPS = ( | |
# Default Django apps: | |
'django.contrib.auth', | |
'django.contrib.contenttypes', | |
'django.contrib.sessions', | |
'django.contrib.sites', | |
'django.contrib.messages', | |
'django.contrib.staticfiles', | |
'django.contrib.comments', | |
# Useful template tags: | |
# 'django.contrib.humanize', | |
# Admin panel and documentation: | |
'django.contrib.admin', | |
# 3rd party direct social auth | |
'social.apps.django_app.default', | |
#'pinax_theme_bootstrap_account', | |
#'pinax_theme_bootstrap', | |
# Users Account | |
'account', | |
'avatar', | |
# rest framework et oauth for rest API | |
#'provider', | |
#'provider.oauth2', | |
'rest_framework', | |
'rest_framework.authtoken', | |
'corsheaders', | |
# data storage and db utils | |
'south', 'storages', | |
# External apps | |
'qhonuskan_votes', 'taggit', | |
) | |
# INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS | |
########## END APP CONFIGURATION | |
########## LOGGING CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#logging | |
# A sample logging configuration. The only tangible logging | |
# performed by this configuration is to send an email to | |
# the site admins on every HTTP 500 error when DEBUG=False. | |
# See http://docs.djangoproject.com/en/dev/topics/logging for | |
# more details on how to customize your logging configuration. | |
LOGGING = { | |
'version': 1, | |
'disable_existing_loggers': False, | |
'filters': { | |
'require_debug_false': { | |
'()': 'django.utils.log.RequireDebugFalse' | |
} | |
}, | |
'handlers': { | |
'mail_admins': { | |
'level': 'ERROR', | |
'filters': ['require_debug_false'], | |
'class': 'django.utils.log.AdminEmailHandler' | |
} | |
}, | |
'loggers': { | |
'django.request': { | |
'handlers': ['mail_admins'], | |
'level': 'ERROR', | |
'propagate': True, | |
}, | |
} | |
} | |
########## END LOGGING CONFIGURATION | |
########## REST CONF | |
REST_FRAMEWORK = { | |
# Use hyperlinked styles by default. | |
# Only used if the `serializer_class` attribute is not set on a view. | |
'DEFAULT_MODEL_SERIALIZER_CLASS': | |
'rest_framework.serializers.HyperlinkedModelSerializer', | |
# Use Django's standard `django.contrib.auth` permissions, | |
# or allow read-only access for unauthenticated users. | |
'DEFAULT_PERMISSION_CLASSES': [ | |
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' | |
] | |
} | |
########## END REST CONF | |
########## WSGI CONFIGURATION | |
# See: https://docs.djangoproject.com/en/dev/ref/settings/#wsgi-application | |
WSGI_APPLICATION = 'wsgi.application' | |
########## END WSGI CONFIGURATION | |
########## Auth | |
AUTHENTICATION_BACKENDS = ( | |
'social.backends.google.GoogleOAuth2', | |
'social.backends.twitter.TwitterOAuth', | |
'social.backends.facebook.FacebookOAuth2', | |
'django.contrib.auth.backends.ModelBackend' | |
) | |
ACCOUNT_EMAIL_UNIQUE = True | |
ACCOUNT_EMAIL_CONFIRMATION_REQUIRED = True | |
SOCIAL_AUTH_PIPELINE = ( | |
'social.pipeline.social_auth.social_details', | |
'social.pipeline.social_auth.social_uid', | |
'social.pipeline.social_auth.auth_allowed', | |
'social.pipeline.social_auth.social_user', | |
'social.pipeline.user.get_username', | |
'social.pipeline.social_auth.associate_by_email', | |
'social.pipeline.user.create_user', | |
'social.pipeline.social_auth.associate_user', | |
'social.pipeline.social_auth.load_extra_data', | |
'social.pipeline.user.user_details' | |
) | |
CORS_ORIGIN_ALLOW_ALL = True | |
#CORS_URLS_REGEX = r'^/api/.*$' | |
#CORS_ALLOW_HEADERS = ( | |
# 'x-requested-with', | |
# 'content-type', | |
# 'accept', | |
# 'origin', | |
# 'authorization', | |
# 'x-csrftoken', | |
# 'x-token' | |
# ) | |
SOCIAL_AUTH_FACEBOOK_KEY = 'your_key_here' | |
SOCIAL_AUTH_FACEBOOK_SECRET = 'your_secret_here' | |
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email', 'user_about_me', 'user_birthday', 'user_location'] | |
########## End Auth |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
angular.module('loginService', []) | |
.provider('loginService', function () { | |
var userToken = localStorage.getItem('userToken'), | |
errorState = 'app.error', | |
logoutState = 'app.discover'; | |
this.$get = function ($rootScope, $http, $q, $state, Restangular) { | |
/** | |
* Low-level, private functions. | |
*/ | |
var setHeaders = function (token) { | |
if (!token) { | |
delete $http.defaults.headers.common['X-Token']; | |
return; | |
} | |
$http.defaults.headers.common['authorization'] = 'Token ' + token.toString(); | |
Restangular.setDefaultHeaders({'authorization': 'Token ' + token.toString()}); | |
}; | |
var setToken = function (token) { | |
if (!token) { | |
localStorage.removeItem('userToken'); | |
} else { | |
localStorage.setItem('userToken', token); | |
} | |
setHeaders(token); | |
}; | |
var getLoginData = function () { | |
if (userToken) { | |
setHeaders(userToken); | |
} else { | |
wrappedService.userRole = userRoles.public; | |
wrappedService.isLogged = false; | |
wrappedService.doneLoading = true; | |
} | |
}; | |
var managePermissions = function () { | |
// Register routing function. | |
$rootScope.$on('$stateChangeStart', function (event, to, toParams, from, fromParams) { | |
/** | |
* $stateChangeStart is a synchronous check to the accessLevels property | |
* if it's not set, it will setup a pendingStateChange and will let | |
* the grandfather resolve do his job. | |
* | |
* In short: | |
* If accessLevels is still undefined, it let the user change the state. | |
* Grandfather.resolve will either let the user in or reject the promise later! | |
*/ | |
if (wrappedService.userRole === null) { | |
wrappedService.doneLoading = false; | |
wrappedService.pendingStateChange = { | |
to: to, | |
toParams: toParams | |
}; | |
return; | |
} | |
// if the state has undefined accessLevel, anyone can access it. | |
// NOTE: if `wrappedService.userRole === undefined` means the service still doesn't know the user role, | |
// we need to rely on grandfather resolve, so we let the stateChange success, for now. | |
if (to.accessLevel === undefined || to.accessLevel.bitMask & wrappedService.userRole.bitMask) { | |
angular.noop(); // requested state can be transitioned to. | |
} else { | |
event.preventDefault(); | |
// test this | |
$state.go(errorState, { error: 'unauthorized' }, { location: false, inherit: false }); | |
$rootScope.$emit('$permissionError'); | |
} | |
}); | |
// Gets triggered when a resolve isn't fulfilled | |
// da aggiungere un caso in cui il resolve da informazioni solo ad un admin e non ad un user | |
// quindi un url ad esempio /resource/admin | |
// anche un url /resource/user | |
// in questo modo si potrà vedere l'error redirect! | |
// anche un caso in cui sono io che faccio fallire una $q cosi si vede l'errore stringa! | |
$rootScope.$on('$stateChangeError', function (event, to, toParams, from, fromParams, error) { | |
/** | |
* This is a very clever way to implement failure redirection. | |
* You can use the value of redirectMap, based on the value of the rejection | |
* So you can setup DIFFERENT redirections based on different promise errors. | |
*/ | |
var errorObj, redirectObj; | |
// in case the promise given to resolve function is an $http request | |
// the error is a object containing the error and additional informations | |
error = (typeof error === 'object') ? error.status.toString() : error; | |
// in case of a random 4xx/5xx status code from server, user gets loggedout | |
// otherwise it *might* forever loop (look call diagram) | |
if (/^[45]\d{2}$/.test(error)) { | |
wrappedService.logoutUser(); | |
} | |
/** | |
* Generic redirect handling. | |
* If a state transition has been prevented and it's not one of the 2 above errors, means it's a | |
* custom error in your application. | |
* | |
* redirectMap should be defined in the $state(s) that can generate transition errors. | |
*/ | |
if (angular.isDefined(to.redirectMap) && angular.isDefined(to.redirectMap[error])) { | |
if (typeof to.redirectMap[error] === 'string') { | |
return $state.go(to.redirectMap[error], { error: error }, { location: false, inherit: false }); | |
} else if (typeof to.redirectMap[error] === 'object') { | |
redirectObj = to.redirectMap[error]; | |
return $state.go(redirectObj.state, { error: redirectObj.prefix + error }, { location: false, inherit: false }); | |
} | |
} | |
return $state.go(errorState, { error: error }, { location: false, inherit: false }); | |
}); | |
}; | |
/** | |
* High level, public methods | |
*/ | |
var wrappedService = { | |
loginHandler: function (user, status, headers, config) { | |
/** | |
* Custom logic to manually set userRole goes here | |
* | |
* Commented example shows an userObj coming with a 'completed' | |
* property defining if the user has completed his registration process, | |
* validating his/her email or not. | |
* | |
* EXAMPLE: | |
* if (user.hasValidatedEmail) { | |
* wrappedService.userRole = userRoles.registered; | |
* } else { | |
* wrappedService.userRole = userRoles.invalidEmail; | |
* $state.go('app.nagscreen'); | |
* } | |
*/ | |
// setup token | |
setToken(user.token); | |
// update user | |
angular.extend(wrappedService.user, user); | |
// flag true on isLogged | |
wrappedService.isLogged = true; | |
// update userRole | |
wrappedService.userRole = userRoles[user.userRole]; | |
return user; | |
}, | |
loginUser: function (httpPromise) { | |
httpPromise.success(this.loginHandler); | |
}, | |
logoutUser: function (httpPromise) { | |
/** | |
* De-registers the userToken remotely | |
* then clears the loginService as it was on startup | |
*/ | |
setToken(null); | |
this.userRole = userRoles.public; | |
this.user = {}; | |
this.isLogged = false; | |
$state.go(logoutState); | |
}, | |
resolvePendingState: function (httpPromise) { | |
var checkUser = $q.defer(), | |
self = this, | |
pendingState = self.pendingStateChange; | |
// When the $http is done, we register the http result into loginHandler, `data` parameter goes into loginService.loginHandler | |
httpPromise.success(self.loginHandler); | |
httpPromise.then( | |
function success(httpObj) { | |
self.doneLoading = true; | |
// duplicated logic from $stateChangeStart, slightly different, now we surely have the userRole informations. | |
if (pendingState.to.accessLevel === undefined || pendingState.to.accessLevel.bitMask & self.userRole.bitMask) { | |
checkUser.resolve(); | |
} else { | |
checkUser.reject('unauthorized'); | |
} | |
}, | |
function reject(httpObj) { | |
checkUser.reject(httpObj.status.toString()); | |
} | |
); | |
/** | |
* I setted up the state change inside the promises success/error, | |
* so i can safely assign pendingStateChange back to null. | |
*/ | |
self.pendingStateChange = null; | |
return checkUser.promise; | |
}, | |
/** | |
* Public properties | |
*/ | |
userRole: null, | |
user: {}, | |
isLogged: null, | |
pendingStateChange: null, | |
doneLoading: null | |
}; | |
getLoginData(); | |
managePermissions(); | |
return wrappedService; | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.conf.urls import patterns, include, url | |
from django.views.generic import TemplateView | |
from rest_framework import routers | |
from api import QuestViewSet, TargetViewSet, IdeaViewSet, UserViewSet, GroupViewSet, WItemViewSet, UProductViewSet, ReviewPointViewSet | |
from apiauth import ObtainAuthToken, ObtainUser, ObtainLogout | |
# Uncomment the next two lines to enable the admin: | |
from django.contrib import admin | |
admin.autodiscover() | |
# Routers provide an easy way of automatically determining the URL conf | |
router = routers.DefaultRouter() | |
router.register(r'quests', QuestViewSet) | |
router.register(r'ideas', IdeaViewSet) | |
router.register(r'witems', WItemViewSet) | |
router.register(r'reviews', ReviewPointViewSet) | |
router.register(r'users', UserViewSet) | |
router.register(r'groups', GroupViewSet) | |
router.register(r'targets', TargetViewSet) | |
urlpatterns = patterns('', | |
url(r'^$', TemplateView.as_view(template_name='base.html')), | |
# API URLs | |
url(r'^api/', include(router.urls)), | |
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), | |
# Uncomment the admin/doc line below to enable admin documentation: | |
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')), | |
# Uncomment the next line to enable the admin: | |
url(r'^admin/', include(admin.site.urls)), | |
url('', include('social.apps.django_app.urls', namespace='social')), | |
url(r"^account/", include("account.urls")), | |
url(r'^api-token/login/(?P<backend>[^/]+)/$', ObtainAuthToken.as_view()), | |
url(r'^api-token/user/', ObtainUser.as_view()), | |
url(r'^api-token/logout/', ObtainLogout.as_view()) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment