cql3: Fix error handling in LIST PERMISSIONS

This patch replaces duplicated code for checking the existence of a user
with the same mechanism for doing so as elsewhere: by checking for
`auth::nonexistent_role` being thrown during the course of checking
access-control.

This patch also ensures that exceptions thrown while querying the list
of permissions on a resource get handled correctly.
This commit is contained in:
Jesse Haber-Kucharsky
2018-01-17 18:14:14 -05:00
parent 13ba128967
commit cccfe269cf

View File

@@ -66,48 +66,33 @@ void cql3::statements::list_permissions_statement::validate(
}
future<> cql3::statements::list_permissions_statement::check_access(const service::client_state& state) {
//
// TODO(jhaberku): The existence checks should be in `execute()`. `check_access` should be restricted to
// authorization checking.
//
auto f = make_ready_future();
if (_username) {
f = state.get_auth_service()->underlying_role_manager().exists(*_username).then([this](bool exists) {
if (!exists) {
throw exceptions::invalid_request_exception(sprint("User %s doesn't exist", *_username));
}
});
if (_resource) {
maybe_correct_resource(*_resource, state);
return state.ensure_exists(*_resource);
}
return f.then([this, &state] {
if (_resource) {
maybe_correct_resource(*_resource, state);
return state.ensure_exists(*_resource);
const auto& as = *state.get_auth_service();
return auth::has_superuser(as, *state.user()).then([this, &state, &as](bool has_super) {
if (has_super) {
return make_ready_future<>();
}
return make_ready_future<>();
}).then([this, &state] {
const auto& as = *state.get_auth_service();
if (!_username) {
return make_exception_future<>(
exceptions::unauthorized_exception("You are not authorized to view everyone's permissions"));
}
return auth::has_superuser(as, *state.user()).then([this, &state, &as](bool has_super) {
if (has_super) {
return make_ready_future<>();
}
if (!_username) {
return auth::has_role(as, *state.user(), *_username).then([this](bool has_role) {
if (!has_role) {
return make_exception_future<>(
exceptions::unauthorized_exception("You are not authorized to view everyone's permissions"));
exceptions::unauthorized_exception(
sprint("You are not authorized to view %s's permissions", *_username)));
}
return auth::has_role(as, *state.user(), *_username).then([this](bool has_role) {
if (!has_role) {
return make_exception_future<>(
exceptions::unauthorized_exception(
sprint("You are not authorized to view %s's permissions", *_username)));
}
return make_ready_future<>();
});
return make_ready_future<>();
}).handle_exception_type([](const auth::nonexistant_role& e) {
return make_exception_future<>(exceptions::invalid_request_exception(e.what()));
});
});
}
@@ -154,7 +139,14 @@ cql3::statements::list_permissions_statement::execute(
[&state, this](opt_resource r) {
return do_with(std::move(r), [this, &state](const opt_resource& r) {
auto& auth_service = *state.get_client_state().get_auth_service();
return auth_service.underlying_authorizer().list(_permissions, r, _username, auth_service);
return auth_service.underlying_authorizer().list(
_permissions,
r,
_username,
auth_service).handle_exception_type([](const auth::nonexistant_role& e) {
return make_exception_future<std::vector<auth::permission_details>>(
exceptions::invalid_request_exception(e.what()));
});
});
},
std::vector<auth::permission_details>(),