assertEquals(Auth::setCookieName($name), $name); $this->assertEquals(Auth::$cookieName, $name); } public function testEncodeDecodeSession() { $id = 'id'; $secret = 'secret'; $session = 'eyJpZCI6ImlkIiwic2VjcmV0Ijoic2VjcmV0In0='; $this->assertEquals(Auth::encodeSession($id, $secret), $session); $this->assertEquals(Auth::decodeSession($session), ['id' => $id, 'secret' => $secret]); } public function testHash() { $secret = 'secret'; $this->assertEquals(Auth::hash($secret), '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b'); } public function testPassword() { /* General tests, using pre-defined hashes generated by online tools */ // Bcrypt - Version Y $plain = 'secret'; $hash = '$2y$08$PDbMtV18J1KOBI9tIYabBuyUwBrtXPGhLxCy9pWP6xkldVOKLrLKy'; $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); // Bcrypt - Version A $plain = 'test123'; $hash = '$2a$12$3f2ZaARQ1AmhtQWx2nmQpuXcWfTj1YV2/Hl54e8uKxIzJe3IfwLiu'; $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); // Bcrypt - Cost 5 $plain = 'hello-world'; $hash = '$2a$05$IjrtSz6SN7UJ6Sh3l.b5jODEvEG2LMJTPAHIaLWRvlWx7if3VMkFO'; $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); // Bcrypt - Cost 15 $plain = 'super-secret-password'; $hash = '$2a$15$DS0ZzbsFZYumH/E4Qj5oeOHnBcM3nCCsCA2m4Goigat/0iMVQC4Na'; $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); // MD5 - Short $plain = 'appwrite'; $hash = '144fa7eaa4904e8ee120651997f70dcc'; $generatedHash = Auth::passwordHash($plain, 'md5'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'md5')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'md5')); // MD5 - Long $plain = 'AppwriteIsAwesomeBackendAsAServiceThatIsAlsoOpenSourced'; $hash = '8410e96cf7ac64e0b84c3f8517a82616'; $generatedHash = Auth::passwordHash($plain, 'md5'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'md5')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'md5')); // PHPass $plain = 'pass123'; $hash = '$P$BVKPmJBZuLch27D4oiMRTEykGLQ9tX0'; $generatedHash = Auth::passwordHash($plain, 'phpass'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'phpass')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'phpass')); /* Provider-specific tests, ensuring functionality of specific use-cases */ // Provider #1 (Database) $plain = 'example-password'; $hash = '$2a$10$3bIGRWUes86CICsuchGLj.e.BqdCdg2/1Ud9LvBhJr0j7Dze8PBdS'; $generatedHash = Auth::passwordHash($plain, 'bcrypt'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'bcrypt')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'bcrypt')); // Provider #2 (Blog) $plain = 'your-password'; $hash = '$P$BkiNDJTpAWXtpaMhEUhUdrv7M0I1g6.'; $generatedHash = Auth::passwordHash($plain, 'phpass'); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'phpass')); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'phpass')); // Provider #2 (Google) $plain = 'users-password'; $hash = 'EPKgfALpS9Tvgr/y1ki7ubY4AEGJeWL3teakrnmOacN4XGiyD00lkzEHgqCQ71wGxoi/zb7Y9a4orOtvMV3/Jw=='; $options = [ 'salt' => '56dFqW+kswqktw==', 'cost_cpu' => 8, 'cost_memory' => 14, 'cost_parallel' => 1, 'length' => 64 ]; $generatedHash = Auth::passwordHash($plain, 'scrypt', $options); \var_dump($generatedHash); $this->assertEquals(true, Auth::passwordVerify($plain, $generatedHash, 'scrypt', $options)); $this->assertEquals(true, Auth::passwordVerify($plain, $hash, 'scrypt', $options)); } public function testPasswordGenerator() { $this->assertEquals(\mb_strlen(Auth::passwordGenerator()), 40); $this->assertEquals(\mb_strlen(Auth::passwordGenerator(5)), 10); } public function testTokenGenerator() { $this->assertEquals(\mb_strlen(Auth::tokenGenerator()), 256); $this->assertEquals(\mb_strlen(Auth::tokenGenerator(5)), 10); } public function testSessionVerify() { $secret = 'secret1'; $hash = Auth::hash($secret); $tokens1 = [ new Document([ '$id' => 'token1', 'expire' => time() + 60 * 60 * 24, 'secret' => $hash, 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', ]), new Document([ '$id' => 'token2', 'expire' => time() - 60 * 60 * 24, 'secret' => 'secret2', 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', ]), ]; $tokens2 = [ new Document([ // Correct secret and type time, wrong expire time '$id' => 'token1', 'expire' => time() - 60 * 60 * 24, 'secret' => $hash, 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', ]), new Document([ '$id' => 'token2', 'expire' => time() - 60 * 60 * 24, 'secret' => 'secret2', 'provider' => Auth::SESSION_PROVIDER_EMAIL, 'providerUid' => 'test@example.com', ]), ]; $this->assertEquals(Auth::sessionVerify($tokens1, $secret), 'token1'); $this->assertEquals(Auth::sessionVerify($tokens1, 'false-secret'), false); $this->assertEquals(Auth::sessionVerify($tokens2, $secret), false); $this->assertEquals(Auth::sessionVerify($tokens2, 'false-secret'), false); } public function testTokenVerify() { $secret = 'secret1'; $hash = Auth::hash($secret); $tokens1 = [ new Document([ '$id' => 'token1', 'type' => Auth::TOKEN_TYPE_RECOVERY, 'expire' => time() + 60 * 60 * 24, 'secret' => $hash, ]), new Document([ '$id' => 'token2', 'type' => Auth::TOKEN_TYPE_RECOVERY, 'expire' => time() - 60 * 60 * 24, 'secret' => 'secret2', ]), ]; $tokens2 = [ new Document([ // Correct secret and type time, wrong expire time '$id' => 'token1', 'type' => Auth::TOKEN_TYPE_RECOVERY, 'expire' => time() - 60 * 60 * 24, 'secret' => $hash, ]), new Document([ '$id' => 'token2', 'type' => Auth::TOKEN_TYPE_RECOVERY, 'expire' => time() - 60 * 60 * 24, 'secret' => 'secret2', ]), ]; $tokens3 = [ // Correct secret and expire time, wrong type new Document([ '$id' => 'token1', 'type' => Auth::TOKEN_TYPE_INVITE, 'expire' => time() + 60 * 60 * 24, 'secret' => $hash, ]), new Document([ '$id' => 'token2', 'type' => Auth::TOKEN_TYPE_RECOVERY, 'expire' => time() - 60 * 60 * 24, 'secret' => 'secret2', ]), ]; $this->assertEquals(Auth::tokenVerify($tokens1, Auth::TOKEN_TYPE_RECOVERY, $secret), 'token1'); $this->assertEquals(Auth::tokenVerify($tokens1, Auth::TOKEN_TYPE_RECOVERY, 'false-secret'), false); $this->assertEquals(Auth::tokenVerify($tokens2, Auth::TOKEN_TYPE_RECOVERY, $secret), false); $this->assertEquals(Auth::tokenVerify($tokens2, Auth::TOKEN_TYPE_RECOVERY, 'false-secret'), false); $this->assertEquals(Auth::tokenVerify($tokens3, Auth::TOKEN_TYPE_RECOVERY, $secret), false); $this->assertEquals(Auth::tokenVerify($tokens3, Auth::TOKEN_TYPE_RECOVERY, 'false-secret'), false); } public function testIsPrivilegedUser() { $this->assertEquals(false, Auth::isPrivilegedUser([])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_MEMBER])); $this->assertEquals(true, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_ADMIN])); $this->assertEquals(true, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_DEVELOPER])); $this->assertEquals(true, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_OWNER])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_APP])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_SYSTEM])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_APP, 'role:'.Auth::USER_ROLE_APP])); $this->assertEquals(false, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_APP, 'role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(true, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_OWNER, 'role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(true, Auth::isPrivilegedUser(['role:'.Auth::USER_ROLE_OWNER, 'role:'.Auth::USER_ROLE_ADMIN, 'role:'.Auth::USER_ROLE_DEVELOPER])); } public function testIsAppUser() { $this->assertEquals(false, Auth::isAppUser([])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_MEMBER])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_ADMIN])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_DEVELOPER])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_OWNER])); $this->assertEquals(true, Auth::isAppUser(['role:'.Auth::USER_ROLE_APP])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_SYSTEM])); $this->assertEquals(true, Auth::isAppUser(['role:'.Auth::USER_ROLE_APP, 'role:'.Auth::USER_ROLE_APP])); $this->assertEquals(true, Auth::isAppUser(['role:'.Auth::USER_ROLE_APP, 'role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_OWNER, 'role:'.Auth::USER_ROLE_GUEST])); $this->assertEquals(false, Auth::isAppUser(['role:'.Auth::USER_ROLE_OWNER, 'role:'.Auth::USER_ROLE_ADMIN, 'role:'.Auth::USER_ROLE_DEVELOPER])); } public function testGuestRoles() { $user = new Document([ '$id' => '' ]); $roles = Auth::getRoles($user); $this->assertCount(1, $roles); $this->assertContains('role:guest', $roles); } public function testUserRoles() { $user = new Document([ '$id' => '123', 'memberships' => [ [ 'teamId' => 'abc', 'roles' => [ 'administrator', 'moderator' ] ], [ 'teamId' => 'def', 'roles' => [ 'guest' ] ] ] ]); $roles = Auth::getRoles($user); $this->assertCount(7, $roles); $this->assertContains('role:member', $roles); $this->assertContains('user:123', $roles); $this->assertContains('team:abc', $roles); $this->assertContains('team:abc/administrator', $roles); $this->assertContains('team:abc/moderator', $roles); $this->assertContains('team:def', $roles); $this->assertContains('team:def/guest', $roles); } public function testPrivilegedUserRoles() { Authorization::setRole('role:'.Auth::USER_ROLE_OWNER); $user = new Document([ '$id' => '123', 'memberships' => [ [ 'teamId' => 'abc', 'roles' => [ 'administrator', 'moderator' ] ], [ 'teamId' => 'def', 'roles' => [ 'guest' ] ] ] ]); $roles = Auth::getRoles($user); $this->assertCount(5, $roles); $this->assertNotContains('role:member', $roles); $this->assertNotContains('user:123', $roles); $this->assertContains('team:abc', $roles); $this->assertContains('team:abc/administrator', $roles); $this->assertContains('team:abc/moderator', $roles); $this->assertContains('team:def', $roles); $this->assertContains('team:def/guest', $roles); } public function testAppUserRoles() { Authorization::setRole('role:'.Auth::USER_ROLE_APP); $user = new Document([ '$id' => '123', 'memberships' => [ [ 'teamId' => 'abc', 'roles' => [ 'administrator', 'moderator' ] ], [ 'teamId' => 'def', 'roles' => [ 'guest' ] ] ] ]); $roles = Auth::getRoles($user); $this->assertCount(5, $roles); $this->assertNotContains('role:member', $roles); $this->assertNotContains('user:123', $roles); $this->assertContains('team:abc', $roles); $this->assertContains('team:abc/administrator', $roles); $this->assertContains('team:abc/moderator', $roles); $this->assertContains('team:def', $roles); $this->assertContains('team:def/guest', $roles); } }