git.fiddlerwoaroof.com
validator_test.cc
7684972a
 /* Copyright (C) CJ Affiliate
  *
  * You may use, distribute and modify this code under  the
  * terms of the  GNU General Public License  version 2  or
  * later.
  *
  * You should have received a copy of the license with this
  * file. If not, you will find a copy in the "LICENSE" file
  * at https://github.com/cjdev/dual-control.
  */
 
28855478
 #include <string>
 #include <vector>
 
f757e35b
 #include "validator.h"
3c673060
 #include "user.h"
f757e35b
 #include "test_util.h"
9af49688
 #include "token.h"
21e4960f
 #include "sys_unistd.h"
 
 template<class T>
 std::shared_ptr<T> share (T *t)
 {
     return std::shared_ptr<T> (t);
 }
 
 class mock_unistd : public unistd_ifc
 {
 private:
     uid_t expected_euid_;
 public:
     mutable std::vector<uid_t> actual_uids;
     mock_unistd (uid_t expected_euid)
         : expected_euid_ (expected_euid)
     {}
 
     int seteuid (uid_t euid) const override
     {
0d8b9a17
         actual_uids.push_back (euid);
21e4960f
         return (euid == expected_euid_ || euid == 0) ? 0 : -1;
     }
 };
 
 class fake_user : public user_ifc
 {
 private:
     uid_t uid_;
 public:
     fake_user (uid_t uid) : uid_ (uid)
     {}
     uid_t uid() const override
     {
         return uid_;
     }
 };
f757e35b
 
28855478
 class fake_directory : public directory_ifc
cdf7fd74
 {
 private:
     std::string user_name_;
21e4960f
     uid_t uid_;
cdf7fd74
 public:
0d8b9a17
     fake_directory (const std::string &user_name,
                     const uid_t uid = -1) : user_name_ (user_name), uid_ (uid)
28855478
     {
     }
b017a4d2
     fake_directory() : user_name_ ("_NOT_A_USER") {}
cdf7fd74
 
bf756dea
     std::vector<user> find_user (const std::string &user_name) const override
cdf7fd74
     {
28855478
         std::vector<user> result;
b017a4d2
 
cdf7fd74
         if (user_name == user_name_) {
0d8b9a17
             result.push_back (user (share (new fake_user (uid_))));
3c673060
         }
0e218820
 
cdf7fd74
         return result;
     }
3c673060
 };
 
e064ffa9
 class fake_tokens : public tokens_ifc
cdf7fd74
 {
 private:
     std::string token_;
 public:
e064ffa9
     fake_tokens (const std::string &token) : token_ (token) {}
     fake_tokens() : token_ ("_NOT_A_TOKEN") {}
af3a4cd4
     std::string token (const user &user) const override
cdf7fd74
     {
         return token_;
     }
9af49688
 };
 
cdf7fd74
 bool validator_validates()
 {
f757e35b
 
9af49688
     // given
     std::string token = "token";
e064ffa9
     tokens tokens (share (new
d10906ee
                           fake_tokens (token)));
3c673060
     std::string user_name = "msmith";
21e4960f
 
     uid_t expected_uid = 1000;
     directory directory (share (new fake_directory (user_name, expected_uid)));
0d8b9a17
     std::shared_ptr<mock_unistd> mock_unistd = share (new class mock_unistd (
                 expected_uid));
21e4960f
     class unistd unistd (mock_unistd);
     validator validator = validator::create (directory, tokens, unistd);
     std::vector<uid_t> expected_uids {expected_uid, 0};
f757e35b
 
3c673060
     // when
044b2625
     bool actual = validator.validate ("requester", user_name, token, "reason");
f757e35b
 
3c673060
     // then
b017a4d2
     check (actual, "should be valid");
0d8b9a17
     check (mock_unistd->actual_uids == expected_uids,
            "should drop permissions");
3c673060
     succeed();
92b68213
 }
 
cdf7fd74
 bool validator_fails_unknown_user()
 {
92b68213
 
cdf7fd74
     // given
     std::string token = "token";
e064ffa9
     tokens tokens (share (new
d10906ee
                           fake_tokens));
28855478
     directory directory (share (new fake_directory));
21e4960f
     class unistd unistd (share (new unistd_ifc()));
     validator validator = validator::create (directory, tokens, unistd);
92b68213
 
cdf7fd74
     // when
044b2625
     bool actual = validator.validate ("requester", "notuser", token, "reason");
92b68213
 
cdf7fd74
     // then
b017a4d2
     check (!actual, "should not be valid");
cdf7fd74
     succeed();
92b68213
 }
 
cdf7fd74
 bool validator_fails_incorrect_token()
 {
92b68213
 
cdf7fd74
     // given
e064ffa9
     tokens tokens (share (new
d10906ee
                           fake_tokens));
9af49688
     std::string user_name = "msmith";
28855478
     directory directory (share (new fake_directory (user_name)));
21e4960f
     class unistd unistd (share (new unistd_ifc()));
     validator validator = validator::create (directory, tokens, unistd);
92b68213
 
cdf7fd74
     // when
b14fb8c6
     bool actual = validator.validate ("requester", user_name, "token",
                                       "reason");
92b68213
 
cdf7fd74
     // then
b017a4d2
     check (!actual, "should not be valid");
cdf7fd74
     succeed();
f757e35b
 }
 
af675d2b
 bool validator_fails_with_own_token()
 {
6ff7d0a7
     // given
af675d2b
     std::string requester_user_name ("requester");
     std::string authorizer_user_name (requester_user_name);
     std::string authorizer_token ("token");
6ff7d0a7
     directory directory (share (new fake_directory (authorizer_user_name)));
e064ffa9
     tokens tokens (share (new
d10906ee
                           fake_tokens (authorizer_token)));
21e4960f
     class unistd unistd (share (new unistd_ifc()));
     validator validator = validator::create (directory, tokens, unistd);
6ff7d0a7
 
     // when
af675d2b
     bool actual = validator.validate (requester_user_name, authorizer_user_name,
044b2625
                                       authorizer_token, "reason");
6ff7d0a7
 
     // then
af675d2b
     check (!actual, "should not be valid");
6ff7d0a7
     succeed();
 
 }
 
af675d2b
 bool validator_fails_with_unknown_requester()
 {
39b6d4a1
     // given
af675d2b
     std::string requester_user_name ("");
     std::string authorizer_user_name ("authorizer");
     std::string authorizer_token ("token");
39b6d4a1
     directory directory (share (new fake_directory (authorizer_user_name)));
e064ffa9
     tokens tokens (share (new
d10906ee
                           fake_tokens (authorizer_token)));
21e4960f
     class unistd unistd (share (new unistd_ifc()));
     validator validator = validator::create (directory, tokens, unistd);
39b6d4a1
 
     // when
af675d2b
     bool actual = validator.validate (requester_user_name, authorizer_user_name,
044b2625
                                       authorizer_token, "reason");
39b6d4a1
 
     // then
af675d2b
     check (!actual, "should not be valid");
39b6d4a1
     succeed();
044b2625
 }
 
b14fb8c6
 bool validator_fails_on_empty_reason()
 {
044b2625
     //given
     std::string requester_user_name ("");
     std::string authorizer_user_name ("authorizer");
     std::string authorizer_token ("token");
     std::string reason;
     directory directory (share (new fake_directory (authorizer_user_name)));
     tokens tokens (share (new
                           fake_tokens (authorizer_token)));
21e4960f
     class unistd unistd (share (new unistd_ifc()));
     validator validator = validator::create (directory, tokens, unistd);
39b6d4a1
 
044b2625
     //when
     bool actual = validator.validate (requester_user_name, authorizer_user_name,
                                       authorizer_token, reason);
 
     //then
b14fb8c6
     check (!actual, "should not be valid");
044b2625
     succeed();
39b6d4a1
 }
 
cdf7fd74
 bool run_tests()
 {
b017a4d2
     test (validator_validates);
     test (validator_fails_unknown_user);
     test (validator_fails_incorrect_token);
6ff7d0a7
     test (validator_fails_with_own_token);
39b6d4a1
     test (validator_fails_with_unknown_requester);
044b2625
     test (validator_fails_on_empty_reason);
f757e35b
     succeed();
 }
 
b017a4d2
 int main (int argc, char *argv[])
cdf7fd74
 {
f757e35b
     return !run_tests();
 }
0d8b9a17