aboutsummaryrefslogtreecommitdiff
path: root/src/privet
diff options
context:
space:
mode:
authorVitaly Buka <vitalybuka@google.com>2015-12-14 23:24:13 -0800
committerVitaly Buka <vitalybuka@google.com>2015-12-15 19:58:21 +0000
commitc3bc82a29cdff05d67d3b583ca0bc25df96ab382 (patch)
tree125f744f314a568b00b9bb4081f0ecd42d2a5e96 /src/privet
parent4ab500249f346a9fcfe084ee1619a39259f7471c (diff)
downloadlibweave-c3bc82a29cdff05d67d3b583ca0bc25df96ab382.tar.gz
Check if device already claimed
Client can claim only unclaimed device. Cloud can claim any device. Claim with kNone is not allowed. BUG=25766815, 26143922 Change-Id: Id92168b7f7c290509e672a659f09b7d06af37b76 Reviewed-on: https://weave-review.googlesource.com/1960 Reviewed-by: Vitaly Buka <vitalybuka@google.com>
Diffstat (limited to 'src/privet')
-rw-r--r--src/privet/auth_manager.cc21
-rw-r--r--src/privet/auth_manager_unittest.cc50
-rw-r--r--src/privet/constants.cc1
-rw-r--r--src/privet/constants.h1
-rw-r--r--src/privet/privet_handler.cc1
5 files changed, 69 insertions, 5 deletions
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc
index f38b854..f9f6777 100644
--- a/src/privet/auth_manager.cc
+++ b/src/privet/auth_manager.cc
@@ -9,6 +9,7 @@
#include "src/config.h"
#include "src/data_encoding.h"
+#include "src/privet/constants.h"
#include "src/privet/openssl_utils.h"
#include "src/string_utils.h"
@@ -80,6 +81,10 @@ std::vector<uint8_t> CreateSecret() {
return secret;
}
+bool IsClaimAllowed(RootClientTokenOwner curret, RootClientTokenOwner claimer) {
+ return claimer > curret || claimer == RootClientTokenOwner::kCloud;
+}
+
} // namespace
AuthManager::AuthManager(Config* config,
@@ -148,6 +153,17 @@ UserInfo AuthManager::ParseAccessToken(const std::vector<uint8_t>& token,
std::vector<uint8_t> AuthManager::ClaimRootClientAuthToken(
RootClientTokenOwner owner,
ErrorPtr* error) {
+ CHECK(RootClientTokenOwner::kNone != owner);
+ if (config_) {
+ auto current = config_->GetSettings().root_client_token_owner;
+ if (!IsClaimAllowed(current, owner)) {
+ Error::AddToPrintf(
+ error, FROM_HERE, errors::kDomain, errors::kAlreadyClaimed,
+ "Device already claimed by '%s'", EnumToString(current).c_str());
+ return {};
+ }
+ };
+
pending_claims_.push_back(std::make_pair(
std::unique_ptr<AuthManager>{new AuthManager{nullptr, {}}}, owner));
if (pending_claims_.size() > kMaxPendingClaims)
@@ -166,8 +182,11 @@ bool AuthManager::ConfirmAuthToken(const std::vector<uint8_t>& token,
[&token](const decltype(pending_claims_)::value_type& auth) {
return auth.first->IsValidAuthToken(token);
});
- if (claim == pending_claims_.end())
+ if (claim == pending_claims_.end()) {
+ Error::AddTo(error, FROM_HERE, errors::kDomain, errors::kNotFound,
+ "Unknown claim");
return false;
+ }
SetSecret(claim->first->GetSecret(), claim->second);
pending_claims_.clear();
diff --git a/src/privet/auth_manager_unittest.cc b/src/privet/auth_manager_unittest.cc
index 7b4aae4..aa124e1 100644
--- a/src/privet/auth_manager_unittest.cc
+++ b/src/privet/auth_manager_unittest.cc
@@ -147,23 +147,65 @@ TEST_F(AuthManagerTest, IsValidAuthToken) {
}
}
-TEST_F(AuthManagerTest, ClaimRootClientAuthToken) {
+class AuthManagerClaimTest : public testing::Test {
+ public:
+ void SetUp() override { EXPECT_GE(auth_.GetSecret().size(), 32u); }
+
+ bool TestClaim(RootClientTokenOwner owner, RootClientTokenOwner claimer) {
+ Config::Transaction change{&config_};
+ change.set_root_client_token_owner(owner);
+ change.Commit();
+ return !auth_.ClaimRootClientAuthToken(claimer, nullptr).empty();
+ }
+
+ protected:
+ Config config_{nullptr};
+ AuthManager auth_{&config_, {}};
+};
+
+TEST_F(AuthManagerClaimTest, WithPreviosOwner) {
+ EXPECT_DEATH(
+ TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kNone), "");
+ EXPECT_DEATH(
+ TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kNone),
+ "");
+ EXPECT_DEATH(
+ TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kNone), "");
+ EXPECT_TRUE(
+ TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kClient));
+ EXPECT_FALSE(
+ TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kClient));
+ EXPECT_FALSE(
+ TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kClient));
+ EXPECT_TRUE(
+ TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kCloud));
+ EXPECT_TRUE(
+ TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kCloud));
+ EXPECT_TRUE(
+ TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kCloud));
+}
+
+TEST_F(AuthManagerClaimTest, NormalClaim) {
auto token =
auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
EXPECT_FALSE(auth_.IsValidAuthToken(token));
+ EXPECT_EQ(RootClientTokenOwner::kNone,
+ config_.GetSettings().root_client_token_owner);
EXPECT_TRUE(auth_.ConfirmAuthToken(token, nullptr));
EXPECT_TRUE(auth_.IsValidAuthToken(token));
+ EXPECT_EQ(RootClientTokenOwner::kCloud,
+ config_.GetSettings().root_client_token_owner);
}
-TEST_F(AuthManagerTest, ClaimRootClientAuthTokenDoubleConfirm) {
+TEST_F(AuthManagerClaimTest, DoubleConfirm) {
auto token =
auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
EXPECT_TRUE(auth_.ConfirmAuthToken(token, nullptr));
EXPECT_TRUE(auth_.ConfirmAuthToken(token, nullptr));
}
-TEST_F(AuthManagerTest, DoubleClaimRootClientAuthToken) {
+TEST_F(AuthManagerClaimTest, DoubleClaim) {
auto token1 =
auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
auto token2 =
@@ -172,7 +214,7 @@ TEST_F(AuthManagerTest, DoubleClaimRootClientAuthToken) {
EXPECT_FALSE(auth_.ConfirmAuthToken(token2, nullptr));
}
-TEST_F(AuthManagerTest, ClaimRootClientAuthTokenOverflow) {
+TEST_F(AuthManagerClaimTest, TokenOverflow) {
auto token =
auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
for (size_t i = 0; i < 100; ++i)
diff --git a/src/privet/constants.cc b/src/privet/constants.cc
index 3cc3e4a..e1962bd 100644
--- a/src/privet/constants.cc
+++ b/src/privet/constants.cc
@@ -30,6 +30,7 @@ const char kInvalidSsid[] = "invalidSsid";
const char kInvalidPassphrase[] = "invalidPassphrase";
const char kNotFound[] = "notFound";
const char kNotImplemented[] = "notImplemented";
+const char kAlreadyClaimed[] = "alreadyClaimed";
} // namespace errors
} // namespace privet
diff --git a/src/privet/constants.h b/src/privet/constants.h
index 0668879..2b001aa 100644
--- a/src/privet/constants.h
+++ b/src/privet/constants.h
@@ -32,6 +32,7 @@ extern const char kInvalidSsid[];
extern const char kInvalidPassphrase[];
extern const char kNotFound[];
extern const char kNotImplemented[];
+extern const char kAlreadyClaimed[];
} // namespace errors
} // namespace privet
} // namespace weave
diff --git a/src/privet/privet_handler.cc b/src/privet/privet_handler.cc
index 86a2a85..b435435 100644
--- a/src/privet/privet_handler.cc
+++ b/src/privet/privet_handler.cc
@@ -153,6 +153,7 @@ struct {
{errors::kInvalidState, http::kInternalServerError},
{errors::kNotFound, http::kNotFound},
{errors::kNotImplemented, http::kNotSupported},
+ {errors::kAlreadyClaimed, http::kDenied},
};
AuthScope AuthScopeFromString(const std::string& scope, AuthScope auto_scope) {