/*************************GO-LICENSE-START*********************************
* Copyright 2016 ThoughtWorks, Inc.
*
* 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.
*************************GO-LICENSE-END***********************************/
package com.thoughtworks.go.domain.materials.svn;
import java.io.File;
import java.io.IOException;
import java.util.List;
import com.googlecode.junit.ext.JunitExtRunner;
import com.thoughtworks.go.domain.materials.Modification;
import com.thoughtworks.go.domain.materials.ValidationBean;
import com.thoughtworks.go.helper.SvnRemoteRepository;
import com.thoughtworks.go.util.FileUtil;
import com.thoughtworks.go.util.TestFileUtil;
import com.thoughtworks.go.util.command.InMemoryStreamConsumer;
import com.thoughtworks.go.util.command.ProcessOutputStreamConsumer;
import org.apache.commons.io.FileUtils;
import org.hamcrest.core.Is;
import org.jdom2.input.SAXBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import static com.thoughtworks.go.util.command.ProcessOutputStreamConsumer.inMemoryConsumer;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
@RunWith(JunitExtRunner.class)
public class SvnCommandRemoteTest {
public SvnRemoteRepository repository;
private static final String HARRY = "harry";
private static final String HARRYS_PASSWORD = "harryssecret";
public SvnCommand command;
public File workingDir;
private InMemoryStreamConsumer outputStreamConsumer;
@Before
public void startRepo() throws Exception {
repository = new SvnRemoteRepository();
repository.addUser(HARRY, HARRYS_PASSWORD);
repository.start();
command = new SvnCommand(null, repository.getUrl(), HARRY, HARRYS_PASSWORD, true);
workingDir = TestFileUtil.createTempFolder("workingDir" + System.currentTimeMillis());
outputStreamConsumer = inMemoryConsumer();
}
@After
public void stopRepo() throws Exception {
if (repository!=null) repository.stop();
FileUtil.deleteFolder(workingDir);
}
@Test public void shouldSupportSvnInfo() throws Exception {
SvnCommand.SvnInfo info = command.remoteInfo(new SAXBuilder());
assertThat(info.getUrl(), is(repository.getUrl()));
}
@Test public void shouldSupportSvnLog() throws Exception {
List<Modification> info = command.latestModification();
assertThat(info.get(0).getComment(), is("Added simple build shell to dump the environment to console."));
}
@Test public void shouldSupportModificationsSince() throws Exception {
List<Modification> info = command.modificationsSince(new SubversionRevision(2));
assertThat(info.size(), is(2));
assertThat(info.get(0).getRevision(), is("4"));
assertThat(info.get(1).getRevision(), is("3"));
}
@Test public void shouldSupportLocalSvnInfoWithoutPassword() throws Exception {
command.checkoutTo(ProcessOutputStreamConsumer.inMemoryConsumer(), workingDir,
new SubversionRevision(4));
SvnCommand commandWithoutPassword = new SvnCommand(null, repository.getUrl(), null, null, true);
SvnCommand.SvnInfo info = commandWithoutPassword.workingDirInfo(workingDir);
assertThat(info.getUrl(), is(repository.getUrl()));
}
@Test
public void shouldMaskPassword_CheckConnection() {
ValidationBean goodResponse = command.checkConnection();
assertThat(goodResponse.isValid(), Is.is(true));
assertThat("Plain text password detected!", goodResponse.getError().contains(HARRYS_PASSWORD), Is.is(false));
ValidationBean badResponse = badUserNameCommand().checkConnection();
assertThat(badResponse.isValid(), Is.is(false));
assertThat("Plain text password detected!", badResponse.getError().contains(HARRYS_PASSWORD), Is.is(false));
badResponse = badPasswordCommand().checkConnection();
assertThat(badResponse.isValid(), Is.is(false));
assertThat("Plain text password detected!", badResponse.getError().contains("some_bad_password"), Is.is(false));
badResponse = badUrlCommand().checkConnection();
assertThat(badResponse.isValid(), Is.is(false));
assertThat("Plain text password detected!", badResponse.getError().contains(HARRYS_PASSWORD), Is.is(false));
}
@Test
public void shouldMaskPassword_UpdateTo() {
command.checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
command.updateTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
try {
badUserNameCommand().updateTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().updateTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().updateTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_CheckoutTo() {
command.checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
try {
FileUtil.deleteFolder(workingDir);
badUserNameCommand().checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
FileUtil.deleteFolder(workingDir);
badPasswordCommand().checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains("some_bad_password"), Is.is(false));
}
try {
FileUtil.deleteFolder(workingDir);
badUrlCommand().checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_getAllExternalURLs() {
try {
badUserNameCommand().getAllExternalURLs();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().getAllExternalURLs();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().getAllExternalURLs();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_latestModification() {
try {
badUserNameCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_modificationsSince() {
try {
badUserNameCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().latestModification();
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_remoteInfo() {
try {
badUserNameCommand().remoteInfo(new SAXBuilder());
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().remoteInfo(new SAXBuilder());
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().remoteInfo(new SAXBuilder());
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_workingDirInfo() {
try {
badUserNameCommand().workingDirInfo(workingDir);
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().workingDirInfo(workingDir);
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().workingDirInfo(workingDir);
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_commit() throws IOException {
command.checkoutTo(outputStreamConsumer, workingDir, new SubversionRevision(2));
File newFile = new File(workingDir.getAbsolutePath() + "/foo");
FileUtils.writeStringToFile(newFile, "content");
command.add(outputStreamConsumer, newFile);
try {
badUserNameCommand().commit(outputStreamConsumer, workingDir, "message");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().commit(outputStreamConsumer, workingDir, "message");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains("some_bad_password"), Is.is(false));
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().commit(outputStreamConsumer, workingDir, "message");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", outputStreamConsumer.getAllOutput().contains(HARRYS_PASSWORD), Is.is(false));
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
@Test
public void shouldMaskPassword_propset() throws IOException {
try {
badUserNameCommand().propset(workingDir, "svn:ignore", "*.foo");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
try {
badPasswordCommand().propset(workingDir, "svn:ignore", "*.foo");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains("some_bad_password"), Is.is(false));
}
try {
badUrlCommand().propset(workingDir, "svn:ignore", "*.foo");
fail("should have failed");
} catch (Exception e) {
assertThat("Plain text password detected!", e.getMessage().contains(HARRYS_PASSWORD), Is.is(false));
}
}
private SvnCommand badUrlCommand() {
return new SvnCommand(null, "https://invalid", "blrstdcrspair", HARRYS_PASSWORD, false);
}
private SvnCommand badUserNameCommand() {
return new SvnCommand(null, repository.getUrl(), "some_bad_user", HARRYS_PASSWORD, false);
}
private SvnCommand badPasswordCommand() {
return new SvnCommand(null, repository.getUrl(), HARRY, "some_bad_password", false);
}
}