| // Copyright (C) 2018 The Android Open Source Project |
| // |
| // Licensed 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. |
| |
| package com.googlesource.gerrit.plugins.readonly; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE; |
| |
| import com.google.gerrit.acceptance.GitUtil; |
| import com.google.gerrit.acceptance.LightweightPluginDaemonTest; |
| import com.google.gerrit.acceptance.TestPlugin; |
| import com.google.gerrit.acceptance.UseLocalDisk; |
| import com.google.gerrit.acceptance.UseSsh; |
| import com.google.gerrit.extensions.api.changes.TopicInput; |
| import com.google.gerrit.extensions.common.ChangeInfo; |
| import com.google.gerrit.extensions.common.ChangeInput; |
| import org.eclipse.jgit.api.errors.TransportException; |
| import org.eclipse.jgit.transport.CredentialsProvider; |
| import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; |
| import org.junit.Ignore; |
| import org.junit.Test; |
| |
| @Ignore |
| @TestPlugin( |
| name = "readonly", |
| sysModule = "com.googlesource.gerrit.plugins.readonly.Module", |
| httpModule = "com.googlesource.gerrit.plugins.readonly.HttpModule", |
| sshModule = "com.googlesource.gerrit.plugins.readonly.SshModule") |
| public abstract class AbstractReadOnlyTest extends LightweightPluginDaemonTest { |
| @Test |
| @UseLocalDisk |
| public void restRequestsAreRejectedWhenReadOnly() throws Exception { |
| ChangeInput in = new ChangeInput(); |
| in.project = project.get(); |
| in.branch = "master"; |
| in.subject = "test"; |
| ChangeInfo change = gApi.changes().create(in).get(); |
| |
| // GET should be allowed |
| String url = "/changes/" + change.changeId; |
| adminRestSession.get(url).assertOK(); |
| |
| // PUT should be allowed |
| TopicInput topic = new TopicInput(); |
| topic.topic = "topic"; |
| adminRestSession.put(url + "/topic", topic).assertOK(); |
| |
| // DELETE should be allowed |
| adminRestSession.delete(url + "/topic").assertNoContent(); |
| |
| // POST should be allowed |
| adminRestSession.post(url + "/abandon").assertOK(); |
| |
| // Enable read-only |
| setReadOnly(true); |
| |
| // GET should be allowed |
| adminRestSession.get(url).assertOK(); |
| |
| // PUT should be blocked |
| adminRestSession.put(url + "/topic", topic).assertStatus(SC_SERVICE_UNAVAILABLE); |
| |
| // DELETE should be blocked |
| adminRestSession.delete(url + "/topic").assertStatus(SC_SERVICE_UNAVAILABLE); |
| |
| // POST should be blocked |
| adminRestSession.post(url + "/restore").assertStatus(SC_SERVICE_UNAVAILABLE); |
| |
| // Disable read-only |
| setReadOnly(false); |
| |
| // GET should be allowed |
| adminRestSession.get(url).assertOK(); |
| |
| // PUT should be allowed |
| adminRestSession.put(url + "/topic", topic).assertOK(); |
| |
| // DELETE should be allowed |
| adminRestSession.delete(url + "/topic").assertNoContent(); |
| |
| // POST should be allowed |
| adminRestSession.post(url + "/restore").assertOK(); |
| } |
| |
| @Test |
| @UseLocalDisk |
| @UseSsh |
| public void sshCommandsAreRejectedWhenReadOnly() throws Exception { |
| String command = "gerrit ls-projects"; |
| |
| // Command should succeed |
| adminSshSession.exec(command); |
| adminSshSession.assertSuccess(); |
| |
| // Enable read-only |
| setReadOnly(true); |
| |
| // Command should be blocked |
| adminSshSession.exec(command); |
| adminSshSession.assertFailure("READ ONLY"); |
| |
| // Disable read-only |
| setReadOnly(false); |
| |
| // Command should succeed |
| adminSshSession.exec(command); |
| adminSshSession.assertSuccess(); |
| } |
| |
| @Test |
| @UseLocalDisk |
| @UseSsh |
| public void pushBySshIsRejectedWhenReadOnly() throws Exception { |
| pushForReview(true); |
| } |
| |
| @Test |
| @UseLocalDisk |
| public void pushByHttpIsRejectedWhenReadOnly() throws Exception { |
| pushForReview(false); |
| } |
| |
| private void pushForReview(boolean ssh) throws Exception { |
| String url = ssh ? adminSshSession.getUrl() : admin.getHttpUrl(server); |
| if (!ssh) { |
| CredentialsProvider.setDefault( |
| new UsernamePasswordCredentialsProvider(admin.username(), admin.httpPassword())); |
| } |
| testRepo = GitUtil.cloneProject(project, url + "/" + project.get()); |
| |
| // Push should succeed |
| pushTo("refs/for/master").assertOkStatus(); |
| |
| // Enable read-only |
| setReadOnly(true); |
| |
| // Push should fail |
| try { |
| pushTo("refs/for/master"); |
| fail("expected TransportException"); |
| } catch (TransportException e) { |
| assertThat(e).hasMessageThat().contains("READ ONLY"); |
| } |
| |
| // Disable read-only |
| setReadOnly(false); |
| |
| // Push should succeed |
| pushTo("refs/for/master").assertOkStatus(); |
| } |
| |
| protected abstract void setReadOnly(boolean readOnly) throws Exception; |
| } |