Skip to content
Snippets Groups Projects
Commit 27bf5c4d authored by Allen Gilliland's avatar Allen Gilliland
Browse files

updating login page to work with our new form validation approach. made a few...

updating login page to work with our new form validation approach.  made a few tweaks to session api to ensure well formed 400 http responses.
parent f25ce79b
No related branches found
No related tags found
No related merge requests found
......@@ -10,52 +10,59 @@ var AuthControllers = angular.module('corvus.auth.controllers', [
'metabase.forms'
]);
AuthControllers.controller('Login', ['$scope', '$location', '$timeout', 'ipCookie', 'Session', 'AppState', function($scope, $location, $timeout, ipCookie, Session, AppState) {
var validEmail = function(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};
$scope.login = function(email, password, remember_me) {
if (!email || !password) {
$scope.error = "Email address and Password are required.";
return;
} else if (!validEmail(email)) {
$scope.error = "Please enter a valid formatted email address.";
return;
}
AuthControllers.controller('Login', ['$scope', '$location', '$timeout', 'ipCookie', 'Session', 'AppState', 'MetabaseForm',
function($scope, $location, $timeout, ipCookie, Session, AppState, MetabaseForm) {
var formFields = {
email: 'email',
password: 'password'
};
var validEmail = function(email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};
$scope.login = function(email, password, remember_me) {
MetabaseForm.clearFormErrors($scope.form, formFields);
$scope.form.$setPristine();
if (!validEmail(email)) {
$scope.form.email.$error.message = "Please enter a valid formatted email address.";
return;
}
Session.create({
'email': email,
'password': password
}, function(new_session) {
// set a session cookie
var isSecure = ($location.protocol() === "https") ? true : false;
ipCookie('metabase.SESSION_ID', new_session.id, {
path: '/',
expires: 14,
secure: isSecure
Session.create({
'email': email,
'password': password
}, function (new_session) {
// set a session cookie
var isSecure = ($location.protocol() === "https") ? true : false;
ipCookie('metabase.SESSION_ID', new_session.id, {
path: '/',
expires: 14,
secure: isSecure
});
// send a login notification event
$scope.$emit('appstate:login', new_session.id);
// this is ridiculously stupid. we have to wait (300ms) for the cookie to actually be set in the browser :(
$timeout(function() {
// we expect the homepage to handle the routing details about where the user should be going
$location.path('/');
}, 300);
}, function (error) {
MetabaseForm.parseFormErrors($scope.form, formFields, error);
});
};
// send a login notification event
$scope.$emit('appstate:login', new_session.id);
// this is ridiculously stupid. we have to wait (300ms) for the cookie to actually be set in the browser :(
$timeout(function() {
// we expect the homepage to handle the routing details about where the user should be going
$location.path('/');
}, 300);
}, function(error) {
$scope.error = "Invalid username/password combination specified.";
});
};
// do a quick check if the user is already logged in. if so then send them somewhere better.
if (AppState.model.currentUser && AppState.model.currentUser.memberOf().length > 0) {
$location.path('/' + AppState.model.currentUser.memberOf()[0].slug + '/');
// do a quick check if the user is already logged in. if so then send them somewhere better.
if (AppState.model.currentUser && AppState.model.currentUser.memberOf().length > 0) {
$location.path('/' + AppState.model.currentUser.memberOf()[0].slug + '/');
}
}
}]);
]);
AuthControllers.controller('Logout', ['$scope', '$location', '$timeout', 'ipCookie', 'Session', function($scope, $location, $timeout, ipCookie, Session) {
......
......@@ -17,14 +17,14 @@
<div class="FormError" ng-show="form.$error.message">{{form.$error.message}}</div>
<div ng-class="{'Form-group--error': form.email.$error.message == undefined}">
<div class="Form-field" ng-class="{'Form-group--error': form.email.$error.message == undefined}">
<mb-form-label form="form" display-name="Email address" field-name="email"></mb-form-label>
<input class="Form-input py1" name="email" placeholder="youlooknicetoday@email.com" type="text" ng-model="email" autofocus>
<input class="Form-input full py1" name="email" placeholder="youlooknicetoday@email.com" type="text" ng-model="email" required autofocus>
</div>
<div ng-class="{'Form-group--error': form.password.$error.message == undefined}">
<div class="Form-field" ng-class="{'Form-group--error': form.password.$error.message == undefined}">
<mb-form-label form="form" display-name="Password" field-name="password"></mb-form-label>
<input class="Form-input py1" name="password" placeholder="Shh..." type="password" ng-model="password">
<input class="Form-input full py1" name="password" placeholder="Shh..." type="password" ng-model="password" required>
</div>
<div>
......
(ns metabase.api.session
"/api/session endpoints"
(:require [cemerick.friend.credentials :as creds]
[clojure.tools.logging :as log]
(:require [clojure.tools.logging :as log]
[compojure.core :refer [defroutes POST DELETE]]
[hiccup.core :refer [html]]
[korma.core :as korma]
......@@ -10,7 +9,7 @@
[metabase.email.messages :as email]
(metabase.models [user :refer [User set-user-password]]
[session :refer [Session]])
[metabase.util.password :as password]))
[metabase.util.password :as pass]))
(defendpoint POST "/"
......@@ -18,9 +17,11 @@
[:as {{:keys [email password] :as body} :body}]
{email [Required Email]
password [Required NonEmptyString]}
(let-400 [user (sel :one :fields [User :id :password_salt :password] :email email (korma/where {:is_active true}))]
(check (creds/bcrypt-verify (str (:password_salt user) password) (:password user))
[400 "password mismatch"])
(let [user (sel :one :fields [User :id :password_salt :password] :email email (korma/where {:is_active true}))]
(checkp (not (nil? user))
(symbol "email") "no account found for the given email")
(checkp (pass/verify-password password (:password_salt user) (:password user))
(symbol "password") "did not match stored password")
(let [session-id (str (java.util.UUID/randomUUID))]
(ins Session
:id session-id
......
(ns metabase.util.password
(:require [metabase.config :as config]))
(:require [cemerick.friend.credentials :as creds]
[metabase.config :as config]))
(defn- count-occurrences
......@@ -25,3 +26,12 @@
:weak (and (> lowers 0) (> digits 0) (> uppers 0)) ; weak = 1 lower, 1 digit, 1 uppercase
:normal (and (> lowers 0) (> digits 0) (> uppers 0) (> specials 0)) ; normal = 1 lower, 1 digit, 1 uppercase, 1 special
:strong (and (> lowers 1) (> digits 0) (> uppers 1) (> specials 0)))))) ; strong = 2 lower, 1 digit, 2 uppercase, 1 special
(defn verify-password
"Verify if a given unhashed password + salt matches the supplied hashed-password. Returns true if matched, false otherwise."
[password salt hashed-password]
(try
(creds/bcrypt-verify (str salt password) hashed-password)
(catch Exception e
;; we wrap the friend/bcrypt-verify with this function specifically to avoid unintended exceptions getting out
false)))
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment