aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Duncan <pabs@pablotron.org>2016-04-02 01:09:45 -0400
committerPaul Duncan <pabs@pablotron.org>2016-04-02 01:09:45 -0400
commit23ba337de24e88c6aaf6ceb37507997f5c5f4920 (patch)
treef5a6fc8d925dafd62ee45973b4e357234ea9ec9a
parent7788012457346ae59fa58ed35fc08aa2b9e6b9ef (diff)
downloadold-guff-23ba337de24e88c6aaf6ceb37507997f5c5f4920.tar.bz2
old-guff-23ba337de24e88c6aaf6ceb37507997f5c5f4920.zip
fully working edit dialog
-rw-r--r--data/stuff/js/util.js4
-rw-r--r--data/stuff/test/auth.js97
-rw-r--r--src/guff/api/methods.cr42
-rw-r--r--src/guff/api/test.cr10
-rw-r--r--src/guff/handlers/api.cr1
-rw-r--r--src/guff/models/user.cr111
-rw-r--r--src/guff/views/ecrs/test/auth.ecr4
7 files changed, 215 insertions, 54 deletions
diff --git a/data/stuff/js/util.js b/data/stuff/js/util.js
index a6826db..c021499 100644
--- a/data/stuff/js/util.js
+++ b/data/stuff/js/util.js
@@ -9,4 +9,8 @@ jQuery(function($) {
data: args,
});
};
+
+ LuigiTemplate.FILTERS.json = function(val) {
+ return JSON.stringify(val);
+ };
});
diff --git a/data/stuff/test/auth.js b/data/stuff/test/auth.js
index 5876a41..0776bfd 100644
--- a/data/stuff/test/auth.js
+++ b/data/stuff/test/auth.js
@@ -5,8 +5,8 @@ jQuery(function($) {
"<a ",
"href='#' ",
"class='list-group-item %{css|h}' ",
- "title='Set user to \"%{user_name|h}.\"' ",
- "data-user_id='%{user_id|h}' ",
+ "title='Edit user \"%{user_name|h}\".' ",
+ "data-row='%{row|json|h}' ",
">",
"<i class='fa fa-fw fa-spinner fa-spin hidden loading'></i>",
"<i class='fa fa-fw fa-user loading'></i>",
@@ -51,7 +51,7 @@ jQuery(function($) {
}).done(function(r) {
list.html($.map(r.users, function(row) {
return TEMPLATES.run('user', $.extend({}, row, {
- css: (r.user_id == row.user_id) ? 'active' : '',
+ row: row,
}));
}).join(''));
});
@@ -74,20 +74,10 @@ jQuery(function($) {
var me = $(this);
// update highlight
- var last = $('#users .active').removeClass('active');
+ $('#users .active').removeClass('active');
me.addClass('active');
- // show spinner
- me.addClass('disabled').find('.loading').toggleClass('hidden');
-
- set_user(me.data('user_id')).always(function() {
- // hide spinner
- me.removeClass('disabled').find('.loading').toggleClass('hidden');
- }).fail(function(r) {
- // restore old highlight
- me.removeClass('active');
- last.addClass('active');
- });
+ $('#edit-dialog').data('row', me.data('row')).modal('show');
// stop event
return false;
@@ -100,6 +90,21 @@ jQuery(function($) {
$('#add-role').val('guest');
});
+ $('#add-dialog').on('shown.bs.modal', function() {
+ $('#add-name').focus();
+ });
+
+ $('#add-name, #add-email, #add-password').keydown(function(ev) {
+ if (ev.which == 13) {
+ setTimeout(function() {
+ $('#add-confirm').click();
+ }, 10);
+
+ // stop event
+ return false;
+ }
+ });
+
$('#add-confirm').click(function() {
var me = $(this);
@@ -130,6 +135,68 @@ jQuery(function($) {
return false;
});
+ $('#edit-dialog').on('show.bs.modal', function() {
+ var row = $(this).data('row');
+
+ $.each({
+ name: 'user_name',
+ email: 'email',
+ role: 'role_name',
+ }, function(id, col) {
+ $('#edit-' + id).val(row[col]);
+ });
+ });
+
+ $('#edit-dialog').on('shown.bs.modal', function() {
+ $('#edit-name').focus();
+ });
+
+ $('#edit-dialog').on('hide.bs.modal', function() {
+ // clear highlight
+ $('#users .active').removeClass('active');
+ });
+
+ $('#edit-name, #edit-email').keydown(function(ev) {
+ if (ev.which == 13) {
+ setTimeout(function() {
+ $('#edit-confirm').click();
+ }, 10);
+
+ // stop event
+ return false;
+ }
+ });
+
+ $('#edit-confirm').click(function() {
+ var me = $(this),
+ user_id = $('#edit-dialog').data('row').user_id;
+
+ if (me.hasClass('disabled'))
+ return false;
+
+ // toggle loading
+ me.toggleClass('disabled').find('.loading').toggleClass('hidden');
+
+ send('test/edit_user', {
+ user_id: user_id,
+ name: $('#edit-name').val(),
+ email: $('#edit-email').val(),
+ role: $('#edit-role').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);
+ reload();
+ $('#edit-dialog').modal('hide');
+ });
+
+ // stop event
+ return false;
+ });
+
$('#login').click(function() {
var me = $(this);
diff --git a/src/guff/api/methods.cr b/src/guff/api/methods.cr
index fce6911..9b8aa3b 100644
--- a/src/guff/api/methods.cr
+++ b/src/guff/api/methods.cr
@@ -403,6 +403,48 @@ module Guff
},
},
+ "edit_user": {
+ text: "Test edit user",
+
+ args: {
+ "user_id": {
+ text: "User ID",
+ type: :int,
+ required: true,
+ },
+
+ "name": {
+ text: "Name of user",
+ type: :text,
+ required: false,
+ },
+
+ "active": {
+ text: "Is this user active?",
+ type: :bool,
+ required: false,
+ },
+
+ "role": {
+ text: "Role of user",
+ type: :text,
+ required: false,
+ },
+
+ "email": {
+ text: "Email address of user",
+ type: :text,
+ required: false,
+ },
+
+ "password": {
+ text: "Password of user",
+ type: :text,
+ required: false,
+ },
+ },
+ },
+
"login": {
text: "Test user login.",
diff --git a/src/guff/api/test.cr b/src/guff/api/test.cr
index decc5ec..91a729c 100644
--- a/src/guff/api/test.cr
+++ b/src/guff/api/test.cr
@@ -65,14 +65,16 @@ module Guff::API::TestAPI
{ "ok": true, "user_id": user_id }
end
- private def do_test_update_user(
+ private def do_test_edit_user(
context : HTTP::Server::Context,
args : Hash(String, String)
)
- @models.user.update_user(args["user_id"].to_i64,
- name: args["name"]? ? args["name"] : nil,
+ @models.user.edit_user(args["user_id"].to_i64,
+ name: args["name"]?,
active: args["active"]? ? args["active"] == "t" : nil,
- role: args["role"]? ? args["role"] : nil
+ role: args["role"]?,
+ email: args["email"]?,
+ password: args["password"]?,
)
{ "ok": true }
diff --git a/src/guff/handlers/api.cr b/src/guff/handlers/api.cr
index d9208b1..523f2f2 100644
--- a/src/guff/handlers/api.cr
+++ b/src/guff/handlers/api.cr
@@ -139,6 +139,7 @@ class Guff::Handlers::APIHandler < Guff::Handler
get_users,
set_user,
add_user,
+ edit_user,
login,
],
})
diff --git a/src/guff/models/user.cr b/src/guff/models/user.cr
index bdbb0de..d440c5c 100644
--- a/src/guff/models/user.cr
+++ b/src/guff/models/user.cr
@@ -23,7 +23,7 @@ class Guff::UserModel < Guff::Model
INSERT INTO users(user_name) VALUES (:user_name)
",
- update_user: "
+ edit_user: "
UPDATE users
SET %{sets}
WHERE user_id = :user_id
@@ -38,6 +38,12 @@ class Guff::UserModel < Guff::Model
(:user_id, :email, :pass_hash)
",
+ edit_login: "
+ UPDATE user_logins
+ SET %{sets}
+ WHERE user_id = :user_id
+ ",
+
login: "
SELECT a.user_id,
a.pass_hash
@@ -92,7 +98,7 @@ class Guff::UserModel < Guff::Model
# set active and/or role
if active || role
- update_user(user_id,
+ edit_user(user_id,
active: active,
role: role,
)
@@ -111,38 +117,46 @@ class Guff::UserModel < Guff::Model
user_id
end
- def update_user(
- user_id : Int64,
- name : String? = nil,
- active : Bool? = nil,
- role : String? = nil,
+ def edit_user(
+ user_id : Int64,
+ name : String? = nil,
+ active : Bool? = nil,
+ role : String? = nil,
+ email : String? = nil,
+ password : String? = nil,
)
- sets = [] of String
- args = { "user_id": user_id.to_s }
+ transaction do
+ sets = [] of String
+ args = { "user_id": user_id.to_s }
- if name != nil
- args["name"] = name.not_nil!
- sets << "user_name = :name"
- end
+ if name != nil
+ args["name"] = name.not_nil!
+ sets << "user_name = :name"
+ end
- if active != nil
- args["is_active"] = active.not_nil! ? "1" : "0"
- sets << "is_active = :is_active"
- end
+ if active != nil
+ args["is_active"] = active.not_nil! ? "1" : "0"
+ sets << "is_active = :is_active"
+ end
- if role != nil
- args["role"] = role.not_nil!
- sets << "
- role_id = (SELECT role_id
- FROM roles
- WHERE role_name = :role)
- "
- end
+ if role != nil
+ args["role"] = role.not_nil!
+ sets << "
+ role_id = (SELECT role_id
+ FROM roles
+ WHERE role_name = :role)
+ "
+ end
- # exec query
- query(:update_user, args, {
- "sets": sets.join(", "),
- }) if sets.size > 0
+ # exec query
+ query(:edit_user, args, {
+ "sets": sets.join(", "),
+ }) if sets.size > 0
+
+ if email != nil || password != nil
+ edit_login(user_id, email, password)
+ end
+ end
end
def delete_login(user_id : Int64)
@@ -156,11 +170,8 @@ class Guff::UserModel < Guff::Model
email : String,
password : String,
)
- # TODO: check password strength
- raise "password too short" if password.size < 4
-
# hash password
- pass_hash = Crypto::Bcrypt::Password.create(password, cost: 10).to_s
+ pass_hash = hash_password(password)
transaction do
# clear old credentials
@@ -175,6 +186,32 @@ class Guff::UserModel < Guff::Model
end
end
+ private def edit_login(
+ user_id : Int64,
+ email : String? = nil,
+ password : String? = nil,
+ )
+ transaction do
+ sets = [] of String
+ args = { "user_id": user_id.to_s }
+
+ if email != nil
+ args["email"] = email.not_nil!
+ sets << "email = :email"
+ end
+
+ if password != nil
+ args["pass_hash"] = hash_password(password.not_nil!)
+ sets << "pass_hash = :pass_hash"
+ end
+
+ # exec query
+ query(:edit_login, args, {
+ "sets": sets.join(", "),
+ }) if sets.size > 0
+ end
+ end
+
def login(
email : String,
password : String
@@ -198,4 +235,12 @@ class Guff::UserModel < Guff::Model
# return user id
row["user_id"] as Int64
end
+
+ private def hash_password(password : String)
+ # TODO: check password strength
+ raise "password too short" if password.size < 4
+
+ # hash password
+ Crypto::Bcrypt::Password.create(password, cost: 10).to_s
+ end
end
diff --git a/src/guff/views/ecrs/test/auth.ecr b/src/guff/views/ecrs/test/auth.ecr
index b683c5c..ab9f552 100644
--- a/src/guff/views/ecrs/test/auth.ecr
+++ b/src/guff/views/ecrs/test/auth.ecr
@@ -228,7 +228,7 @@
</div><!-- modal-dialog -->
</div><!-- modal -->
-<div id='edit-user' class='modal fade' role='dialog'>
+<div id='edit-dialog' class='modal fade' role='dialog'>
<div class='modal-dialog' role='document'>
<div class='modal-content'>
<div class='modal-header'>
@@ -295,7 +295,7 @@
<div class='modal-footer'>
<button
- id='edit-user-confirm'
+ id='edit-confirm'
class='btn btn-primary'
title='Update user.'
>