Created timestamper module to start the application. Added cookie-based authentication to ts_api. Added utility methods to ts_api: * make_json_400/1 and make_json_400/1 * make_json_401/1 and make_json_401/2 * parse_json_body/1 reads a JSON object from a HTTP request body. Implemented ts_api_session module to manage api user sessions. Fixed ts_entry:list* methods to be 0-indexed. Removed the ts_json:ejson_to_record/1 implementation for ts_user records. Decided that ts_user records are never trusted from the client, manipulation of fields such as pwd, username will be restricted to app pages. Changed the password hashing algorithm. Now uses SHA1(pwd + 256bit salt). Want to use bcrypt, investingating cross-platform bcrypt implementation. Fixed yaws.conf config file.
48 lines
1.4 KiB
Erlang
48 lines
1.4 KiB
Erlang
-module(ts_user).
|
|
%-export([create_table/1, new/1, update/1, lookup/1, list/2]).
|
|
-compile(export_all).
|
|
|
|
-include("ts_db_records.hrl").
|
|
-include_lib("stdlib/include/qlc.hrl").
|
|
|
|
create_table(TableOpts) ->
|
|
mnesia:create_table(ts_user,
|
|
TableOpts ++ [{attributes, record_info(fields, ts_user)},
|
|
{type, ordered_set}]).
|
|
|
|
new(UR = #ts_user{}) ->
|
|
case mnesia:dirty_read(ts_user, UR#ts_user.username) of
|
|
[ExistingRecord] -> {error, {record_exists, ExistingRecord}};
|
|
[] -> mnesia:dirty_write(hash_input_record(UR))
|
|
end.
|
|
|
|
update(UR = #ts_user{}) ->
|
|
case mnesia:dirty_read(ts_user, UR#ts_user.username) of
|
|
[] -> no_record;
|
|
[_Record] -> mnesia:dirty_write(hash_input_record(UR))
|
|
end.
|
|
|
|
lookup(Username) ->
|
|
case mnesia:dirty_read(ts_user, Username) of
|
|
[] -> no_record;
|
|
[User] -> User
|
|
end.
|
|
|
|
list(Start, Length) -> ts_common:list(ts_user, Start, Length).
|
|
|
|
hash_input_record(User=#ts_user{}) ->
|
|
% create a new User record
|
|
Salt = generate_salt(),
|
|
HashedPwd = hash_pwd(User#ts_user.pwd, Salt),
|
|
User#ts_user{pwd = HashedPwd, pwd_salt = Salt}.
|
|
|
|
generate_salt() -> crypto:rand_bytes(36).
|
|
|
|
hash_pwd(Password, Salt) -> crypto:sha(Password ++ Salt).
|
|
|
|
check_credentials(Username, Password) ->
|
|
User = lookup(Username),
|
|
HashedInput = hash_pwd(Password, User#ts_user.pwd_salt),
|
|
|
|
HashedInput == User#ts_user.pwd.
|