tentd 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +8 -0
- data/Gemfile +9 -0
- data/Guardfile +6 -0
- data/LICENSE.txt +22 -0
- data/README.md +49 -0
- data/Rakefile +8 -0
- data/bin/tent-server +3 -0
- data/lib/tentd.rb +31 -0
- data/lib/tentd/api.rb +58 -0
- data/lib/tentd/api/apps.rb +196 -0
- data/lib/tentd/api/authentication_finalize.rb +12 -0
- data/lib/tentd/api/authentication_lookup.rb +27 -0
- data/lib/tentd/api/authentication_verification.rb +50 -0
- data/lib/tentd/api/authorizable.rb +21 -0
- data/lib/tentd/api/authorization.rb +14 -0
- data/lib/tentd/api/core_profile_data.rb +45 -0
- data/lib/tentd/api/followers.rb +218 -0
- data/lib/tentd/api/followings.rb +241 -0
- data/lib/tentd/api/groups.rb +161 -0
- data/lib/tentd/api/middleware.rb +32 -0
- data/lib/tentd/api/posts.rb +373 -0
- data/lib/tentd/api/profile.rb +78 -0
- data/lib/tentd/api/router.rb +123 -0
- data/lib/tentd/api/router/caching_headers.rb +49 -0
- data/lib/tentd/api/router/extract_params.rb +88 -0
- data/lib/tentd/api/router/serialize_response.rb +38 -0
- data/lib/tentd/api/user_lookup.rb +10 -0
- data/lib/tentd/core_ext/hash/slice.rb +29 -0
- data/lib/tentd/datamapper/array_property.rb +23 -0
- data/lib/tentd/datamapper/query.rb +19 -0
- data/lib/tentd/json_patch.rb +181 -0
- data/lib/tentd/model.rb +30 -0
- data/lib/tentd/model/app.rb +68 -0
- data/lib/tentd/model/app_authorization.rb +113 -0
- data/lib/tentd/model/follower.rb +105 -0
- data/lib/tentd/model/following.rb +100 -0
- data/lib/tentd/model/group.rb +24 -0
- data/lib/tentd/model/mention.rb +19 -0
- data/lib/tentd/model/notification_subscription.rb +56 -0
- data/lib/tentd/model/permissible.rb +227 -0
- data/lib/tentd/model/permission.rb +28 -0
- data/lib/tentd/model/post.rb +178 -0
- data/lib/tentd/model/post_attachment.rb +27 -0
- data/lib/tentd/model/post_version.rb +64 -0
- data/lib/tentd/model/profile_info.rb +80 -0
- data/lib/tentd/model/random_public_id.rb +46 -0
- data/lib/tentd/model/serializable.rb +58 -0
- data/lib/tentd/model/type_properties.rb +36 -0
- data/lib/tentd/model/user.rb +39 -0
- data/lib/tentd/model/user_scoped.rb +14 -0
- data/lib/tentd/notifications.rb +13 -0
- data/lib/tentd/notifications/girl_friday.rb +30 -0
- data/lib/tentd/notifications/sidekiq.rb +50 -0
- data/lib/tentd/tent_type.rb +20 -0
- data/lib/tentd/tent_version.rb +41 -0
- data/lib/tentd/version.rb +3 -0
- data/spec/fabricators/app_authorizations_fabricator.rb +5 -0
- data/spec/fabricators/apps_fabricator.rb +11 -0
- data/spec/fabricators/followers_fabricator.rb +14 -0
- data/spec/fabricators/followings_fabricator.rb +17 -0
- data/spec/fabricators/groups_fabricator.rb +3 -0
- data/spec/fabricators/mentions_fabricator.rb +3 -0
- data/spec/fabricators/notification_subscriptions_fabricator.rb +4 -0
- data/spec/fabricators/permissions_fabricator.rb +1 -0
- data/spec/fabricators/post_attachments_fabricator.rb +8 -0
- data/spec/fabricators/post_versions_fabricator.rb +12 -0
- data/spec/fabricators/posts_fabricator.rb +12 -0
- data/spec/fabricators/profile_infos_fabricator.rb +30 -0
- data/spec/integration/api/apps_spec.rb +466 -0
- data/spec/integration/api/followers_spec.rb +535 -0
- data/spec/integration/api/followings_spec.rb +688 -0
- data/spec/integration/api/groups_spec.rb +207 -0
- data/spec/integration/api/posts_spec.rb +874 -0
- data/spec/integration/api/profile_spec.rb +285 -0
- data/spec/integration/api/router_spec.rb +102 -0
- data/spec/integration/model/app_authorization_spec.rb +59 -0
- data/spec/integration/model/app_spec.rb +63 -0
- data/spec/integration/model/follower_spec.rb +344 -0
- data/spec/integration/model/following_spec.rb +97 -0
- data/spec/integration/model/group_spec.rb +39 -0
- data/spec/integration/model/notification_subscription_spec.rb +145 -0
- data/spec/integration/model/post_spec.rb +658 -0
- data/spec/spec_helper.rb +37 -0
- data/spec/support/expect_server.rb +3 -0
- data/spec/support/json_request.rb +54 -0
- data/spec/support/with_constant.rb +23 -0
- data/spec/support/with_warnings.rb +6 -0
- data/spec/unit/api/authentication_finalize_spec.rb +45 -0
- data/spec/unit/api/authentication_lookup_spec.rb +65 -0
- data/spec/unit/api/authentication_verification_spec.rb +50 -0
- data/spec/unit/api/authorizable_spec.rb +50 -0
- data/spec/unit/api/authorization_spec.rb +44 -0
- data/spec/unit/api/caching_headers_spec.rb +121 -0
- data/spec/unit/core_profile_data_spec.rb +64 -0
- data/spec/unit/json_patch_spec.rb +407 -0
- data/spec/unit/tent_type_spec.rb +28 -0
- data/spec/unit/tent_version_spec.rb +68 -0
- data/tentd.gemspec +36 -0
- metadata +435 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --backtrace
|
data/.travis.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
source_key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBM2Nvc0tLYnJWQllHTlI5WEE5WTc1L2FJbndPUWZ6L1dzK29GblQrR1hhVzV0Y3poCnpybTlyckU4WkpTWmtOaEpQQkZaMEpLMjI2M3FWSHkxWW45MC9XdUZ0aEZxbGdVNUgxbS9TTHJuelgrUzd2NHcKZk9zWU1xV1VvNVNzVXpLV3B0REhXNjMvQjlCNjBtck9OZnkwRU0yZjM0b05GMTlLTFM5ZTZKQ2t0aWViQXg2VAppaXE2OEtkVW5rODNVZjhYRkVOWi9iK2p3N2FaekdQNVY0R0JvMmhud1hEbFUxanlwNkVnVFUzdThNWFpHRUU2CjV4MWJlYmtIYUdPZXlGRUNTQUJsTEZBUGwrMDZsNEluaE0rMC9RSmJUTnlWdUNHaUtDNStlU3FwREdtdlJxK3MKTC9sNG9zMTBOUEdLU0c1eDRXcFIycUVRQXVxYTZPV0dTMlE0SHdJREFRQUJBb0lCQVFDeXlrckV6cUtBVzJ6UApvQjhHUWNwekdRTlRwSXowZDZMOTBCYU1oK3dxUy9Ha1E3QjRkTFViUVZjZEFjbTF3UlZ3YmRCSVdpMDhkRHVsCnRnNkdnNWJzdjZPL2ZOUytjU0YyUzJQdkhuVEU3U1dtc1pTbTd1SEgya0V6aVNOTndrYzkzS29KRnYreTdmWkUKNzhLaU5MOTNtRHRiK2E3Sis1QVJVdEdnaXhHc29Fb3FYeU9xYVJNNFBmK1pwSHZYcVZLR2xUM0tNaDBCQVM4TQpuK1ZtblpzRDUyMFNETXR0SUJQYXg3U2pPb2NQQ3lmOEt5dHVxblRRSC9RMjVsSE5HcmI1VmQxYzd4dFJ1SlRDCnVGWmFhczAwSzZBUG5uZDZkak1rM3kxSTJSNG8vRUlBOFZhRWNoc0ZCUXd5ZGlxQThkL0gyZTd5czRBd1RHL0sKbVFBMzk0eDVBb0dCQVBwUnNRdStib1dvclFRWC9teTdyU0M4QzFRQmlYQVBNUGxhU3A1d29WMlEzbnQzL1l4TApYbVh6SFdBTlU2dWo2Q01vTHg3UWtXMGppOXFySk9aR2JUejZ0VTFBOHFHL28yRVVKSldJN3F0Qnh5R291YS8yCjcraDliOGJYZDBNZDVWYXp5S21hSEE5aHA3Qm04Y2hpaTlNUUhBTFVrNUIwbyt5azhoUHVFOXl6QW9HQkFPTFMKdXY5ZE8wdm9wTVA2aHpYYitIamJodkZJVXBudTNOR2srQVdWQ3Rlc2NHRzZkMUdqR1loaUxmN2p5eGdUQ3NBegpBek9kVEs3eXI5bXZpTHJKb2J2a05pbG5SNzBnRHNkckJuK2p0ajQvb1MwaUpRWTB6WlpSVTZ2bzhIM3cvSGxyCjVMRVFPOUVGOCs1bWRlT3lIMDI4b1lUY1IvaWNTcC9vV3RiTG53VGxBb0dBWWh5WXp5aVJ1ek9VdE5FT3VPR0sKaHhVTlA1em1tSlJydHFCTU5QT2lXOEVIWXM5eUFvWWI5c3VtVE5xTVcrNy9jcUF5YjlxQjFZd2tLYzRBeFh6LwpIZktLRTBDTW1SYzYyemNBNjlkaTdKNzRoTm5VQmdNOG54eGpMa1dQaWkveWp0d2luMDgzQmxSWlhJdk00cVMxCmQwR09LUkhXMEx6VzcwN3JUeUoyaUg4Q2dZRUF3cGdwNStWemRzZExlL3NXUHdYTjRObnRwbGoyekt0WmRONkUKRGozMHhGMWpPT1RCY3g5clMwOTN5SUpqZmU3d1BUNUdrK1J5b25FQW50QnlqRlZwMVFtUDBldVNaMVgyZCsyQQo4TVppRm50K2Fuc3RxbXBvcW5weFB6NGovTmhmc2tmM05sVUlER2FBQk5xUWIxMGtjQXZSd21zOXI3TmVibHZvCmV2ak1IMlVDZ1lFQWpnYlRGcnV0Ri9Kam82bW4zYW1HNVBWVGJ1S2NRUEdwUEZWRm1tZFlreCthRXk4b2xEV1EKcFF2Y0k0U0F4UVRnaGFXOUZkc3ZBUEtVMkdUbTZFR2VlR0ZuMERTZExPZ2ZLSW52UFMrbUo3NEhBTnllQWpmbApxR1diTWJRcXFtclQ4akVFemNRWENZYnVNZndZOTJyTVZwVXhRc3VVb1dzWXN2aVFkOGM5ZlN3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
2
|
+
before_script:
|
3
|
+
- psql -c 'create database tentd_test;' -U postgres
|
4
|
+
env:
|
5
|
+
- TEST_DATABASE_URL=postgres://postgres@localhost/tentd_test
|
6
|
+
rvm:
|
7
|
+
- 1.9.3
|
8
|
+
- rbx-19mode
|
data/Gemfile
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
4
|
+
|
5
|
+
gem 'rack-test', :git => 'https://github.com/brynary/rack-test.git'
|
6
|
+
gem 'tent-client', :git => 'git://github.com/tent/tent-client-ruby.git', :branch => 'master'
|
7
|
+
gem 'rb-fsevent', '~> 0.9.1'
|
8
|
+
gem 'do_jdbc', :platform => :jruby
|
9
|
+
gem 'girl_friday', '~> 0.10'
|
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Apollic Software, LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# tentd ![Build Status](https://magnum.travis-ci.com/tent/tentd.png?branch=master&token=YmxLSPgdpsxNUMWJpzRx)
|
2
|
+
|
3
|
+
tentd is an **alpha** implementation of a [Tent Protocol](http://tent.io) server.
|
4
|
+
It currently contains **broken code, ugly code, many bugs, and security flaws**.
|
5
|
+
The code should only be used to experiment with how Tent works. Under no
|
6
|
+
circumstances should the code in its current form be used for data that is
|
7
|
+
supposed to be private. All of the implemented APIs are in flux, and are
|
8
|
+
expected to change heavily before the Tent 1.0 release.
|
9
|
+
|
10
|
+
|
11
|
+
## Requirements
|
12
|
+
|
13
|
+
TentD is written using Ruby 1.9 with Rack and Datamapper and is only tested with
|
14
|
+
PostgreSQL. The code needs a few fixes to work with 1.8 and other databases.
|
15
|
+
|
16
|
+
If you have Ruby 1.9, Bundler, and PostgreSQL installed, this should get the
|
17
|
+
tests running:
|
18
|
+
|
19
|
+
```shell
|
20
|
+
createdb tent_server_test
|
21
|
+
bundle install
|
22
|
+
rake
|
23
|
+
```
|
24
|
+
|
25
|
+
If you want to run this as a Tent server, you should use
|
26
|
+
[tentd-admin](https://github.com/tent/tentd-admin).
|
27
|
+
|
28
|
+
|
29
|
+
## Contributions
|
30
|
+
|
31
|
+
If you want to help out with the TentD code instead of writing Tent clients and
|
32
|
+
applications, here are some areas that can be worked on:
|
33
|
+
|
34
|
+
- Fix database queries. There are a bunch of suboptimal uses of the database,
|
35
|
+
and basically no indexes. Low hanging fruit would be to turn on logging while
|
36
|
+
running the tests and index all the queries.
|
37
|
+
- Add data validation/normalization.
|
38
|
+
- Audit security.
|
39
|
+
- Refactor. The current code was hacked together quickly and is pretty ugly.
|
40
|
+
- Add tests. There are quite a few areas that aren't tested completely.
|
41
|
+
- Fix tests. A lot of tests are written as integration tests and depend on the
|
42
|
+
database, many would be much faster as unit tests that don't hit the database.
|
43
|
+
|
44
|
+
Please note that we are not looking for Pull Requests that make fundamental
|
45
|
+
changes to how the Tent Protocol works.
|
46
|
+
|
47
|
+
### Contributors
|
48
|
+
|
49
|
+
- [Jonas Schneider](https://github.com/jonasschneider)
|
data/Rakefile
ADDED
data/bin/tent-server
ADDED
data/lib/tentd.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'tentd/version'
|
2
|
+
require 'tent-client'
|
3
|
+
|
4
|
+
module TentD
|
5
|
+
autoload :API, 'tentd/api'
|
6
|
+
autoload :Action, 'tentd/action'
|
7
|
+
autoload :JsonPatch, 'tentd/json_patch'
|
8
|
+
autoload :TentVersion, 'tentd/tent_version'
|
9
|
+
autoload :TentType, 'tentd/tent_type'
|
10
|
+
|
11
|
+
def self.new(options={})
|
12
|
+
if options[:database] || ENV['DATABASE_URL']
|
13
|
+
DataMapper.setup(:default, options[:database] || ENV['DATABASE_URL'])
|
14
|
+
end
|
15
|
+
|
16
|
+
require "tentd/notifications/#{options[:job_backend] || 'girl_friday'}"
|
17
|
+
|
18
|
+
@faraday_adapter = options[:faraday_adapter]
|
19
|
+
API.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.faraday_adapter
|
23
|
+
@faraday_adapter
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.faraday_adapter=(a)
|
27
|
+
@faraday_adapter = a
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
require 'tentd/model'
|
data/lib/tentd/api.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
module TentD
|
2
|
+
class API
|
3
|
+
PER_PAGE = 50
|
4
|
+
MAX_PER_PAGE = 200
|
5
|
+
MEDIA_TYPE = 'application/vnd.tent.v0+json'.freeze
|
6
|
+
PROFILE_REL = 'https://tent.io/rels/profile'.freeze
|
7
|
+
|
8
|
+
autoload :Apps, 'tentd/api/apps'
|
9
|
+
autoload :Posts, 'tentd/api/posts'
|
10
|
+
autoload :Groups, 'tentd/api/groups'
|
11
|
+
autoload :Profile, 'tentd/api/profile'
|
12
|
+
autoload :Followers, 'tentd/api/followers'
|
13
|
+
autoload :Followings, 'tentd/api/followings'
|
14
|
+
autoload :CoreProfileData, 'tentd/api/core_profile_data'
|
15
|
+
autoload :UserLookup, 'tentd/api/user_lookup'
|
16
|
+
autoload :AuthenticationLookup, 'tentd/api/authentication_lookup'
|
17
|
+
autoload :AuthenticationVerification, 'tentd/api/authentication_verification'
|
18
|
+
autoload :AuthenticationFinalize, 'tentd/api/authentication_finalize'
|
19
|
+
autoload :Authorization, 'tentd/api/authorization'
|
20
|
+
autoload :Authorizable, 'tentd/api/authorizable'
|
21
|
+
autoload :Router, 'tentd/api/router'
|
22
|
+
autoload :Middleware, 'tentd/api/middleware'
|
23
|
+
include Router
|
24
|
+
|
25
|
+
mount Apps
|
26
|
+
mount Posts
|
27
|
+
mount Groups
|
28
|
+
mount Profile
|
29
|
+
mount Followers
|
30
|
+
mount Followings
|
31
|
+
|
32
|
+
class HelloWorld < Middleware
|
33
|
+
def action(env)
|
34
|
+
[200, { 'Link' => %(<%s>; rel="%s") % [File.join(env['SCRIPT_NAME'], 'profile'), PROFILE_REL] }, ['Tent!']]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class CorsPreflight < Middleware
|
39
|
+
def action(env)
|
40
|
+
headers = {
|
41
|
+
'Access-Control-Allow-Origin' => '*',
|
42
|
+
'Access-Control-Allow-Methods' => 'GET, POST, HEAD, PUT, DELETE, PATCH, OPTIONS',
|
43
|
+
'Access-Control-Allow-Headers' => 'Authorization',
|
44
|
+
'Access-Control-Max-Age' => '2592000' # 30 days
|
45
|
+
}
|
46
|
+
[200, headers, []]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
get '/' do |b|
|
51
|
+
b.use HelloWorld
|
52
|
+
end
|
53
|
+
|
54
|
+
options %r{/.*} do |b|
|
55
|
+
b.use CorsPreflight
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
module TentD
|
2
|
+
class API
|
3
|
+
class Apps
|
4
|
+
include Router
|
5
|
+
|
6
|
+
class GetActualId < Middleware
|
7
|
+
def action(env)
|
8
|
+
if env.params.app_id
|
9
|
+
if app = Model::App.first(:public_id => env.params.app_id)
|
10
|
+
env.params.app_id = app.id
|
11
|
+
else
|
12
|
+
env.params.app_id = nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
if env.params.auth_id
|
17
|
+
if app_auth = Model::AppAuthorization.first(:public_id => env.params.auth_id)
|
18
|
+
env.params.auth_id = app_auth.id
|
19
|
+
else
|
20
|
+
env.params.auth_id = nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
env
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class AuthorizeReadOne < Middleware
|
29
|
+
def action(env)
|
30
|
+
authorize_env!(env, :read_apps) unless env.params.app_id && env.current_auth &&
|
31
|
+
env.current_auth.kind_of?(Model::App) &&
|
32
|
+
env.current_auth.id == env.params.app_id
|
33
|
+
env
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class AuthorizeReadAll < Middleware
|
38
|
+
def action(env)
|
39
|
+
authorize_env!(env, :read_apps)
|
40
|
+
env
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class AuthorizeWriteOne < Middleware
|
45
|
+
def action(env)
|
46
|
+
authorize_env!(env, :write_apps) unless env.params.app_id && env.current_auth &&
|
47
|
+
env.current_auth.kind_of?(Model::App) &&
|
48
|
+
env.current_auth.id == env.params.app_id
|
49
|
+
env
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class GetOne < Middleware
|
54
|
+
def action(env)
|
55
|
+
if app = Model::App.first(:id => env.params.app_id)
|
56
|
+
env.response = app
|
57
|
+
end
|
58
|
+
env
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class GetAll < Middleware
|
63
|
+
def action(env)
|
64
|
+
env.response = Model::App.all
|
65
|
+
env
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Create < Middleware
|
70
|
+
def action(env)
|
71
|
+
env.response = Model::App.create_from_params(env.params.data)
|
72
|
+
env.authorized_scopes << :read_secrets
|
73
|
+
env
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class CreateAuthorization < Middleware
|
78
|
+
def action(env)
|
79
|
+
unless authorize_env?(env, :write_apps)
|
80
|
+
if env.params.data.code
|
81
|
+
return AuthorizationTokenExchange.new(@app).call(env)
|
82
|
+
else
|
83
|
+
authorize_env!(env, :write_apps)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
if app = Model::App.first(:id => env.params.app_id)
|
88
|
+
env.authorized_scopes << :authorization_token
|
89
|
+
authorization = app.authorizations.create_from_params(
|
90
|
+
:app_id => env.params.app_id,
|
91
|
+
:notification_url => env.params.data.notification_url,
|
92
|
+
:post_types => env.params.data.post_types.to_a.map { |url| URI.decode(url) },
|
93
|
+
:profile_info_types => env.params.data.profile_info_types.to_a.map { |url| URI.decode(url) },
|
94
|
+
:scopes => env.params.data.scopes
|
95
|
+
)
|
96
|
+
env.response = authorization
|
97
|
+
end
|
98
|
+
env
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class AuthorizationTokenExchange < Middleware
|
103
|
+
def action(env)
|
104
|
+
if authorization = Model::AppAuthorization.first(:app_id => env.params.app_id, :token_code => env.params.data.code)
|
105
|
+
env.response = authorization.token_exchange!
|
106
|
+
else
|
107
|
+
raise Unauthorized
|
108
|
+
end
|
109
|
+
env
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
class Update < Middleware
|
114
|
+
def action(env)
|
115
|
+
if app = Model::App.update_from_params(env.params.app_id, env.params.data)
|
116
|
+
env.response = app
|
117
|
+
end
|
118
|
+
env
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
class UpdateAppAuthorization < Middleware
|
123
|
+
def action(env)
|
124
|
+
authorize_env!(env, :write_apps)
|
125
|
+
if (auth = TentD::Model::AppAuthorization.first(:app_id => env.params.app_id, :id => env.params.auth_id)) &&
|
126
|
+
auth.update_from_params(env.params.data)
|
127
|
+
env.response = auth
|
128
|
+
end
|
129
|
+
env
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
class Destroy < Middleware
|
134
|
+
def action(env)
|
135
|
+
if (app = Model::App.get(env.params.app_id)) && app.destroy
|
136
|
+
env.response = ''
|
137
|
+
end
|
138
|
+
env
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class DestroyAppAuthorization < Middleware
|
143
|
+
def action(env)
|
144
|
+
authorize_env!(env, :write_apps)
|
145
|
+
if (auth = TentD::Model::AppAuthorization.first(:app_id => env.params.app_id, :id => env.params.auth_id)) &&
|
146
|
+
auth.destroy
|
147
|
+
env.response = ''
|
148
|
+
end
|
149
|
+
env
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
get '/apps/:app_id' do |b|
|
154
|
+
b.use GetActualId
|
155
|
+
b.use AuthorizeReadOne
|
156
|
+
b.use GetOne
|
157
|
+
end
|
158
|
+
|
159
|
+
get '/apps' do |b|
|
160
|
+
b.use AuthorizeReadAll
|
161
|
+
b.use GetAll
|
162
|
+
end
|
163
|
+
|
164
|
+
post '/apps' do |b|
|
165
|
+
b.use Create
|
166
|
+
end
|
167
|
+
|
168
|
+
post '/apps/:app_id/authorizations' do |b|
|
169
|
+
b.use GetActualId
|
170
|
+
b.use CreateAuthorization
|
171
|
+
end
|
172
|
+
|
173
|
+
put '/apps/:app_id/authorizations/:auth_id' do |b|
|
174
|
+
b.use GetActualId
|
175
|
+
b.use UpdateAppAuthorization
|
176
|
+
end
|
177
|
+
|
178
|
+
delete '/apps/:app_id/authorizations/:auth_id' do |b|
|
179
|
+
b.use GetActualId
|
180
|
+
b.use DestroyAppAuthorization
|
181
|
+
end
|
182
|
+
|
183
|
+
put '/apps/:app_id' do |b|
|
184
|
+
b.use GetActualId
|
185
|
+
b.use AuthorizeWriteOne
|
186
|
+
b.use Update
|
187
|
+
end
|
188
|
+
|
189
|
+
delete '/apps/:app_id' do |b|
|
190
|
+
b.use GetActualId
|
191
|
+
b.use AuthorizeWriteOne
|
192
|
+
b.use Destroy
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module TentD
|
2
|
+
class API
|
3
|
+
class AuthenticationFinalize < Middleware
|
4
|
+
def action(env)
|
5
|
+
return env unless env.hmac? && env.hmac.verified
|
6
|
+
env.current_auth = env.potential_auth
|
7
|
+
env.current_auth.update(:mac_timestamp_delta => Time.now.to_i - env.hmac.ts.to_i) unless env.current_auth.mac_timestamp_delta
|
8
|
+
env
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module TentD
|
2
|
+
class API
|
3
|
+
class AuthenticationLookup < Middleware
|
4
|
+
def action(env)
|
5
|
+
return env unless env['HTTP_AUTHORIZATION']
|
6
|
+
env['hmac'] = Hash[env['HTTP_AUTHORIZATION'].scan(/([a-z]+)="([^"]+)"/i)]
|
7
|
+
mac_key_id = env['hmac']['id']
|
8
|
+
env.potential_auth = case mac_key_id.to_s[0,1]
|
9
|
+
when 's'
|
10
|
+
TentD::Model::Follower.first(:mac_key_id => mac_key_id)
|
11
|
+
when 'a'
|
12
|
+
TentD::Model::App.first(:mac_key_id => mac_key_id)
|
13
|
+
when 'u'
|
14
|
+
TentD::Model::AppAuthorization.first(:mac_key_id => mac_key_id)
|
15
|
+
end
|
16
|
+
env.potential_auth = Model::Following.first(:mac_key_id => mac_key_id) unless env.potential_auth
|
17
|
+
if env.potential_auth
|
18
|
+
env.hmac.secret = env.potential_auth.mac_key
|
19
|
+
env.hmac.algorithm = env.potential_auth.mac_algorithm
|
20
|
+
else
|
21
|
+
env.hmac = nil
|
22
|
+
end
|
23
|
+
env
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|