tentd 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. data/.gitignore +18 -0
  2. data/.rspec +1 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +9 -0
  5. data/Guardfile +6 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +49 -0
  8. data/Rakefile +8 -0
  9. data/bin/tent-server +3 -0
  10. data/lib/tentd.rb +31 -0
  11. data/lib/tentd/api.rb +58 -0
  12. data/lib/tentd/api/apps.rb +196 -0
  13. data/lib/tentd/api/authentication_finalize.rb +12 -0
  14. data/lib/tentd/api/authentication_lookup.rb +27 -0
  15. data/lib/tentd/api/authentication_verification.rb +50 -0
  16. data/lib/tentd/api/authorizable.rb +21 -0
  17. data/lib/tentd/api/authorization.rb +14 -0
  18. data/lib/tentd/api/core_profile_data.rb +45 -0
  19. data/lib/tentd/api/followers.rb +218 -0
  20. data/lib/tentd/api/followings.rb +241 -0
  21. data/lib/tentd/api/groups.rb +161 -0
  22. data/lib/tentd/api/middleware.rb +32 -0
  23. data/lib/tentd/api/posts.rb +373 -0
  24. data/lib/tentd/api/profile.rb +78 -0
  25. data/lib/tentd/api/router.rb +123 -0
  26. data/lib/tentd/api/router/caching_headers.rb +49 -0
  27. data/lib/tentd/api/router/extract_params.rb +88 -0
  28. data/lib/tentd/api/router/serialize_response.rb +38 -0
  29. data/lib/tentd/api/user_lookup.rb +10 -0
  30. data/lib/tentd/core_ext/hash/slice.rb +29 -0
  31. data/lib/tentd/datamapper/array_property.rb +23 -0
  32. data/lib/tentd/datamapper/query.rb +19 -0
  33. data/lib/tentd/json_patch.rb +181 -0
  34. data/lib/tentd/model.rb +30 -0
  35. data/lib/tentd/model/app.rb +68 -0
  36. data/lib/tentd/model/app_authorization.rb +113 -0
  37. data/lib/tentd/model/follower.rb +105 -0
  38. data/lib/tentd/model/following.rb +100 -0
  39. data/lib/tentd/model/group.rb +24 -0
  40. data/lib/tentd/model/mention.rb +19 -0
  41. data/lib/tentd/model/notification_subscription.rb +56 -0
  42. data/lib/tentd/model/permissible.rb +227 -0
  43. data/lib/tentd/model/permission.rb +28 -0
  44. data/lib/tentd/model/post.rb +178 -0
  45. data/lib/tentd/model/post_attachment.rb +27 -0
  46. data/lib/tentd/model/post_version.rb +64 -0
  47. data/lib/tentd/model/profile_info.rb +80 -0
  48. data/lib/tentd/model/random_public_id.rb +46 -0
  49. data/lib/tentd/model/serializable.rb +58 -0
  50. data/lib/tentd/model/type_properties.rb +36 -0
  51. data/lib/tentd/model/user.rb +39 -0
  52. data/lib/tentd/model/user_scoped.rb +14 -0
  53. data/lib/tentd/notifications.rb +13 -0
  54. data/lib/tentd/notifications/girl_friday.rb +30 -0
  55. data/lib/tentd/notifications/sidekiq.rb +50 -0
  56. data/lib/tentd/tent_type.rb +20 -0
  57. data/lib/tentd/tent_version.rb +41 -0
  58. data/lib/tentd/version.rb +3 -0
  59. data/spec/fabricators/app_authorizations_fabricator.rb +5 -0
  60. data/spec/fabricators/apps_fabricator.rb +11 -0
  61. data/spec/fabricators/followers_fabricator.rb +14 -0
  62. data/spec/fabricators/followings_fabricator.rb +17 -0
  63. data/spec/fabricators/groups_fabricator.rb +3 -0
  64. data/spec/fabricators/mentions_fabricator.rb +3 -0
  65. data/spec/fabricators/notification_subscriptions_fabricator.rb +4 -0
  66. data/spec/fabricators/permissions_fabricator.rb +1 -0
  67. data/spec/fabricators/post_attachments_fabricator.rb +8 -0
  68. data/spec/fabricators/post_versions_fabricator.rb +12 -0
  69. data/spec/fabricators/posts_fabricator.rb +12 -0
  70. data/spec/fabricators/profile_infos_fabricator.rb +30 -0
  71. data/spec/integration/api/apps_spec.rb +466 -0
  72. data/spec/integration/api/followers_spec.rb +535 -0
  73. data/spec/integration/api/followings_spec.rb +688 -0
  74. data/spec/integration/api/groups_spec.rb +207 -0
  75. data/spec/integration/api/posts_spec.rb +874 -0
  76. data/spec/integration/api/profile_spec.rb +285 -0
  77. data/spec/integration/api/router_spec.rb +102 -0
  78. data/spec/integration/model/app_authorization_spec.rb +59 -0
  79. data/spec/integration/model/app_spec.rb +63 -0
  80. data/spec/integration/model/follower_spec.rb +344 -0
  81. data/spec/integration/model/following_spec.rb +97 -0
  82. data/spec/integration/model/group_spec.rb +39 -0
  83. data/spec/integration/model/notification_subscription_spec.rb +145 -0
  84. data/spec/integration/model/post_spec.rb +658 -0
  85. data/spec/spec_helper.rb +37 -0
  86. data/spec/support/expect_server.rb +3 -0
  87. data/spec/support/json_request.rb +54 -0
  88. data/spec/support/with_constant.rb +23 -0
  89. data/spec/support/with_warnings.rb +6 -0
  90. data/spec/unit/api/authentication_finalize_spec.rb +45 -0
  91. data/spec/unit/api/authentication_lookup_spec.rb +65 -0
  92. data/spec/unit/api/authentication_verification_spec.rb +50 -0
  93. data/spec/unit/api/authorizable_spec.rb +50 -0
  94. data/spec/unit/api/authorization_spec.rb +44 -0
  95. data/spec/unit/api/caching_headers_spec.rb +121 -0
  96. data/spec/unit/core_profile_data_spec.rb +64 -0
  97. data/spec/unit/json_patch_spec.rb +407 -0
  98. data/spec/unit/tent_type_spec.rb +28 -0
  99. data/spec/unit/tent_version_spec.rb +68 -0
  100. data/tentd.gemspec +36 -0
  101. metadata +435 -0
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rbx/
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color --backtrace
@@ -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'
@@ -0,0 +1,6 @@
1
+ guard 'rspec', :version => 2 do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/tentd/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
4
+ watch(%r{^lib/[^/]+\.rb$}) { "spec" }
5
+ watch(%r{spec/(spec_helper|support/).*\.rb}) { "spec" }
6
+ end
@@ -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.
@@ -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)
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new(:spec) do |spec|
6
+ spec.pattern = 'spec/**/*_spec.rb'
7
+ end
8
+ task :default => :spec
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'tent-server'
@@ -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'
@@ -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