Skip to content

Instantly share code, notes, and snippets.

@jeppenejsum
Created March 14, 2013 11:41
Show Gist options
  • Save jeppenejsum/5160712 to your computer and use it in GitHub Desktop.
Save jeppenejsum/5160712 to your computer and use it in GitHub Desktop.
Check if cookies are enabled
package fleetzone
package http
import net.liftweb.http._
import net.liftweb.http.provider._
import net.liftweb.sitemap._
import net.liftweb.common._
import net.liftweb.util._
import scala.xml._
/**
* Class used for checking landing pages
*
* Verifies that cookies are enabled and redirects to error page if not.
*
* Example usage:
*
* val cookieVerifier = new CookieVerifier(cookies => RedirectResponse("/cookieerror.html", cookies:_*)) {
* verify {
* case Req(path, _, _) if pathIsPublic(path) => true
* }
* }
*/
class CookieVerifier(errorHandler: (HTTPCookie*) => LiftResponse, cookieName: String = "verifier", verifyURI: List[String] = List("verifycookies")) extends Logger {
private object cookiesEnabled extends SessionVar[Box[Boolean]](Empty)
LiftRules.dispatch.append {
case Req(path, _, _) if path == verifyURI => () => Full{
debug("Verify if cookie with name %s is present".format(cookieName))
trace("Received cookies: "+S.request.dmap("")(_.cookies.toString))
val receivedValue = S.cookieValue(cookieName)
val expected = S.param("verify")
val cookiesOk = receivedValue.isDefined && receivedValue == expected
debug("Cookie found: %s, should match: %s. Result: %s".format(receivedValue, expected, cookiesOk))
cookiesEnabled(Full(cookiesOk))
S.deleteCookie(cookieName)
trace("Deleted cookie, Response cookies: "+S.responseCookies)
if (cookiesOk) {
val returnTo = (S.param("returnTo").map(Helpers.urlDecode(_)) or S.referer).getOrElse("/")
debug("Cookie present, redirect back to %s. referer=%s".format(returnTo, S.referer))
RedirectResponse(returnTo, S.responseCookies :_*)
} else {
debug("Cookie not present, calling error handler")
errorHandler(S.responseCookies :_*)
}
}
}
protected def verify(handler: PartialFunction[Req, Boolean]): Unit = LiftRules.dispatch.append(new LiftRules.DispatchPF() {
def isDefinedAt(in: Req) = {
if (handler.isDefinedAt(in) && handler(in)) {
val skipCheck = in.param("_nocheck").isDefined
val enabled = cookiesEnabled.dmap(false)(enabled => enabled)
trace("Cookies enabled (%s)=%s, skip=%s".format(in.uri, enabled, skipCheck))
!(enabled || skipCheck)
} else
false
}
def apply(in: Req): () => Box[LiftResponse] = {
val value = StringHelpers.randomString(16)
debug("Cookies not checked, redirecting to verify url, value=%s".format(value))
val cookie = HTTPCookie(cookieName, value).setMaxAge(-1).setPath("/")
// Need to escape the incoming URL, as it may itself contain URL parameters
val paramList = in.params.keys.flatMap(key => in.params(key).map(v => key -> v)).toList
val paramString = Helpers.paramsToUrlParams(paramList)
val returnUrl = in.uri + "?" + paramString
val encoded = Helpers.urlEncode(returnUrl)
val uri = "/%s?verify=%s&returnTo=%s".format(verifyURI.mkString("/"), value,encoded)
trace("Redirecting to "+uri)
() => Full(RedirectResponse(uri, cookie))
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment