Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions contrib/endpoints/include/api_manager/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ class Request {
// Adds a header to backend. If the header exists, overwrite its value
virtual utils::Status AddHeaderToBackend(const std::string &key,
const std::string &value) = 0;

// Gets all HTTP request headers. This method cannot be made into a pure
// virtual function until all the implementations of this class also implement
// the GetHeaders method. Changing this to a pure virtual function should be
// done with a lot of care and making sure that all implementations of this
// class have implemented this method.
virtual void GetHeaders(std::map<std::string, std::string> *headers) = 0;
};

} // namespace api_manager
Expand Down
39 changes: 11 additions & 28 deletions contrib/endpoints/src/api_manager/check_security_rules_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,13 @@ static const char kDummyBody[] = R"(
static const char kDummyAudience[] = "test-audience";

const char kFirstRequest[] =
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"method":"get","path":"/ListShelves","auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","email_verified":true,"azp":"limin-429@appspot.gserviceaccount.com","aud":"https://myfirebaseapp.appspot.com","sub":"113424383671131376652","iat":1486575396,"iss":"https://accounts.google.com","exp":1486578996}}}}]}})";
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"headers":{"Pragma":"Custom value"},"path":"/ListShelves","method":"get","auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","email_verified":true,"azp":"limin-429@appspot.gserviceaccount.com","sub":"113424383671131376652","aud":"https://myfirebaseapp.appspot.com","iat":1486575396,"iss":"https://accounts.google.com","exp":1486578996}}}}]}})";

const char kSecondRequest[] =
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","azp":"limin-429@appspot.gserviceaccount.com","aud":"https://myfirebaseapp.appspot.com","sub":"113424383671131376652","iss":"https://accounts.google.com","email_verified":true,"iat":1486575396,"exp":1486578996}},"method":"get","path":"/ListShelves"},"functionMocks":[{"function":"f1","args":[{"exactValue":"http://url1"},{"exactValue":"POST"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}}]}]}})";
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"headers":{"Pragma":"Custom value"},"auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","azp":"limin-429@appspot.gserviceaccount.com","iat":1486575396,"email_verified":true,"aud":"https://myfirebaseapp.appspot.com","sub":"113424383671131376652","exp":1486578996,"iss":"https://accounts.google.com"}},"method":"get","path":"/ListShelves"},"functionMocks":[{"function":"f1","args":[{"exactValue":"http://url1"},{"exactValue":"POST"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}}]}]}})";

const char kThirdRequest[] =
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"method":"get","path":"/ListShelves","auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","iat":1486575396,"azp":"limin-429@appspot.gserviceaccount.com","exp":1486578996,"email_verified":true,"sub":"113424383671131376652","aud":"https://myfirebaseapp.appspot.com","iss":"https://accounts.google.com"}}},"functionMocks":[{"function":"f2","args":[{"exactValue":"http://url2"},{"exactValue":"GET"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}},{"function":"f3","args":[{"exactValue":"https://url3"},{"exactValue":"GET"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}},{"function":"f1","args":[{"exactValue":"http://url1"},{"exactValue":"POST"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}}]}]}})";
R"({"testSuite":{"testCases":[{"expectation":"ALLOW","request":{"headers":{"Pragma":"Custom value"},"auth":{"token":{"email":"limin-429@appspot.gserviceaccount.com","exp":1486578996,"iss":"https://accounts.google.com","iat":1486575396,"sub":"113424383671131376652","aud":"https://myfirebaseapp.appspot.com","azp":"limin-429@appspot.gserviceaccount.com","email_verified":true}},"method":"get","path":"/ListShelves"},"functionMocks":[{"function":"f2","args":[{"exactValue":"http://url2"},{"exactValue":"GET"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}},{"function":"f3","args":[{"exactValue":"https://url3"},{"exactValue":"GET"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}},{"function":"f1","args":[{"exactValue":"http://url1"},{"exactValue":"POST"},{"exactValue":{"key":"value"}},{"exactValue":"test-audience"}],"result":{"value":{"key":"value"}}}]}]}})";

::google::protobuf::Value ToValue(const std::string &arg) {
::google::protobuf::Value value;
Expand Down Expand Up @@ -198,31 +198,6 @@ MATCHER_P3(HTTPRequestMatches, url, method, body, "") {
return MessageDifferencer::Equals(actual, expected);
}

FunctionCall BuildCall(const std::string &name, const std::string &url,
const std::string &method, const std::string &body,
const std::string &audience) {
FunctionCall func_call;
func_call.set_function(name);

if (!url.empty()) {
*(func_call.add_args()) = ToValue(url);
}

if (!method.empty()) {
*(func_call.add_args()) = ToValue(method);
}

if (!body.empty()) {
*(func_call.add_args()) = ToValue(body);
}

if (!audience.empty()) {
*(func_call.add_args()) = ToValue(audience);
}

return func_call;
}

// Get a server configuration that has auth disabled. This should disable
// security rules check by default.
std::pair<std::string, std::string> GetConfigWithAuthForceDisabled() {
Expand Down Expand Up @@ -346,6 +321,14 @@ class CheckSecurityRulesTest : public ::testing::Test {
ON_CALL(*raw_request_, GetRequestPath())
.WillByDefault(Return(std::string("/ListShelves")));

ON_CALL(*raw_request_, GetHeaders(_))
.WillByDefault(
testing::Invoke([](std::map<std::string, std::string> *map) {
if (map != nullptr) {
(*map)["Pragma"] = "Custom value";
}
}));

request_context_ = std::make_shared<context::RequestContext>(
service_context_, std::move(request));
release_url_ =
Expand Down
4 changes: 2 additions & 2 deletions contrib/endpoints/src/api_manager/check_workflow.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ void CheckWorkflow::RegisterAll() {
Register(FetchServiceAccountToken);
// Authentication checks.
Register(CheckAuth);
// Checks service control.
Register(CheckServiceControl);
// Check Security Rules.
Register(CheckSecurityRules);
// Checks service control.
Register(CheckServiceControl);
// Quota control
Register(QuotaControl);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const std::string kToken = "token";
const std::string kAuth = "auth";
const std::string kPath = "path";
const std::string kMethod = "method";
const std::string kHeaders = "headers";
const std::string kHttpGetMethod = "GET";
const std::string kHttpPostMethod = "POST";
const std::string kHttpHeadMethod = "HEAD";
Expand Down Expand Up @@ -180,6 +181,7 @@ Status FirebaseRequest::UpdateRulesetRequestBody(
::google::protobuf::Value claims;
::google::protobuf::Value path;
::google::protobuf::Value method;
::google::protobuf::Value headers;

Status status = utils::JsonToProto(context_->auth_claims(), &claims);
if (!status.ok()) {
Expand All @@ -188,6 +190,10 @@ Status FirebaseRequest::UpdateRulesetRequestBody(

auto *variables = test_case->mutable_request()->mutable_struct_value();
auto *fields = variables->mutable_fields();
GetHeaders(&headers);
if (headers.kind_case() != ::google::protobuf::Value::kNullValue) {
(*fields)[kHeaders] = headers;
}

path.set_string_value(context_->request()->GetRequestPath());
(*fields)[kPath] = path;
Expand Down Expand Up @@ -216,6 +222,26 @@ Status FirebaseRequest::UpdateRulesetRequestBody(
return status;
}

void FirebaseRequest::GetHeaders(::google::protobuf::Value *headers) {
if (headers == nullptr) {
return;
}

std::map<std::string, std::string> req_headers;
context_->request()->GetHeaders(&req_headers);
if (req_headers.size() == 0) {
headers->set_null_value(::google::protobuf::NullValue::NULL_VALUE);
return;
}

auto *map = headers->mutable_struct_value()->mutable_fields();
for (const auto &kvp : req_headers) {
::google::protobuf::Value value;
value.set_string_value(kvp.second);
(*map)[kvp.first] = value;
}
}

Status FirebaseRequest::ProcessTestRulesetResponse(const std::string &body) {
Status status = utils::JsonToProto(body, &response_);
if (!status.ok()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ class FirebaseRequest {
std::vector<std::pair<proto::TestRulesetResponse::TestResult::FunctionCall,
std::string>>::const_iterator
Find(const proto::TestRulesetResponse::TestResult::FunctionCall &func_call);
void GetHeaders(::google::protobuf::Value *value);

// The API manager environment. Primarily used for logging.
ApiManagerEnvInterface *env_;
Expand Down
1 change: 1 addition & 0 deletions contrib/endpoints/src/api_manager/mock_request.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class MockRequest : public Request {
MOCK_METHOD0(GetGrpcResponseBytes, int64_t());
MOCK_METHOD0(GetGrpcRequestMessageCounts, int64_t());
MOCK_METHOD0(GetGrpcResponseMessageCounts, int64_t());
MOCK_METHOD1(GetHeaders, void(std::map<std::string, std::string> *));
};

} // namespace api_manager
Expand Down