satz 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +4 -0
- data/README.md +48 -2
- data/lib/satz.rb +63 -4
- data/satz.gemspec +1 -1
- data/test/all.rb +61 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ef14c47b68ac506c9096dfa78e62d7e174d3dd4
|
4
|
+
data.tar.gz: eb243d56d8184dda598263589bcbfe7e5580bb2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1025b3c94d78c146c7cee02a24be964ae9b4fef849855d954e3dff793fc901dcd405b175155ea8fb159227a0b9d32ab61854f969242a0e41880aa7430b15fd6
|
7
|
+
data.tar.gz: cb37e3aabca0617d18c8730f815fc3997843a1528b3eca6834c985acd41fec8009486126d4072c229948308efd24a090cb1c2721477d036a20628486bde0b934
|
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -19,7 +19,7 @@ Usage
|
|
19
19
|
An example of a Satz application would look like this:
|
20
20
|
|
21
21
|
```ruby
|
22
|
-
App = Satz.
|
22
|
+
App = Satz.define do
|
23
23
|
on "players" do
|
24
24
|
on :player_id do
|
25
25
|
get do
|
@@ -55,15 +55,61 @@ In user defined objects, you can define the method `to_json` according
|
|
55
55
|
to your needs. Most ORMs already provide meaningful definitions for
|
56
56
|
that method.
|
57
57
|
|
58
|
+
Authentication
|
59
|
+
--------------
|
60
|
+
|
61
|
+
The `auth` method checks if Basic Auth headers were provided and
|
62
|
+
returns `nil` otherwise. If it's able to access the supplied
|
63
|
+
credentials, it yield the username and password and returns the
|
64
|
+
result (if it's not false) or nil.
|
65
|
+
|
66
|
+
Here's an example of how to use it:
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
@user = auth do |user, pass|
|
70
|
+
|
71
|
+
# Here you can use any method of your
|
72
|
+
# choice. The example is from Shield.
|
73
|
+
User.authenticate(user, pass)
|
74
|
+
end
|
75
|
+
|
76
|
+
on @user.nil? do
|
77
|
+
res.status = 401
|
78
|
+
reply(error: "Unauthorized")
|
79
|
+
end
|
80
|
+
```
|
81
|
+
|
82
|
+
Anything defined after that `on` block will be executed only if the
|
83
|
+
authentication succeded.
|
84
|
+
|
85
|
+
Serialization
|
86
|
+
-------------
|
87
|
+
|
88
|
+
The default serializer is `JSON`, but it can be customized by
|
89
|
+
supplying a serializer:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
Satz.serializer = MySerializer
|
93
|
+
```
|
94
|
+
|
95
|
+
A serializer must respond to `load(arg)` and `dump(arg)`, and that's
|
96
|
+
the only restriction. Note that the supplied serializer will be used
|
97
|
+
by all `Satz` applications.
|
98
|
+
|
58
99
|
API
|
59
100
|
---
|
60
101
|
|
61
102
|
Apart from [Syro][syro]'s API, the following methods are available:
|
62
103
|
|
63
|
-
`
|
104
|
+
`auth`: Process Basic Auth headers and yield username and password.
|
105
|
+
|
106
|
+
`read`: Reads the body of the request and parses it as JSON.
|
64
107
|
|
65
108
|
`reply`: Writes to the response its argument encoded as JSON.
|
66
109
|
|
110
|
+
Installation
|
111
|
+
------------
|
112
|
+
|
67
113
|
```
|
68
114
|
$ gem install satz
|
69
115
|
```
|
data/lib/satz.rb
CHANGED
@@ -22,24 +22,83 @@
|
|
22
22
|
|
23
23
|
require "syro"
|
24
24
|
require "json"
|
25
|
+
require "base64"
|
25
26
|
|
26
27
|
class Satz
|
28
|
+
|
29
|
+
# The JSON module from stdlib provides a safe way of loading data
|
30
|
+
# with the `parse` method, but the most widespread API for encoding
|
31
|
+
# and decoding data is with the `load` and `dump` methods, which in
|
32
|
+
# the case of JSON are unsafe. This module wraps the JSON constant
|
33
|
+
# from stdlib in order to expose a safe version of `load`. As the
|
34
|
+
# serializer is configurable, the user is expected to provide
|
35
|
+
# objects that respond safely to those methods.
|
36
|
+
module Serializer
|
37
|
+
def self.load(value)
|
38
|
+
JSON.load(value, nil, create_additions: false)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.dump(value)
|
42
|
+
JSON.dump(value)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
@@serializer = Serializer
|
47
|
+
|
48
|
+
def self.serializer
|
49
|
+
@@serializer
|
50
|
+
end
|
51
|
+
|
52
|
+
# Modify the serializer to be used for all Satz applications.
|
53
|
+
# The serializer object must reply to `load(arg)` and `dump(arg)`.
|
54
|
+
def self.serializer=(value)
|
55
|
+
@@serializer = value
|
56
|
+
end
|
57
|
+
|
27
58
|
class Deck < Syro::Deck
|
59
|
+
HTTP_AUTHORIZATION = "HTTP_AUTHORIZATION".freeze
|
60
|
+
|
61
|
+
# Checks the Basic Auth headers and yields
|
62
|
+
# user and pass if credentials are provided.
|
63
|
+
# Returns nil if there are no credentials or
|
64
|
+
# if the block returns false or nil.
|
65
|
+
#
|
66
|
+
# Usage:
|
67
|
+
#
|
68
|
+
# @user = auth do |user, pass|
|
69
|
+
# User.authenticate(user, pass)
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# on @user.nil? do
|
73
|
+
# res.status = 401
|
74
|
+
# reply(error: "Unauthorized")
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
def auth
|
78
|
+
http_auth = env.fetch(HTTP_AUTHORIZATION) do
|
79
|
+
return nil
|
80
|
+
end
|
81
|
+
|
82
|
+
cred = http_auth.split(" ")[1]
|
83
|
+
user, pass = Base64.decode64(cred).split(":")
|
84
|
+
|
85
|
+
yield(user, pass) || nil
|
86
|
+
end
|
28
87
|
|
29
|
-
# Respond by default with JSON.
|
88
|
+
# Respond by default with JSON. The default charset
|
89
|
+
# for "application/json" is UTF-8.
|
30
90
|
def default_headers
|
31
91
|
{ "Content-Type" => "application/json" }
|
32
92
|
end
|
33
93
|
|
34
94
|
# Read JSON data from the POST request.
|
35
95
|
def read
|
36
|
-
|
37
|
-
body && JSON.parse(body)
|
96
|
+
Satz.serializer.load(req.body.read)
|
38
97
|
end
|
39
98
|
|
40
99
|
# Write JSON data to the response.
|
41
100
|
def reply(data)
|
42
|
-
res.write(
|
101
|
+
res.write(Satz.serializer.dump(data))
|
43
102
|
end
|
44
103
|
end
|
45
104
|
|
data/satz.gemspec
CHANGED
data/test/all.rb
CHANGED
@@ -1,22 +1,37 @@
|
|
1
|
-
|
1
|
+
A1 = Satz.define do
|
2
2
|
get do
|
3
|
-
reply(
|
3
|
+
reply(read)
|
4
4
|
end
|
5
5
|
|
6
6
|
post do
|
7
7
|
reply(read)
|
8
8
|
end
|
9
|
+
|
10
|
+
on "protected" do
|
11
|
+
@user = auth do |user, pass|
|
12
|
+
user == "foo" && pass == "bar"
|
13
|
+
end
|
14
|
+
|
15
|
+
on @user.nil? do
|
16
|
+
res.status = 401
|
17
|
+
reply(error: "Unauthorized")
|
18
|
+
end
|
19
|
+
|
20
|
+
get do
|
21
|
+
reply(true)
|
22
|
+
end
|
23
|
+
end
|
9
24
|
end
|
10
25
|
|
11
26
|
setup do
|
12
|
-
Driver.new(
|
27
|
+
Driver.new(A1)
|
13
28
|
end
|
14
29
|
|
15
30
|
test "get" do |app|
|
16
31
|
app.get("/")
|
17
32
|
|
18
33
|
assert_equal 200, app.last_response.status
|
19
|
-
assert_equal %Q(
|
34
|
+
assert_equal %Q(null), app.last_response.body
|
20
35
|
end
|
21
36
|
|
22
37
|
test "post" do |app|
|
@@ -27,3 +42,45 @@ test "post" do |app|
|
|
27
42
|
assert_equal data, app.last_response.body
|
28
43
|
assert_equal 200, app.last_response.status
|
29
44
|
end
|
45
|
+
|
46
|
+
test "auth" do |app|
|
47
|
+
app.get("/protected")
|
48
|
+
|
49
|
+
assert_equal %Q({"error":"Unauthorized"}), app.last_response.body
|
50
|
+
assert_equal 401, app.last_response.status
|
51
|
+
|
52
|
+
app.authorize("foo", "bar")
|
53
|
+
|
54
|
+
app.get("/protected")
|
55
|
+
|
56
|
+
assert_equal %Q(true), app.last_response.body
|
57
|
+
end
|
58
|
+
|
59
|
+
module Reverser
|
60
|
+
def self.load(data)
|
61
|
+
data
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.dump(data)
|
65
|
+
data.reverse
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
Satz.serializer = Reverser
|
70
|
+
|
71
|
+
A2 = Satz.define do
|
72
|
+
get do
|
73
|
+
reply("hello")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
setup do
|
78
|
+
Driver.new(A2)
|
79
|
+
end
|
80
|
+
|
81
|
+
test "get" do |app|
|
82
|
+
app.get("/")
|
83
|
+
|
84
|
+
assert_equal 200, app.last_response.status
|
85
|
+
assert_equal %Q(olleh), app.last_response.body
|
86
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: satz
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: syro
|