users registration

This commit is contained in:
Davide Alberani 2016-06-12 23:44:48 +02:00
parent 7549accecd
commit 42ad0756de
5 changed files with 110 additions and 26 deletions

22
angular_app/js/app.js vendored
View file

@ -35,7 +35,7 @@ eventManApp.run(['$rootScope', '$state', '$stateParams', '$log', 'Info',
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.error = {error: false};
$rootScope.error = {error: false, message: '', code: 0};
$rootScope.readInfo = function(callback) {
Info.get({}, function(data) {
@ -46,19 +46,27 @@ eventManApp.run(['$rootScope', '$state', '$stateParams', '$log', 'Info',
});
};
$rootScope.showError = function(error) {
$rootScope.error.code = error.code;
$rootScope.error.message = error.message;
$rootScope.error.error = true;
};
$rootScope.clearError = function() {
$rootScope.error.code = null;
$rootScope.error.message = '';
$rootScope.error.error = false;
};
$rootScope.errorHandler = function(response) {
$log.debug('Handling error message:');
$log.debug(response);
$rootScope.error.status = response.status;
$rootScope.error.statusText = response.statusText;
if (response.data && response.data.error) {
$rootScope.error.code = response.data.code;
$rootScope.error.message = response.data.message;
$rootScope.error.error = true;
$rootScope.showError(response.data);
} else {
$rootScope.error.code = null;
$rootScope.error.message = '';
$rootScope.error.error = false;
$rootScope.clearError();
}
};

View file

@ -542,10 +542,20 @@ eventManControllers.controller('LoginCtrl', ['$scope', '$rootScope', '$state', '
function ($scope, $rootScope, $state, $log, User) {
$scope.loginData = {};
$scope.login = function() {
User.login($scope.loginData, function(data) {
$scope.register = function() {
User.add($scope.newUser, function(data) {
$scope.login($scope.newUser);
});
};
$scope.login = function(loginData) {
if (!loginData) {
loginData = $scope.loginData;
}
User.login(loginData, function(data) {
if (!data.error) {
$rootScope.readInfo(function() {
$rootScope.clearError();
$state.go('events');
});
}

View file

@ -253,6 +253,11 @@ eventManServices.factory('User', ['$resource', '$rootScope',
}
},
add: {
method: 'POST',
interceptor : {responseError: $rootScope.errorHandler}
},
login: {
method: 'POST',
url: '/login',

View file

@ -1,22 +1,44 @@
<!-- Login and user registration page. -->
<div class="container">
<div class="panel panel-primary table-striped top5">
<div class="panel-heading">{{'Login' | translate}}</div>
<div class="panel-body">
<div id="wronglogin" class="alert alert-danger alert-dismissible hidden" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<strong>{{'Error!' | translate}}</strong> {{'Wrong username and password.' | translate}}
<div class="row">
<div class="col-md-7 col-xs-7">
<div class="panel panel-primary table-striped">
<div class="panel-heading">{{'Login' | translate}}</div>
<div class="panel-body">
<form method="POST">
<div class="input-group input-group-lg">
<span class="input-group-addon min150">{{'Username' | translate}}</span>
<input type="text" id="username" name="username" ng-model="loginData.username" class="form-control">
</div>
<div class="input-group input-group-lg top10">
<span class="input-group-addon min150">{{'Password' | translate}}</span>
<input type="password" id="password" name="password" ng-model="loginData.password" class="form-control">
</div>
<button type="submit" ng-click="login()" class="btn btn-success top10">{{'login' | translate}}</button>
</form>
</div>
</div>
<form method="POST">
<div class="input-group input-group-lg">
<span class="input-group-addon min150">{{'Username' | translate}}</span>
<input type="text" id="username" name="username" ng-model="loginData.username" class="form-control" placeholder="admin">
</div>
<div class="col-md-1 col-xs-1 hcenter" style="top:100px;">
<div class="vcenter">or</div>
</div>
<div class="col-md-4 col-xs-4">
<div class="panel panel-success table-striped">
<div class="panel-heading">{{'Register a new user' | translate}}</div>
<div class="panel-body">
<form method="POST">
<div class="input-group input-group-lg">
<span class="input-group-addon min150">{{'Username' | translate}}</span>
<input type="text" id="username" name="username" ng-model="newUser.username" class="form-control">
</div>
<div class="input-group input-group-lg top10">
<span class="input-group-addon min150">{{'Password' | translate}}</span>
<input type="password" id="password" name="password" ng-model="newUser.password" class="form-control">
</div>
<button type="submit" ng-click="register()" class="btn btn-success top10">{{'register' | translate}}</button>
</form>
</div>
<div class="input-group input-group-lg top10">
<span class="input-group-addon min150">{{'Password' | translate}}</span>
<input type="password" id="password" name="password" ng-model="loginData.password" class="form-control" placeholder="eventman">
</div>
<button type="submit" ng-click="login()" class="btn btn-success top10">{{'login' | translate}}</button>
</form>
</div>
</div>
</div>
</div>

View file

@ -63,6 +63,24 @@ def authenticated(method):
return my_wrapper
class BaseException(Exception):
"""Base class for EventMan custom exceptions.
:param message: text message
:type message: str
:param status: numeric http status code
:type status: int"""
def __init__(self, message, status=400):
super(BaseException, self).__init__(message)
self.message = message
self.status = status
class InputException(BaseException):
"""Exception raised by errors in input handling."""
pass
class BaseHandler(tornado.web.RequestHandler):
"""Base class for request handlers."""
permissions = {
@ -70,7 +88,8 @@ class BaseHandler(tornado.web.RequestHandler):
'event:tickets|all': True,
'event:tickets-all|create': True,
'events|read': True,
'persons|create': True
'persons|create': True,
'users|create': True
}
# A property to access the first value of each argument.
@ -102,6 +121,16 @@ class BaseHandler(tornado.web.RequestHandler):
'true': True
}
def write_error(self, status_code, **kwargs):
"""Default error handler."""
if isinstance(kwargs.get('exc_info', (None, None))[1], BaseException):
exc = kwargs['exc_info'][1]
status_code = exc.status
message = exc.message
else:
message = 'internal error'
self.build_error(message, status=status_code)
def is_api(self):
"""Return True if the path is from an API call."""
return self.request.path.startswith('/v%s' % API_VERSION)
@ -667,6 +696,16 @@ class UsersHandler(CollectionHandler):
document = 'user'
collection = 'users'
def filter_input_post_all(self, data):
username = (data.get('username') or '').strip()
password = (data.get('password') or '').strip()
if not (username and password):
raise InputException('missing username or password')
res = self.db.query('users', {'username': username})
if res:
raise InputException('username already exists')
return {'username': username, 'password': utils.hash_password(password)}
class EbCSVImportPersonsHandler(BaseHandler):
"""Importer for CSV files exported from eventbrite."""