Skip to content

Commit

Permalink
Credentials now accumulates entries
Browse files Browse the repository at this point in the history
  • Loading branch information
maiha committed Jan 18, 2017
1 parent 3efb379 commit 7bf6595
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 12 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ get "/" do |env|
end
```

### accumulated entries

When `basic_auth` is called in several times, the credentials are accumulated and shared by all pages.

```crystal
basic_auth "user1", "123"
get "/members" do |env|
"restricted page" # both `user1` and `guest` can see this page.
end
basic_auth "guest", "temp"
get "/trial" do |env|
"restricted page" # both `user1` and `guest` can see this page.
end
```

## Contributing

1. Fork it ( https://github.com/kemalcr/kemal-basic-auth/fork )
Expand Down
35 changes: 29 additions & 6 deletions spec/credentials_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,35 @@ describe "HTTPBasicAuth::Credentials" do
"serdar" => "123",
"dogruyol" => "abc",
}
crendentials = HTTPBasicAuth::Credentials.new(entries)
credentials = HTTPBasicAuth::Credentials.new(entries)

crendentials.authorize?("serdar" , "123").should eq("serdar")
crendentials.authorize?("serdar" , "xxx").should eq(nil)
crendentials.authorize?("dogruyol", "abc").should eq("dogruyol")
crendentials.authorize?("dogruyol", "xxx").should eq(nil)
crendentials.authorize?("foo" , "bar").should eq(nil)
credentials.authorize?("serdar" , "123").should eq("serdar")
credentials.authorize?("serdar" , "xxx").should eq(nil)
credentials.authorize?("dogruyol", "abc").should eq("dogruyol")
credentials.authorize?("dogruyol", "xxx").should eq(nil)
credentials.authorize?("foo" , "bar").should eq(nil)
end

describe "#update" do
credentials = HTTPBasicAuth::Credentials.new

it "(String, String) adds a new entry" do
credentials.authorize?("serdar", "123").should eq(nil)
credentials.update("serdar", "123")
credentials.authorize?("serdar", "123").should eq("serdar")
credentials.authorize?("serdar", "xxx").should eq(nil)
end

it "(Hash) adds new entries" do
credentials.update({"a" => "1", "b" => "2"})
credentials.authorize?("a", "1").should eq("a")
credentials.authorize?("a", "x").should eq(nil)
credentials.authorize?("b", "2").should eq("b")
credentials.authorize?("c", "3").should eq(nil)
end

it "preserves accumulated entries" do
credentials.authorize?("serdar", "123").should eq("serdar")
end
end
end
17 changes: 16 additions & 1 deletion spec/kemal-basic-auth_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,23 @@ describe "HTTPBasicAuth" do
context.kemal_authorized_username?.should eq(nil)
end

it "adds HTTPBasicAuthHandler" do
it "adds HTTPBasicAuthHandler at most once" do
basic_auth "serdar", "123"
Kemal.config.handlers.size.should eq 6

basic_auth "dogruyol", "abc"
Kemal.config.handlers.size.should eq 6
end

describe ".runtime" do
it "returns singleton instance" do
HTTPBasicAuth.runtime.should be_a(HTTPBasicAuth)
end

it "is affected by `basic_auth`" do
HTTPBasicAuth.runtime.authorize?("a", "1").should eq(nil)
basic_auth "a", "1"
HTTPBasicAuth.runtime.authorize?("a", "1").should eq("a")
end
end
end
20 changes: 17 additions & 3 deletions src/kemal-basic-auth.cr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ class HTTPBasicAuth
AUTH_MESSAGE = "Could not verify your access level for that URL.\nYou have to login with proper credentials"
HEADER_LOGIN_REQUIRED = "Basic realm=\"Login Required\""

def initialize(@credentials : Credentials)
# a lazy singleton instance which is automatically added to handler in first access
@@runtime : self?
def self.runtime
@@runtime ||= new.tap{|handler| add_handler handler}
@@runtime.not_nil!
end

getter credentials
delegate update, to: credentials

def initialize(@credentials : Credentials = Credentials.new)
end

# backward compatibility
Expand Down Expand Up @@ -51,15 +61,19 @@ class HTTPBasicAuth

def authorize?(value) : String?
username, password = Base64.decode_string(value[BASIC.size + 1..-1]).split(":")
authorize?(username, password)
end

def authorize?(username : String, password : String) : String?
@credentials.authorize?(username, password)
end
end

# Helper to easily add HTTP Basic Auth support.
def basic_auth(username, password)
add_handler HTTPBasicAuth.new(username, password)
HTTPBasicAuth.runtime.update(username, password)
end

def basic_auth(crendentials : Hash(String, String))
add_handler HTTPBasicAuth.new(crendentials)
HTTPBasicAuth.runtime.update(crendentials)
end
14 changes: 12 additions & 2 deletions src/kemal-basic-auth/credentials.cr
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class HTTPBasicAuth
class HTTPBasicAuth
class Credentials
def initialize(@entries : Hash(String, String) = Hash(String, String).new)
alias Entries = Hash(String, String)

def initialize(@entries : Entries = Entries.new)
end

def authorize?(username : String, password : String) : String?
Expand All @@ -10,5 +12,13 @@ class HTTPBasicAuth
nil
end
end

def update(username : String, password : String)
@entries[username] = password
end

def update(other : Entries)
@entries.merge!(other)
end
end
end

0 comments on commit 7bf6595

Please sign in to comment.