Created
October 28, 2009 21:53
-
-
Save kuba97531/220899 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This application is only for me. Or can you tell the secret? | |
<form method="post" action="<%= current_action %>"> | |
<input id="<%= param_name%>" name="<%= param_name%>" type="password" /> | |
<button class="submitButton" type="submit" name="commit">Here I am!</button> | |
</form> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class OnlyForMe | |
require 'erb' | |
require 'tilt' | |
class InvalidConfiguration < StandardError; end | |
attr_reader :param_name | |
# here all keys, that were authenticated are stored | |
@@accepted_keys = [] | |
def initialize(app, opts = {}) | |
@app = app | |
# list of all passwords that we accept | |
@secret_phrases = opts[:secret_phrases] || ["password"] | |
raise InvalidConfiguration unless @secret_phrases.is_a?(Array) | |
# name of parameter used in the authentication form | |
@param_name = opts[:param_name] || 'secret_phrase' | |
# name of the cookie in wich we store authentication key | |
@cookie_name = opts[:cookie_name] || 'only.for.me' | |
# how long should session last? | |
@expires = opts[:expires] || 1.hour | |
# provide template with one form and a field. | |
# template is | |
@template_path = opts[:template_path] | |
end | |
def call(env) | |
# if user is authenticated we just call the application | |
return @app.call(env) if @@accepted_keys.include?(read_key(env)) | |
request = Rack::Request.new(env) | |
if @secret_phrases.include?(request.params[@param_name]) | |
# When user sends request with proper secret phrase we prepare a new key for him | |
new_key = Digest::MD5.hexdigest("Only for me %s %s" % [ Time.now.to_f, rand]) | |
@@accepted_keys << new_key | |
# and redirect him to application. | |
status, headers, body = [301, {"Location" => env["REQUEST_PATH"] }, "Redirected!"] | |
# with key stored in cookie | |
send_with_key(new_key, body, status, headers) | |
else | |
#if user is not authorized, we show him authentication page | |
page = Tilt.new(@template_path).render(self, :current_action => env['HTTP_PATH']) | |
return [200, {"Content-Type" => "text/html"}, [page]] | |
end | |
end | |
# read authentication key from cookie | |
def read_key(env) | |
request = Rack::Request.new(env) | |
request.cookies[@cookie_name] | |
end | |
# pack authentication key into cookie and attach it to response | |
def send_with_key(data, body, status, headers) | |
cookie = Hash.new | |
cookie[:value] = data | |
cookie[:expires] = Time.now + @expires | |
response = Rack::Response.new(body, status, headers) | |
response.set_cookie(@cookie_name, cookie) | |
response.to_a | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment