summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Ultramarine/Model/Users.pm625
-rw-r--r--t/tests/model/users.t46
2 files changed, 71 insertions, 0 deletions
diff --git a/lib/Ultramarine/Model/Users.pm6 b/lib/Ultramarine/Model/Users.pm6
new file mode 100644
index 0000000..ad52ab4
--- /dev/null
+++ b/lib/Ultramarine/Model/Users.pm6
@@ -0,0 +1,25 @@
+use v6.d.PREVIEW;
+use Digest::MD5;
+use experimental :pack;
+
+class Ultramarine::Model::Users {
+ has %!accounts;
+
+ submethod BUILD(:%!accounts) {}
+
+ multi method authenticate(:$user!,:$password! is copy) {
+ $password ~~ s[^enc\:(.+)$] = pack('H*',$/[0]).decode('UTF-8');
+
+ return (%!accounts{$user} && %!accounts{$user} eq $password);
+ }
+
+ multi method authenticate(:$user!,:$token!,:$salt!) {
+ return unless my $password = %!accounts{$user};
+
+ my $expected_token = Digest::MD5.md5_hex(
+ $password ~ $salt
+ );
+
+ return $token eq $expected_token;
+ }
+}
diff --git a/t/tests/model/users.t b/t/tests/model/users.t
new file mode 100644
index 0000000..1518831
--- /dev/null
+++ b/t/tests/model/users.t
@@ -0,0 +1,46 @@
+use v6.d.PREVIEW;
+use Test;
+use Ultramarine::Model::Users;
+
+my $u = Ultramarine::Model::Users.new(accounts => { me => 'sesame' });
+
+nok(
+ $u.authenticate(:user<me>,:password<bad>),
+ 'bad password should fail',
+);
+
+nok(
+ $u.authenticate(:user<not-there>,:password<bad>),
+ 'bad username should fail',
+);
+
+ok(
+ $u.authenticate(:user<me>,:password<sesame>),
+ 'plaintext should work',
+);
+
+ok(
+ $u.authenticate(:user<me>,:password<enc:736573616d65>),
+ 'hex-encoded should work',
+);
+
+nok(
+ $u.authenticate(:user<me>,:password<enc:736573616d64>),
+ 'bad hex-encoded should fail',
+);
+
+ok(
+ $u.authenticate(:user<me>,:token<26719a1196d2a940705a59634eb18eab>,
+ :salt<c19b2d>),
+ 'salted hash should work',
+);
+
+nok(
+ $u.authenticate(:user<me>,:token<26719a1196d2a940705a59634eb18eab>,
+ :salt<c19b2c>),
+ 'bad salted hash should work',
+);
+
+done-testing;
+
+