Auth.pm 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package Trog::Auth;
  2. use strict;
  3. use warnings;
  4. no warnings 'experimental';
  5. use feature qw{signatures};
  6. use DBI;
  7. use DBD::SQLite;
  8. use File::Slurper qw{read_text};
  9. use UUID::Tiny ':std';
  10. use Digest::SHA 'sha256';
  11. =head1 Trog::Auth
  12. An SQLite3 authdb.
  13. =head1 Termination Conditions
  14. Throws exceptions in the event the session database cannot be accessed.
  15. =head1 FUNCTIONS
  16. =head2 session2user(sessid) = STRING
  17. Translate a session UUID into a username.
  18. Returns empty string on no active session.
  19. =cut
  20. sub session2user ($sessid) {
  21. my $dbh = _dbh();
  22. my $rows = $dbh->selectall_arrayref("SELECT name FROM sess_user WHERE session=?",{ Slice => {} }, $sessid);
  23. return '' unless ref $rows eq 'ARRAY' && @$rows;
  24. return $rows->[0]->{name};
  25. }
  26. =head2 mksession(user, pass) = STRING
  27. Create a session for the user and waste all other sessions.
  28. Returns a session ID, or blank string in the event the user does not exist or incorrect auth was passed.
  29. =cut
  30. sub mksession ($user,$pass) {
  31. my $dbh = _dbh();
  32. my $records = $dbh->selectall_arrayref("SELECT salt FROM user WHERE name = ?", { Slice => {} }, $user);
  33. return '' unless ref $records eq 'ARRAY' && @$records;
  34. my $salt = $records->[0]->{salt};
  35. my $hash = sha256($pass.$salt);
  36. my $worked = $dbh->selectall_arrayref("SELECT id FROM user WHERE hash=? AND name = ?", { Slice => {} }, $hash, $user);
  37. return '' unless ref $worked eq 'ARRAY' && @$worked;
  38. my $uid = $worked->[0]->{id};
  39. my $uuid = create_uuid_as_string(UUID_V1, UUID_NS_DNS);
  40. $dbh->do("INSERT OR REPLACE INTO session (id,user_id) VALUES (?,?)", undef, $uuid, $uid) or return '';
  41. return $uuid;
  42. }
  43. =head2 useradd(user, pass) = BOOL
  44. Adds a user identified by the provided password into the auth DB.
  45. Returns True or False (likely false when user already exists).
  46. =cut
  47. sub useradd ($user, $pass) {
  48. my $dbh = _dbh();
  49. my $salt = create_uuid();
  50. my $hash = sha256($pass.$salt);
  51. return $dbh->do("INSERT INTO user (name,salt,hash) VALUES (?,?,?)", undef, $user, $salt, $hash);
  52. }
  53. my $dbh;
  54. # Ensure the db schema is OK, and give us a handle
  55. sub _dbh {
  56. return $dbh if $dbh;
  57. my $qq = read_text('schema/auth.schema');
  58. my $dbname = "$ENV{HOME}/.tcms/auth.db";
  59. $dbh = DBI->connect("dbi:SQLite:dbname=$dbname","","");
  60. $dbh->{sqlite_allow_multiple_statements} = 1;
  61. $dbh->do($qq) or die "Could not ensure auth database consistency";
  62. $dbh->{sqlite_allow_multiple_statements} = 0;
  63. return $dbh;
  64. }
  65. 1;