Skip to content

Commit

Permalink
yegor256#45: merged with master and resolved conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
Yegor Bugayenko committed Mar 18, 2013
2 parents a93cafe + 120eb9e commit f870fc8
Show file tree
Hide file tree
Showing 16 changed files with 208 additions and 88 deletions.
15 changes: 15 additions & 0 deletions s3auth-hosts/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,19 @@
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
*/
@Immutable
@ToString
@EqualsAndHashCode(of = { "bucket", "htpasswd" })
@EqualsAndHashCode(of = "bucket")
@Loggable(Loggable.DEBUG)
final class DefaultHost implements Host {

Expand Down
19 changes: 7 additions & 12 deletions s3auth-hosts/src/main/java/com/s3auth/hosts/Htpasswd.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import com.jcabi.aspects.Cacheable;
import com.jcabi.aspects.Immutable;
import com.jcabi.aspects.LogExceptions;
import com.jcabi.aspects.Loggable;
import com.jcabi.log.Logger;
import java.io.ByteArrayOutputStream;
Expand All @@ -55,8 +56,8 @@
* @checkstyle ClassDataAbstractionCoupling (500 lines)
*/
@Immutable
@EqualsAndHashCode(of = "host")
@Loggable(Loggable.DEBUG)
@EqualsAndHashCode(of = "host")
final class Htpasswd {

/**
Expand Down Expand Up @@ -94,17 +95,10 @@ public Htpasswd(@NotNull final Host hst) {
*/
@Override
public String toString() {
String text;
try {
text = Logger.format(
".htpasswd(%d user(s), reloaded every %d min)",
this.fetch().size(),
Htpasswd.LIFETIME
);
} catch (IOException ex) {
text = ex.getMessage();
}
return text;
return Logger.format(
".htpasswd(? user(s), reloaded every %d min)",
Htpasswd.LIFETIME
);
}

/**
Expand All @@ -114,6 +108,7 @@ public String toString() {
* @return Yes or no
* @throws IOException If some error inside
*/
@LogExceptions
public boolean authorized(@NotNull final String user,
@NotNull final String password) throws IOException {
final ConcurrentMap<String, String> users = this.fetch();
Expand Down
60 changes: 60 additions & 0 deletions s3auth-hosts/src/test/java/com/s3auth/hosts/DefaultHostITCase.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2012, s3auth.com
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met: 1) Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer. 2) Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution. 3) Neither the name of the s3auth.com nor
* the names of its contributors may be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.s3auth.hosts;

import java.net.URI;
import org.junit.Test;

/**
* Integration test case for {@link DefaultHost}.
* @author Yegor Bugayenko ([email protected])
* @version $Id$
*/
public final class DefaultHostITCase {

/**
* DefaultHost can throw IOException for absent object.
* @throws Exception If there is some problem inside
*/
@Test(expected = java.io.IOException.class)
public void throwsWhenAbsentResource() throws Exception {
final Host host = new DefaultHost(
new DefaultBucket(
new DomainMocker()
.withName("invalid-bucket.s3auth.com")
.withKey("foo")
.withSecret("invalid-data")
.mock()
)
);
host.fetch(URI.create("foo.html"));
}

}
26 changes: 10 additions & 16 deletions s3auth-hosts/src/test/java/com/s3auth/hosts/DefaultHostTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -107,32 +107,26 @@ public S3Object answer(final InvocationOnMock invocation) {
}

/**
* DefaultHost can throw IOException for absent object.
* DefaultHost can show some stats in {@code #toString()}.
* @throws Exception If there is some problem inside
*/
@Test(expected = java.io.IOException.class)
public void throwsWhenAbsentResource() throws Exception {
final Host host = new DefaultHost(
new DefaultBucket(
new DomainMocker()
.withName("invalid-bucket.s3auth.com")
.withKey("foo")
.withSecret("invalid-data")
.mock()
)
@Test
public void showsStatsInToString() throws Exception {
MatcherAssert.assertThat(
new DefaultHost(new BucketMocker().mock()),
Matchers.hasToString(Matchers.notNullValue())
);
host.fetch(URI.create("foo.html"), Range.ENTIRE);
}

/**
* DefaultHost can show some stats in {@code #toString()}.
* DefaultHost can reject authorization with invalid credentials.
* @throws Exception If there is some problem inside
*/
@Test
public void showsStatsInToString() throws Exception {
public void rejectsAuthorizationWhenInvalidCredentials() throws Exception {
MatcherAssert.assertThat(
new DefaultHost(new BucketMocker().mock()),
Matchers.hasToString(Matchers.notNullValue())
new DefaultHost(new BucketMocker().mock()).authorized("1", "2"),
Matchers.is(false)
);
}

Expand Down
15 changes: 15 additions & 0 deletions s3auth-hosts/src/test/java/com/s3auth/hosts/HtpasswdTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ public void ignoresBrokenLines() throws Exception {
);
}

/**
* Htpasswd can use default host.
* @throws Exception If there is some problem inside
*/
@Test
public void worksWithDefaultHost() throws Exception {
final Htpasswd htpasswd = new Htpasswd(
new DefaultHost(new BucketMocker().mock())
);
MatcherAssert.assertThat(
htpasswd.authorized("jacky", "pwd"),
Matchers.is(false)
);
}

/**
* Create host that fetches the provided htpasswd content.
* @param htpasswd The content to fetch
Expand Down
37 changes: 31 additions & 6 deletions s3auth-relay/src/main/java/com/s3auth/relay/LocalHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,16 @@ final class LocalHost implements Host {
* {@inheritDoc}
*/
@Override
@SuppressWarnings("PMD.DoNotCallSystemExit")
public Resource fetch(@NotNull final URI uri, @NotNull final Range range)
public Resource fetch(@NotNull final URI uri, @NotNull final Range range)
throws IOException {
if (uri.toString().startsWith("/shutdown")) {
throw this.halt(uri.toString());
}
String output;
if ("/".equals(uri.toString())) {
output = "see www.s3auth.com";
} else if ("/version".equals(uri.toString())) {
output = Manifests.read("S3Auth-Revision");
} else if (uri.toString().equals(LocalHost.SHUTDOWN)) {
output = "";
Logger.warn(this, "fetch(%s): shutting down..", uri);
System.exit(0);
} else {
throw new HttpException(
HttpURLConnection.HTTP_NOT_FOUND,
Expand Down Expand Up @@ -127,4 +125,31 @@ public String toString() {
return "localhost";
}

/**
* Shutdown.
* @param uri URI just dispatched
* @return The exception to throw
*/
@SuppressWarnings("PMD.DoNotCallSystemExit")
private IOException halt(final String uri) {
IOException exception;
if (uri.equals(LocalHost.SHUTDOWN)) {
exception = new IOException();
Logger.warn(this, "fetch(%s): shutting down..", uri);
System.exit(0);
} else {
exception = new HttpException(
HttpURLConnection.HTTP_NOT_FOUND,
String.format(
"shutdown key ends with '%s...'",
LocalHost.SHUTDOWN.substring(
// @checkstyle MagicNumber (1 line)
LocalHost.SHUTDOWN.length() - 5
)
)
);
}
return exception;
}

}
14 changes: 9 additions & 5 deletions s3auth-relay/src/main/java/com/s3auth/relay/SecuredHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import com.jcabi.aspects.Loggable;
import com.s3auth.hosts.Host;
import com.s3auth.hosts.Range;
import com.s3auth.hosts.Resource;
import java.io.IOException;
import java.net.HttpURLConnection;
Expand Down Expand Up @@ -95,12 +96,13 @@ public SecuredHost(@NotNull final Host hst,
* {@inheritDoc}
*/
@Override
public Resource fetch(@NotNull final URI uri) throws IOException {
public Resource fetch(@NotNull final URI uri, @NotNull final Range range)
throws IOException {
Resource res;
if (this.isHidden(uri)) {
res = this.secured(uri);
res = this.secured(uri, range);
} else {
res = this.host.fetch(uri);
res = this.host.fetch(uri, range);
}
return res;
}
Expand Down Expand Up @@ -133,10 +135,12 @@ public void close() throws IOException {
/**
* Fetch this URI in a secure way.
* @param uri The URI to fetch
* @param range The range
* @return Fetched resource
* @throws IOException If some IO problem inside
*/
private Resource secured(final URI uri) throws IOException {
private Resource secured(final URI uri, final Range range)
throws IOException {
if (!this.request.headers().containsKey(HttpHeaders.AUTHORIZATION)) {
throw new HttpException(
new HttpResponse()
Expand Down Expand Up @@ -189,7 +193,7 @@ private Resource secured(final URI uri) throws IOException {
.withBody(this.host.toString())
);
}
return this.host.fetch(uri);
return this.host.fetch(uri, range);
}

}
2 changes: 1 addition & 1 deletion s3auth-relay/src/main/resources/log4j.properties
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ log4j.appender.SYSLOG.facilityPrinting=true
log4j.appender.SYSLOG.syslogHost=localhost
log4j.appender.SYSLOG.header=true
log4j.appender.SYSLOG.layout=org.apache.log4j.PatternLayout
log4j.appender.SYSLOG.layout.ConversionPattern=[%p] %t %c: %m%n
log4j.appender.SYSLOG.layout.ConversionPattern=[%p] ${buildNumber} %c: %m%n

# Application-specific logging
log4j.logger.com.s3auth=INFO
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import com.jcabi.manifests.Manifests;
import com.s3auth.hosts.Host;
import com.s3auth.hosts.Range;
import com.s3auth.hosts.ResourceMocker;
import java.net.URI;
import org.hamcrest.MatcherAssert;
Expand Down Expand Up @@ -64,7 +65,7 @@ public void rendersHomePage() throws Exception {
Matchers.hasToString(Matchers.equalTo("localhost"))
);
MatcherAssert.assertThat(
ResourceMocker.toString(host.fetch(URI.create("/"))),
ResourceMocker.toString(host.fetch(URI.create("/"), Range.ENTIRE)),
Matchers.notNullValue()
);
}
Expand All @@ -77,7 +78,9 @@ public void rendersHomePage() throws Exception {
public void reportsCurrentVersion() throws Exception {
final Host host = new LocalHost();
MatcherAssert.assertThat(
ResourceMocker.toString(host.fetch(URI.create("/version"))),
ResourceMocker.toString(
host.fetch(URI.create("/version"), Range.ENTIRE)
),
Matchers.equalTo(Manifests.read("S3Auth-Revision"))
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import com.s3auth.hosts.Host;
import com.s3auth.hosts.HostMocker;
import com.s3auth.hosts.Range;
import com.s3auth.hosts.Resource;
import java.net.HttpURLConnection;
import java.net.URI;
Expand Down Expand Up @@ -63,7 +64,7 @@ public void requestsAuthorization() throws Exception {
new SecuredHost(
new HostMocker().mock(),
HttpRequestMocker.toRequest(http)
).fetch(URI.create("/"));
).fetch(URI.create("/"), Range.ENTIRE);
Assert.fail("exception expected");
} catch (HttpException ex) {
MatcherAssert.assertThat(
Expand All @@ -90,7 +91,7 @@ public void requestsAuthorizationWhenBrokenData() throws Exception {
new SecuredHost(
new HostMocker().mock(),
HttpRequestMocker.toRequest(http)
).fetch(URI.create("/test.html"));
).fetch(URI.create("/test.html"), Range.ENTIRE);
Assert.fail("exception expected, but didn't happen");
} catch (HttpException ex) {
MatcherAssert.assertThat(
Expand Down Expand Up @@ -130,7 +131,7 @@ public boolean authorized(final String user,
return false;
}
@Override
public Resource fetch(final URI uri) {
public Resource fetch(final URI uri, final Range range) {
throw new UnsupportedOperationException();
}
@Override
Expand All @@ -141,7 +142,7 @@ public void close() {
HttpRequestMocker.toRequest(
"GET / HTTP/1.1\nAuthorization: Basic dGVzdDp0ZXN0\n\n"
)
).fetch(URI.create("/test-request.html"));
).fetch(URI.create("/test-request.html"), Range.ENTIRE);
Assert.fail("authorization failed expected, but didn't happen");
} catch (HttpException ex) {
MatcherAssert.assertThat(
Expand Down
Loading

0 comments on commit f870fc8

Please sign in to comment.