diff options
-rw-r--r-- | data/stuff/test/auth.js | 40 | ||||
-rw-r--r-- | src/guff/api/methods.cr | 20 | ||||
-rw-r--r-- | src/guff/api/test.cr | 10 | ||||
-rw-r--r-- | src/guff/handlers/api.cr | 2 | ||||
-rw-r--r-- | src/guff/models/user.cr | 37 | ||||
-rw-r--r-- | src/guff/views/ecrs/test/auth.ecr | 66 |
6 files changed, 168 insertions, 7 deletions
diff --git a/data/stuff/test/auth.js b/data/stuff/test/auth.js index 1bba095..408010b 100644 --- a/data/stuff/test/auth.js +++ b/data/stuff/test/auth.js @@ -91,6 +91,9 @@ jQuery(function($) { $('#create-user').click(function() { var me = $(this); + if (me.hasClass('disabled')) + return false; + // toggle loading me.toggleClass('disabled').find('.loading').toggleClass('hidden'); @@ -113,6 +116,43 @@ jQuery(function($) { return false; }); + $('#login').click(function() { + var me = $(this); + + if (me.hasClass('disabled')) + return false; + + // toggle loading + me.toggleClass('disabled').find('.loading').toggleClass('hidden'); + + send('test/login', { + email: $('#login-email').val(), + password: $('#login-password').val(), + }).always(function() { + // toggle loading + me.toggleClass('disabled').find('.loading').toggleClass('hidden'); + }).fail(function(r) { + alert('Error ' + r.responseText); + }).done(function(r) { + console.log(r); + }); + + // stop event + return false; + }); + + $('#login-user, #login-password').keydown(function(ev) { + if (ev.which == 13) { + setTimeout(function() { + // trigger login + $('#login').click(); + }, 10); + + // stop event + return false; + } + }); + $('#reload').click(reload); // load users diff --git a/src/guff/api/methods.cr b/src/guff/api/methods.cr index 970e41f..fce6911 100644 --- a/src/guff/api/methods.cr +++ b/src/guff/api/methods.cr @@ -368,7 +368,7 @@ module Guff }, "add_user": { - text: "Add new user", + text: "Test add new user", args: { "name": { @@ -402,6 +402,24 @@ module Guff }, }, }, + + "login": { + text: "Test user login.", + + args: { + "email": { + text: "Email address of user", + type: :text, + required: true, + }, + + "password": { + text: "Password of user", + type: :text, + required: true, + }, + }, + }, } } diff --git a/src/guff/api/test.cr b/src/guff/api/test.cr index 059f670..448cadf 100644 --- a/src/guff/api/test.cr +++ b/src/guff/api/test.cr @@ -82,7 +82,7 @@ module Guff::API::TestAPI user_id = @models.user.add_user(args["name"].not_nil!, active: args["active"]? ? args["active"] == "t" : nil, role: args["role"]?, - email: args["name"]?, + email: args["email"]?, password: args["password"]?, ) { "ok": true, "user_id": user_id } @@ -120,4 +120,12 @@ module Guff::API::TestAPI @models.user.remove_login(args["user_id"].to_i) { "ok": true } end + + private def do_test_login( + context : HTTP::Server::Context, + args : Hash(String, String) + ) + user_id = @models.user.login(args["email"], args["password"]).to_i + { "ok": true, "user_id": user_id } + end end diff --git a/src/guff/handlers/api.cr b/src/guff/handlers/api.cr index 0f7f963..d9208b1 100644 --- a/src/guff/handlers/api.cr +++ b/src/guff/handlers/api.cr @@ -139,7 +139,7 @@ class Guff::Handlers::APIHandler < Guff::Handler get_users, set_user, add_user, - update_user, + login, ], }) rescue e diff --git a/src/guff/models/user.cr b/src/guff/models/user.cr index 98ae10b..28e317e 100644 --- a/src/guff/models/user.cr +++ b/src/guff/models/user.cr @@ -20,6 +20,18 @@ class Guff::UserModel < Guff::Model INSERT INTO user_logins(user_id, email, pass_hash) VALUES (:user_id, :email, :pass_hash) ", + + login: " + SELECT a.user_id, + a.pass_hash + + FROM user_logins a + JOIN users b + ON (b.user_id = a.user_id AND + b.is_active) + + WHERE a.email = :email + ", }) def initialize(models : Models) @@ -125,6 +137,7 @@ class Guff::UserModel < Guff::Model # hash password pass_hash = Crypto::Bcrypt::Password.create(password, cost: 10).to_s + # puts "user_id = #{user_id}, email = #{email}, password = #{password}, pass_hash = #{pass_hash}" transaction do # clear old credentials @@ -138,4 +151,28 @@ class Guff::UserModel < Guff::Model }, nil) end end + + def login( + email : String, + password : String + ) + # map email to user id and pass hash + row = row(:login, { + "email": email, + }, nil) + + raise "invalid login" unless row + + # shut compiler up + row = row.not_nil! + + # get pass hash from db + pass_hash = Crypto::Bcrypt::Password.new(row["pass_hash"].to_s) + + # compare hash against password + raise "invalid login" unless pass_hash == password + + # return user id + row["user_id"] as Int64 + end end diff --git a/src/guff/views/ecrs/test/auth.ecr b/src/guff/views/ecrs/test/auth.ecr index 89d3283..ec6e9a8 100644 --- a/src/guff/views/ecrs/test/auth.ecr +++ b/src/guff/views/ecrs/test/auth.ecr @@ -15,7 +15,7 @@ </div><!-- navbar --> <div class='container'> - <div class='col-md-8 col-md-offset-2'> + <div class='col-md-6'> <div class='panel panel-default'> <div class='panel-heading'> <b> @@ -46,11 +46,13 @@ </span><!-- list-group-item --> </div><!-- list-group --> </div><!-- panel --> + </div><!-- col-md-6 --> + <div class='col-md-6'> <div class='panel panel-default'> <div class='panel-heading'> <b> - <i class='fa fa-user'></i> + <i class='fa fa-user-plus'></i> Create User </b> </div><!-- panel-heading --> @@ -123,12 +125,68 @@ </span> <span class='loading'> - <i class='fa fa-plus-square'></i> + <i class='fa fa-user-plus'></i> Create User </span> </button> </div><!-- form-group --> </div><!-- panel-body --> </div><!-- panel --> - </div><!-- col-md-8 --> + + <div class='panel panel-default'> + <div class='panel-heading'> + <b> + <i class='fa fa-lock'></i> + Login + </b> + </div><!-- panel-heading --> + + <div class='panel-body'> + <div class='form-group'> + <label for='login-email'> + Email + </label> + + <input + type='text' + id='login-email' + class='form-control' + title='Enter email address.' + placeholder='foo@example.com' + /> + </div><!-- form-group --> + + <div class='form-group'> + <label for='login-password'> + Password + </label> + + <input + type='password' + id='login-password' + class='form-control' + title='Enter password.' + /> + </div><!-- form-group --> + + <div class='form-group'> + <button + id='login' + class='btn btn-primary' + title='Log in.' + > + <span class='hidden loading'> + <i class='fa fa-spinner fa-spin'></i> + Please Wait... + </span> + + <span class='loading'> + <i class='fa fa-unlock-alt'></i> + Log In + </span> + </button> + </div><!-- form-group --> + </div><!-- panel-body --> + </div><!-- panel --> + </div><!-- col-md-6 --> </div><!-- container --> |