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 |
|