diff --git a/configure.py b/configure.py
index a8c55bed4b..41255f6cf9 100755
--- a/configure.py
+++ b/configure.py
@@ -341,6 +341,7 @@ scylla_core = (['database.cc',
'cql3/statements/drop_user_statement.cc',
'cql3/statements/list_users_statement.cc',
'cql3/statements/authorization_statement.cc',
+ 'cql3/statements/permission_altering_statement.cc',
'cql3/update_parameters.cc',
'cql3/ut_name.cc',
'cql3/user_options.cc',
diff --git a/cql3/statements/permission_altering_statement.cc b/cql3/statements/permission_altering_statement.cc
new file mode 100644
index 0000000000..b5cd84ef0d
--- /dev/null
+++ b/cql3/statements/permission_altering_statement.cc
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright 2016 ScyllaDB
+ *
+ * Modified by ScyllaDB
+ */
+
+/*
+ * This file is part of Scylla.
+ *
+ * Scylla is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Scylla is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Scylla. If not, see .
+ */
+
+#include
+
+#include "permission_altering_statement.hh"
+#include "cql3/query_processor.hh"
+#include "cql3/query_options.hh"
+#include "cql3/selection/selection.hh"
+#include "auth/auth.hh"
+
+cql3::statements::permission_altering_statement::permission_altering_statement(
+ auth::permission_set permissions, auth::data_resource resource,
+ sstring username)
+ : _permissions(permissions), _resource(std::move(resource)), _username(
+ std::move(username)) {
+}
+
+void cql3::statements::permission_altering_statement::validate(distributed& proxy, const service::client_state& state) {
+ // a check to ensure the existence of the user isn't being leaked by user existence check.
+ state.ensure_not_anonymous();
+}
+
+future<> cql3::statements::permission_altering_statement::check_access(const service::client_state& state) {
+ return auth::auth::is_existing_user(_username).then([this, &state](bool exists) {
+ if (!exists) {
+ throw exceptions::invalid_request_exception(sprint("User %s doesn't exist", _username));
+ }
+ mayme_correct_resource(_resource, state);
+ if (!_resource.exists()) {
+ throw exceptions::invalid_request_exception(sprint("%s doesn't exist", _resource));
+ }
+
+ // check that the user has AUTHORIZE permission on the resource or its parents, otherwise reject GRANT/REVOKE.
+ return state.ensure_has_permission(auth::permission::AUTHORIZE, _resource).then([this, &state] {
+ static auto perm_list = {
+ auth::permission::READ,
+ auth::permission::WRITE,
+ auth::permission::CREATE,
+ auth::permission::ALTER,
+ auth::permission::DROP,
+ auth::permission::SELECT,
+ auth::permission::MODIFY,
+ };
+ return do_for_each(perm_list, [this, &state](auth::permission p) {
+ // TODO: how about we re-write the access check to check a set
+ // right away. Might need some tweaking of enum_set to make it
+ // neat/transparent, but still...
+ // This is not critical code however.
+ if (_permissions.contains(p)) {
+ return state.ensure_has_permission(p, _resource);
+ }
+ return make_ready_future();
+ });
+ });
+ });
+}
+
diff --git a/cql3/statements/permission_altering_statement.hh b/cql3/statements/permission_altering_statement.hh
new file mode 100644
index 0000000000..f8c5e36b92
--- /dev/null
+++ b/cql3/statements/permission_altering_statement.hh
@@ -0,0 +1,67 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copyright 2016 ScyllaDB
+ *
+ * Modified by ScyllaDB
+ */
+
+/*
+ * This file is part of Scylla.
+ *
+ * Scylla is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Scylla is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Scylla. If not, see .
+ */
+
+#pragma once
+
+#include "authorization_statement.hh"
+#include "auth/permission.hh"
+#include "auth/data_resource.hh"
+
+namespace cql3 {
+
+namespace statements {
+
+class permission_altering_statement : public authorization_statement {
+protected:
+ auth::permission_set _permissions;
+ auth::data_resource _resource;
+ sstring _username;
+
+public:
+ permission_altering_statement(auth::permission_set, auth::data_resource, sstring);
+
+ void validate(distributed&, const service::client_state&) override;
+ future<> check_access(const service::client_state&) override;
+};
+
+}
+
+}