Skip to content
This repository has been archived by the owner on May 9, 2021. It is now read-only.

Commit

Permalink
redirect when an HttpsOnly target is hit via HTTP instead of failing;…
Browse files Browse the repository at this point in the history
… add config option for old behavior - fixes #51
  • Loading branch information
kprevas committed Mar 17, 2012
1 parent bfff3f4 commit 1bcd7b8
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 6 deletions.
32 changes: 30 additions & 2 deletions ronin-test/test/ronin/HttpsTest.gs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ uses java.lang.*
uses org.junit.*
uses ronin.*
uses ronin.test.*
uses controller.Https
uses controller.HttpsClass
uses ronin.config.DefaultRoninConfig

class HttpsTest {

Expand All @@ -21,9 +24,22 @@ class HttpsTest {
}
}

@Test
function testHttpToHttpsOnlyMethodRedirects() {
var resp = RoninTest.get("Https/httpsOnly")
RoninTest.assertRedirect(resp)
RoninTest.assertRedirectTo(resp, Https#httpsOnly())
}


@Test(FiveHundredException, 0)
function testHttpToHttpsOnlyMethodFails() {
RoninTest.get("Https/httpsOnly")
try {
(RoninTest.RawConfig as DefaultRoninConfig).HttpsStrategy = FAIL
RoninTest.get("Https/httpsOnly")
} finally {
(RoninTest.RawConfig as DefaultRoninConfig).HttpsStrategy = REDIRECT
}
}

@Test
Expand All @@ -33,9 +49,21 @@ class HttpsTest {
}
}

@Test
function testHttpToHttpsOnlyClassRedirects() {
var resp = RoninTest.get("HttpsClass/noAnnotation")
RoninTest.assertRedirect(resp)
RoninTest.assertRedirectTo(resp, HttpsClass#noAnnotation())
}

@Test(FiveHundredException, 0)
function testHttpToHttpsOnlyClassFails() {
RoninTest.get("HttpsClass/noAnnotation")
try {
(RoninTest.RawConfig as DefaultRoninConfig).HttpsStrategy = FAIL
RoninTest.get("HttpsClass/noAnnotation")
} finally {
(RoninTest.RawConfig as DefaultRoninConfig).HttpsStrategy = REDIRECT
}
}

}
21 changes: 17 additions & 4 deletions ronin/src/ronin/RoninServlet.gs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ class RoninServlet extends AbstractRoninServlet {
files = Ronin.Config.ServletFileUpload.parseRequest(req) as List<FileItem>
}
checkMethodPermitted(actionMethod, httpMethod)
checkHttps(actionMethod, req.Scheme)
if(checkHttps(actionMethod, req.Scheme)) {
resp.sendRedirect(req.FullURL.replaceFirst(req.Scheme, "https"))
return
}
if(not checkLogin(actionMethod, req.FullURL)) {
return
}
Expand Down Expand Up @@ -365,15 +368,25 @@ class RoninServlet extends AbstractRoninServlet {
}
}

private function checkHttps(method : IMethodInfo, scheme : String) {
private function checkHttps(method : IMethodInfo, scheme : String) : boolean {
var needsHttps = false;
var httpsMethodAnnotation = method.getAnnotation(HttpsOnly)?.Instance
if(httpsMethodAnnotation != null and scheme != "https") {
throw new FiveHundredException("${method} requires HTTPS protocol.")
needsHttps = true;
}
var httpsTypeAnnotation = method.OwnersType.TypeInfo.getAnnotation(HttpsOnly)?.Instance
if(httpsTypeAnnotation != null and scheme != "https") {
throw new FiveHundredException("${method} requires HTTPS protocol.")
needsHttps = true;
}
if (needsHttps) {
switch (Ronin.Config.HttpsStrategy) {
case REDIRECT:
return true;
case FAIL:
throw new FiveHundredException("${method} requires HTTPS protocol.")
}
}
return false;
}

private function checkLogin(method : IMethodInfo, requestURL : String) : boolean {
Expand Down
5 changes: 5 additions & 0 deletions ronin/src/ronin/config/DefaultRoninConfig.gs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ uses ronin.templates.ShowDevException
uses gw.lang.parser.exceptions.ParseResultsException
uses ronin.templates.ShowDevParseResultsException
uses gw.lang.parser.exceptions.ErrantGosuClassException
uses ronin.config.IRoninConfig.HttpsStrategy

/**
* The default implementation of {@link ronin.config.IRoninConfig}.
Expand Down Expand Up @@ -67,6 +68,9 @@ class DefaultRoninConfig implements IRoninConfig {
// authentication
var _authManager : IAuthManager as AuthManager

// HTTPS handling
var _httpsStrategy : HttpsStrategy as HttpsStrategy

var _restrictedProperties : Set<PropertyReference> as RestrictedProperties
var _loginRedirect : MethodReference as LoginRedirect
property set LoginRedirect(methodRef : MethodReference) {
Expand Down Expand Up @@ -100,6 +104,7 @@ class DefaultRoninConfig implements IRoninConfig {
ServletFileUpload = new ServletFileUpload(new DiskFileItemFactory())
Filters = {}
RestrictedProperties = {}
HttpsStrategy = REDIRECT

ErrorHandler = new DefaultErrorHandler()
URLHandler = new DefaultURLHandler()
Expand Down
7 changes: 7 additions & 0 deletions ronin/src/ronin/config/IRoninConfig.gs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ uses javax.servlet.Filter
*/
interface IRoninConfig {

enum HttpsStrategy {REDIRECT, FAIL}

/**
* The servlet responsible for handling Ronin requests.
*/
Expand Down Expand Up @@ -107,6 +109,11 @@ interface IRoninConfig {
*/
property get LoginRedirect() : MethodReference

/**
* What to do if an HTTPS-only controller method or class is accessed via HTTP.
*/
property get HttpsStrategy() : HttpsStrategy

/**
* Initializes a servlet filter with a default filter configuration and returns it.
*/
Expand Down

0 comments on commit 1bcd7b8

Please sign in to comment.