cloudkit 0.9.1 → 0.10.0
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.
- data/CHANGES +6 -0
- data/COPYING +1 -1
- data/README +7 -7
- data/TODO +4 -3
- data/cloudkit.gemspec +4 -4
- data/doc/curl.html +133 -72
- data/doc/index.html +1 -1
- data/doc/rest-api.html +109 -0
- data/examples/3.ru +1 -1
- data/examples/4.ru +1 -1
- data/examples/5.ru +2 -2
- data/examples/6.ru +2 -2
- data/lib/cloudkit.rb +7 -1
- data/lib/cloudkit/constants.rb +40 -0
- data/lib/cloudkit/oauth_filter.rb +9 -9
- data/lib/cloudkit/oauth_store.rb +1 -5
- data/lib/cloudkit/openid_filter.rb +11 -11
- data/lib/cloudkit/rack/builder.rb +3 -3
- data/lib/cloudkit/request.rb +18 -12
- data/lib/cloudkit/service.rb +26 -8
- data/lib/cloudkit/store.rb +109 -34
- data/lib/cloudkit/store/adapter.rb +0 -1
- data/lib/cloudkit/store/response.rb +1 -0
- data/lib/cloudkit/store/sql_adapter.rb +2 -2
- data/lib/cloudkit/util.rb +2 -37
- data/test/helper.rb +6 -39
- data/test/oauth_filter_test.rb +13 -13
- data/test/openid_filter_test.rb +14 -8
- data/test/request_test.rb +6 -6
- data/test/service_test.rb +337 -113
- data/test/store_test.rb +4 -10
- metadata +4 -4
- data/lib/cloudkit/rack/lint.rb +0 -12
    
        data/doc/index.html
    CHANGED
    
    | @@ -24,7 +24,7 @@ | |
| 24 24 | 
             
              </div>
         | 
| 25 25 | 
             
              <div class="meta">
         | 
| 26 26 | 
             
                <p class="wrapper">
         | 
| 27 | 
            -
                  Version 0. | 
| 27 | 
            +
                  Version 0.10.0 <a href="http://blog.joncrosby.me">released</a>. Install with <em>gem install cloudkit</em>.
         | 
| 28 28 | 
             
                </p>
         | 
| 29 29 | 
             
              </div>
         | 
| 30 30 | 
             
              <div class="wrapper intro-row">
         | 
    
        data/doc/rest-api.html
    CHANGED
    
    | @@ -107,6 +107,59 @@ | |
| 107 107 | 
             
              <span class="definition">uri-list:</span> an array of document URIs within the given collection. If less than the total available are supplied in the uris element, additional requests can be made, specifying the offset and limit query parameters. Future versions of CloudKit may page result sets to optimize performance.
         | 
| 108 108 | 
             
            </p>
         | 
| 109 109 |  | 
| 110 | 
            +
            <div class="uri-template">
         | 
| 111 | 
            +
              GET /%collection%/_resolved
         | 
| 112 | 
            +
            </div>
         | 
| 113 | 
            +
            <p>
         | 
| 114 | 
            +
              List the objects and metadata contained within a collection. This effectively provides the
         | 
| 115 | 
            +
              same result as first listing the URIs using GET /%collection% followed by
         | 
| 116 | 
            +
              performing a GET /%collection%/%uuid% for each URI.
         | 
| 117 | 
            +
            </p>
         | 
| 118 | 
            +
             | 
| 119 | 
            +
            <p>
         | 
| 120 | 
            +
              <span class="spec-header">URI Variables:</span><br/>
         | 
| 121 | 
            +
              <span class="definition">collection:</span> a named collection of JSON documents.
         | 
| 122 | 
            +
            </p>
         | 
| 123 | 
            +
             | 
| 124 | 
            +
            <p>
         | 
| 125 | 
            +
              <span class="spec-header">Optional Query Parameters:</span><br/>
         | 
| 126 | 
            +
              <span class="definition">offset:</span> 0-based starting index for the list of results. Default is 0.<br/>
         | 
| 127 | 
            +
              <span class="definition">limit:</span>  maximum number of results to return. Default is undefined, meaning unlimited.
         | 
| 128 | 
            +
            </p>
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            <p>
         | 
| 131 | 
            +
              <span class="spec-header">Response:</span><br/>
         | 
| 132 | 
            +
              {<br/>
         | 
| 133 | 
            +
                "total":%total-results%,<br/>
         | 
| 134 | 
            +
                "offset":%offset-value%,<br/>
         | 
| 135 | 
            +
                "documents":[%document-list%]<br/>
         | 
| 136 | 
            +
              }
         | 
| 137 | 
            +
            </p>
         | 
| 138 | 
            +
             | 
| 139 | 
            +
            <p>
         | 
| 140 | 
            +
              <span class="spec-header">Response Variables:</span><br/>
         | 
| 141 | 
            +
              <span class="definition">total-results:</span> the total number of available results in the complete set, calculated prior applying any provided limits.<br/>
         | 
| 142 | 
            +
              <span class="definition">offset-value:</span> integer representing the offset.<br/>
         | 
| 143 | 
            +
              <span class="definition">document-list:</span> an array of documents and their metadata within the given collection. If less than the total available are supplied in the documents element, additional requests can be made, specifying the offset and limit query parameters. Future versions of CloudKit may page result sets to optimize performance.
         | 
| 144 | 
            +
            </p>
         | 
| 145 | 
            +
             | 
| 146 | 
            +
            <p>
         | 
| 147 | 
            +
              <span class="spec-header">Document:</span><br/>
         | 
| 148 | 
            +
              {<br/>
         | 
| 149 | 
            +
                "etag":%etag%,<br/>
         | 
| 150 | 
            +
                "last_modified":%last-modified%,<br/>
         | 
| 151 | 
            +
                "uri":%uri-value%,<br/>
         | 
| 152 | 
            +
                "document":%json-document%<br/>
         | 
| 153 | 
            +
              }
         | 
| 154 | 
            +
            </p>
         | 
| 155 | 
            +
             | 
| 156 | 
            +
            <p>
         | 
| 157 | 
            +
              <span class="spec-header">Document Variables:</span><br/>
         | 
| 158 | 
            +
              <span class="definition">etag:</span> the value of the ETag normally returned in a response header when requesting the individual document.<br/>
         | 
| 159 | 
            +
              <span class="definition">last-modified:</span> the value of the Last-Modified timestamp normally returned in a response header when requesting the individual document.<br/>
         | 
| 160 | 
            +
              <span class="definition">uri-value:</span> the URI for the individual document relative to the service root.<br/>
         | 
| 161 | 
            +
              <span class="definition">json-document:</span> a valid JSON document.
         | 
| 162 | 
            +
            </p>
         | 
| 110 163 |  | 
| 111 164 | 
             
            <div class="uri-template">
         | 
| 112 165 | 
             
              GET /%collection%/%uuid%
         | 
| @@ -167,6 +220,62 @@ | |
| 167 220 | 
             
              <span class="definition">uri-list:</span> an array of document URIs within the given collection. If less than the total available are supplied in the uris element, additional requests can be made, specifying the offset and limit query parameters. Future versions of CloudKit may page result sets to optimize performance.
         | 
| 168 221 | 
             
            </p>
         | 
| 169 222 |  | 
| 223 | 
            +
            <div class="uri-template">
         | 
| 224 | 
            +
              GET /%collection%/%uuid%/versions/_resolved
         | 
| 225 | 
            +
            </div>
         | 
| 226 | 
            +
            <p>
         | 
| 227 | 
            +
              List the objects and metadata contained within a collection of document versions.
         | 
| 228 | 
            +
              This effectively provides the same result as first listing the URIs using
         | 
| 229 | 
            +
              GET /%collection%/%uuid%/versions followed by performing a
         | 
| 230 | 
            +
              GET /%collection%/%uuid%/versions/%etag% for each URI.
         | 
| 231 | 
            +
            </p>
         | 
| 232 | 
            +
             | 
| 233 | 
            +
            <p>
         | 
| 234 | 
            +
              <span class="spec-header">URI Variables:</span><br/>
         | 
| 235 | 
            +
              <span class="definition">collection:</span> a named collection of documents.<br/>
         | 
| 236 | 
            +
              <span class="definition">uuid:</span> the unique key for a JSON document.
         | 
| 237 | 
            +
            </p>
         | 
| 238 | 
            +
             | 
| 239 | 
            +
            <p>
         | 
| 240 | 
            +
              <span class="spec-header">Optional Query Parameters:</span><br/>
         | 
| 241 | 
            +
              <span class="definition">offset:</span> 0-based starting index for the list of results. Default is 0.<br/>
         | 
| 242 | 
            +
              <span class="definition">limit:</span> maximum number of results to return. Default is undefined, meaning unlimited.
         | 
| 243 | 
            +
            </p>
         | 
| 244 | 
            +
             | 
| 245 | 
            +
            <p>
         | 
| 246 | 
            +
              <span class="spec-header">Response:</span><br/>
         | 
| 247 | 
            +
              {<br/>
         | 
| 248 | 
            +
                "total":%total-results%,<br/>
         | 
| 249 | 
            +
                "offset":%offset-value%,<br/>
         | 
| 250 | 
            +
                "documents":[%document-list%]<br/>
         | 
| 251 | 
            +
              }
         | 
| 252 | 
            +
            </p>
         | 
| 253 | 
            +
             | 
| 254 | 
            +
            <p>
         | 
| 255 | 
            +
              <span class="spec-header">Response Variables:</span><br/>
         | 
| 256 | 
            +
              <span class="definition">total-results:</span> the total number of available results in the complete set, calculated prior applying any provided limits.<br/>
         | 
| 257 | 
            +
              <span class="definition">offset-value:</span> integer representing the offset.<br/>
         | 
| 258 | 
            +
              <span class="definition">document-list:</span> an array of documents and their metadata within the given collection. If less than the total available are supplied in the documents element, additional requests can be made, specifying the offset and limit query parameters. Future versions of CloudKit may page result sets to optimize performance.
         | 
| 259 | 
            +
            </p>
         | 
| 260 | 
            +
             | 
| 261 | 
            +
            <p>
         | 
| 262 | 
            +
              <span class="spec-header">Document:</span><br/>
         | 
| 263 | 
            +
              {<br/>
         | 
| 264 | 
            +
                "etag":%etag%,<br/>
         | 
| 265 | 
            +
                "last_modified":%last-modified%,<br/>
         | 
| 266 | 
            +
                "uri":%uri-value%,<br/>
         | 
| 267 | 
            +
                "document":%json-document%<br/>
         | 
| 268 | 
            +
              }
         | 
| 269 | 
            +
            </p>
         | 
| 270 | 
            +
             | 
| 271 | 
            +
            <p>
         | 
| 272 | 
            +
              <span class="spec-header">Document Variables:</span><br/>
         | 
| 273 | 
            +
              <span class="definition">etag:</span> the value of the ETag normally returned in a response header when requesting the individual document.<br/>
         | 
| 274 | 
            +
              <span class="definition">last-modified:</span> the value of the Last-Modified timestamp normally returned in a response header when requesting the individual document.<br/>
         | 
| 275 | 
            +
              <span class="definition">uri-value:</span> the URI for the individual document relative to the service root.<br/>
         | 
| 276 | 
            +
              <span class="definition">json-document:</span> a valid JSON document.
         | 
| 277 | 
            +
            </p>
         | 
| 278 | 
            +
             | 
| 170 279 | 
             
            <div class="uri-template">
         | 
| 171 280 | 
             
              GET /%collection%/%uuid%/versions/%etag%
         | 
| 172 281 | 
             
            </div>
         | 
    
        data/examples/3.ru
    CHANGED
    
    | @@ -3,4 +3,4 @@ require 'cloudkit' | |
| 3 3 | 
             
            use Rack::Session::Pool
         | 
| 4 4 | 
             
            use CloudKit::OpenIDFilter
         | 
| 5 5 | 
             
            use CloudKit::Service, :collections => [:notes]
         | 
| 6 | 
            -
            run lambda{|env| [200, {'Content-Type' => 'text/html'}, ['HELLO']]}
         | 
| 6 | 
            +
            run lambda{|env| [200, {'Content-Type' => 'text/html', 'Content-Length' => '5'}, ['HELLO']]}
         | 
    
        data/examples/4.ru
    CHANGED
    
    | @@ -2,4 +2,4 @@ $:.unshift File.expand_path(File.dirname(__FILE__)) + '/../lib' | |
| 2 2 | 
             
            require 'cloudkit'
         | 
| 3 3 | 
             
            use CloudKit::OAuthFilter
         | 
| 4 4 | 
             
            use CloudKit::Service, :collections => [:notes]
         | 
| 5 | 
            -
            run lambda{|env| [200, {'Content-Type' => 'text/html'}, ['HELLO']]}
         | 
| 5 | 
            +
            run lambda{|env| [200, {'Content-Type' => 'text/html', 'Content-Length' => '5'}, ['HELLO']]}
         | 
    
        data/examples/5.ru
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            $:.unshift File.expand_path(File.dirname(__FILE__)) + '/../lib'
         | 
| 2 2 | 
             
            require 'cloudkit'
         | 
| 3 3 | 
             
            use Rack::Config do |env|
         | 
| 4 | 
            -
              env[ | 
| 4 | 
            +
              env[CLOUDKIT_STORAGE_URI] = 'sqlite://example.db'
         | 
| 5 5 | 
             
            end
         | 
| 6 6 | 
             
            use Rack::Session::Pool
         | 
| 7 7 | 
             
            use CloudKit::OAuthFilter
         | 
| 8 8 | 
             
            use CloudKit::OpenIDFilter
         | 
| 9 9 | 
             
            use CloudKit::Service, :collections => [:notes]
         | 
| 10 | 
            -
            run lambda{|env| [200, {'Content-Type' => 'text/html'}, ['HELLO']]}
         | 
| 10 | 
            +
            run lambda{|env| [200, {'Content-Type' => 'text/html', 'Content-Length' => '5'}, ['HELLO']]}
         | 
    
        data/examples/6.ru
    CHANGED
    
    | @@ -1,10 +1,10 @@ | |
| 1 1 | 
             
            $:.unshift File.expand_path(File.dirname(__FILE__)) + '/../lib'
         | 
| 2 2 | 
             
            require 'cloudkit'
         | 
| 3 3 | 
             
            use Rack::Config do |env|
         | 
| 4 | 
            -
              env[ | 
| 4 | 
            +
              env[CLOUDKIT_STORAGE_URI] = 'mysql://user:pass@localhost/cloudkit_example'
         | 
| 5 5 | 
             
            end
         | 
| 6 6 | 
             
            use Rack::Session::Pool
         | 
| 7 7 | 
             
            use CloudKit::OAuthFilter
         | 
| 8 8 | 
             
            use CloudKit::OpenIDFilter
         | 
| 9 9 | 
             
            use CloudKit::Service, :collections => [:notes]
         | 
| 10 | 
            -
            run lambda{|env| [200, {'Content-Type' => 'text/html'}, ['HELLO']]}
         | 
| 10 | 
            +
            run lambda{|env| [200, {'Content-Type' => 'text/html', 'Content-Length' => '5'}, ['HELLO']]}
         | 
    
        data/lib/cloudkit.rb
    CHANGED
    
    | @@ -14,6 +14,7 @@ require 'oauth/consumer' | |
| 14 14 | 
             
            require 'oauth/request_proxy/rack_request'
         | 
| 15 15 | 
             
            require 'oauth/server'
         | 
| 16 16 | 
             
            require 'oauth/signature'
         | 
| 17 | 
            +
            require 'cloudkit/constants'
         | 
| 17 18 | 
             
            require 'cloudkit/util'
         | 
| 18 19 | 
             
            require 'cloudkit/store/adapter'
         | 
| 19 20 | 
             
            require 'cloudkit/store/extraction_view'
         | 
| @@ -27,12 +28,17 @@ require 'cloudkit/oauth_store' | |
| 27 28 | 
             
            require 'cloudkit/openid_filter'
         | 
| 28 29 | 
             
            require 'cloudkit/openid_store'
         | 
| 29 30 | 
             
            require 'cloudkit/rack/builder'
         | 
| 30 | 
            -
            require 'cloudkit/rack/lint'
         | 
| 31 31 | 
             
            require 'cloudkit/rack/router'
         | 
| 32 32 | 
             
            require 'cloudkit/request'
         | 
| 33 33 | 
             
            require 'cloudkit/service'
         | 
| 34 34 | 
             
            require 'cloudkit/user_store'
         | 
| 35 35 |  | 
| 36 | 
            +
            include CloudKit::Constants
         | 
| 37 | 
            +
             | 
| 38 | 
            +
            module CloudKit
         | 
| 39 | 
            +
              VERSION = '0.10.0'
         | 
| 40 | 
            +
            end
         | 
| 41 | 
            +
             | 
| 36 42 | 
             
            class Object
         | 
| 37 43 |  | 
| 38 44 | 
             
              # Execute a method if it exists.
         | 
| @@ -0,0 +1,40 @@ | |
| 1 | 
            +
            module CloudKit
         | 
| 2 | 
            +
              module Constants
         | 
| 3 | 
            +
             | 
| 4 | 
            +
                # The key used to store the authenticated user.
         | 
| 5 | 
            +
                CLOUDKIT_AUTH_KEY = 'cloudkit.user'.freeze
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                # The key used to indicate the presence of auth in a stack.
         | 
| 8 | 
            +
                CLOUDKIT_AUTH_PRESENCE = 'cloudkit.auth'.freeze
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                # The key used to store auth challenge headers shared between
         | 
| 11 | 
            +
                # OpenID and OAuth middleware.
         | 
| 12 | 
            +
                CLOUDKIT_AUTH_CHALLENGE = 'cloudkit.challenge'.freeze
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # The 'via' key used to announce and track upstream middleware.
         | 
| 15 | 
            +
                CLOUDKIT_VIA = 'cloudkit.via'.freeze
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                # The key used to store the 'flash' in the session.
         | 
| 18 | 
            +
                CLOUDKIT_FLASH = 'cloudkit.flash'.freeze
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                # The 'via' key for the OAuth filter.
         | 
| 21 | 
            +
                CLOUDKIT_OAUTH_FILTER_KEY = 'cloudkit.filter.oauth'.freeze
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                # The 'via' key for the OpenID filter.
         | 
| 24 | 
            +
                CLOUDKIT_OPENID_FILTER_KEY = 'cloudkit.filter.openid'.freeze
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # The key used to store the shared storage URI for the stack.
         | 
| 27 | 
            +
                CLOUDKIT_STORAGE_URI = 'cloudkit.storage.uri'.freeze
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # The key for the login URL used in OpenID and OAuth middleware
         | 
| 30 | 
            +
                # components.
         | 
| 31 | 
            +
                CLOUDKIT_LOGIN_URL = 'cloudkit.filter.openid.url.login'.freeze
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # The key for the logout URL used in OpenID and OAuth middleware
         | 
| 34 | 
            +
                # components.
         | 
| 35 | 
            +
                CLOUDKIT_LOGOUT_URL = 'cloudkit.filter.openid.url.logout'.freeze
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                # The outer namespace key for the JSON store.
         | 
| 38 | 
            +
                CLOUDKIT_STORE = :cloudkit_json_store.freeze
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
            end
         | 
| @@ -31,11 +31,11 @@ module CloudKit | |
| 31 31 |  | 
| 32 32 | 
             
                def call(env)
         | 
| 33 33 | 
             
                  @@lock.synchronize do
         | 
| 34 | 
            -
                    @@store = OAuthStore.new(env[ | 
| 34 | 
            +
                    @@store = OAuthStore.new(env[CLOUDKIT_STORAGE_URI])
         | 
| 35 35 | 
             
                  end unless @@store
         | 
| 36 36 |  | 
| 37 37 | 
             
                  request = Request.new(env)
         | 
| 38 | 
            -
                  request.announce_auth( | 
| 38 | 
            +
                  request.announce_auth(CLOUDKIT_OAUTH_FILTER_KEY)
         | 
| 39 39 | 
             
                  return xrds_location(request) if oauth_disco_draft2_xrds?(request)
         | 
| 40 40 | 
             
                  return @app.call(env) if request.path_info == '/'
         | 
| 41 41 |  | 
| @@ -99,7 +99,7 @@ module CloudKit | |
| 99 99 | 
             
                  @@store.put(
         | 
| 100 100 | 
             
                    "/cloudkit_oauth_request_tokens/#{token_id}",
         | 
| 101 101 | 
             
                    :json => request_token)
         | 
| 102 | 
            -
                   | 
| 102 | 
            +
                  Rack::Response.new("oauth_token=#{token_id}&oauth_token_secret=#{secret}", 201).finish
         | 
| 103 103 | 
             
                end
         | 
| 104 104 |  | 
| 105 105 | 
             
                def request_authorization(request)
         | 
| @@ -186,7 +186,7 @@ module CloudKit | |
| 186 186 | 
             
                  @@store.delete(
         | 
| 187 187 | 
             
                    "/cloudkit_oauth_request_tokens/#{request[:oauth_token]}",
         | 
| 188 188 | 
             
                    :etag => request_token_response.etag)
         | 
| 189 | 
            -
                   | 
| 189 | 
            +
                  Rack::Response.new("oauth_token=#{token_id}&oauth_token_secret=#{secret}", 201).finish
         | 
| 190 190 | 
             
                end
         | 
| 191 191 |  | 
| 192 192 | 
             
                def inject_user_or_challenge(request)
         | 
| @@ -222,11 +222,11 @@ module CloudKit | |
| 222 222 | 
             
                end
         | 
| 223 223 |  | 
| 224 224 | 
             
                def inject_challenge(request)
         | 
| 225 | 
            -
                  request.env[ | 
| 225 | 
            +
                  request.env[CLOUDKIT_AUTH_CHALLENGE] = challenge_headers(request)
         | 
| 226 226 | 
             
                end
         | 
| 227 227 |  | 
| 228 | 
            -
                def challenge(request, message)
         | 
| 229 | 
            -
                   | 
| 228 | 
            +
                def challenge(request, message='')
         | 
| 229 | 
            +
                  Rack::Response.new(message, 401, challenge_headers(request)).finish
         | 
| 230 230 | 
             
                end
         | 
| 231 231 |  | 
| 232 232 | 
             
                def challenge_headers(request)
         | 
| @@ -243,7 +243,7 @@ module CloudKit | |
| 243 243 |  | 
| 244 244 | 
             
                def login_redirect(request)
         | 
| 245 245 | 
             
                  request.session['return_to'] = request.url if request.session
         | 
| 246 | 
            -
                  [302, {'Location' => request.login_url | 
| 246 | 
            +
                  Rack::Response.new([], 302, {'Location' => request.login_url}).finish
         | 
| 247 247 | 
             
                end
         | 
| 248 248 |  | 
| 249 249 | 
             
                def load_user_from_session(request)
         | 
| @@ -264,7 +264,7 @@ module CloudKit | |
| 264 264 |  | 
| 265 265 | 
             
                def xrds_location(request)
         | 
| 266 266 | 
             
                  # Current OAuth Discovery Draft 2 / XRDS-Simple 1.0, Section 5.1.2
         | 
| 267 | 
            -
                  [200, {'X-XRDS-Location' => "#{request.scheme}://#{request.env['HTTP_HOST']}/oauth"} | 
| 267 | 
            +
                  Rack::Response.new([], 200, {'X-XRDS-Location' => "#{request.scheme}://#{request.env['HTTP_HOST']}/oauth"}).finish
         | 
| 268 268 | 
             
                end
         | 
| 269 269 |  | 
| 270 270 | 
             
                def get_descriptor(request)
         | 
    
        data/lib/cloudkit/oauth_store.rb
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 | 
             
            module CloudKit
         | 
| 2 | 
            -
             | 
| 2 | 
            +
             | 
| 3 3 | 
             
              # An OAuthStore is a thin abstraction around CloudKit::Store, providing
         | 
| 4 4 | 
             
              # consistent collection names, and allowing automatic migrations in later
         | 
| 5 5 | 
             
              # releases if needed.
         | 
| @@ -35,10 +35,6 @@ module CloudKit | |
| 35 35 | 
             
                  @@store.delete(uri, options)
         | 
| 36 36 | 
             
                end
         | 
| 37 37 |  | 
| 38 | 
            -
                def resolve_uris(uris) #:nodoc:
         | 
| 39 | 
            -
                  @@store.resolve_uris(uris)
         | 
| 40 | 
            -
                end
         | 
| 41 | 
            -
                
         | 
| 42 38 | 
             
                def reset! #:nodoc:
         | 
| 43 39 | 
             
                  @@store.reset!
         | 
| 44 40 | 
             
                end
         | 
| @@ -20,13 +20,13 @@ module CloudKit | |
| 20 20 |  | 
| 21 21 | 
             
                def call(env)
         | 
| 22 22 | 
             
                  @@lock.synchronize do
         | 
| 23 | 
            -
                    @@store = OpenIDStore.new(env[ | 
| 24 | 
            -
                    @users  = UserStore.new(env[ | 
| 23 | 
            +
                    @@store = OpenIDStore.new(env[CLOUDKIT_STORAGE_URI])
         | 
| 24 | 
            +
                    @users  = UserStore.new(env[CLOUDKIT_STORAGE_URI])
         | 
| 25 25 | 
             
                    @@store.get_association('x') rescue nil # refresh sqlite3
         | 
| 26 26 | 
             
                  end unless @@store
         | 
| 27 27 |  | 
| 28 28 | 
             
                  request = Request.new(env)
         | 
| 29 | 
            -
                  request.announce_auth( | 
| 29 | 
            +
                  request.announce_auth(CLOUDKIT_OPENID_FILTER_KEY)
         | 
| 30 30 |  | 
| 31 31 | 
             
                  case request
         | 
| 32 32 | 
             
                  when r(:get, request.login_url); request_login(request)
         | 
| @@ -37,18 +37,18 @@ module CloudKit | |
| 37 37 | 
             
                    if (root_request?(request) || valid_auth_key?(request) || logged_in?(request))
         | 
| 38 38 | 
             
                      @app.call(env)
         | 
| 39 39 | 
             
                    else
         | 
| 40 | 
            -
                      if request.env[ | 
| 40 | 
            +
                      if request.env[CLOUDKIT_AUTH_CHALLENGE]
         | 
| 41 41 | 
             
                        store_location(request)
         | 
| 42 42 | 
             
                        erb(
         | 
| 43 43 | 
             
                          request,
         | 
| 44 44 | 
             
                          :openid_login,
         | 
| 45 | 
            -
                          request.env[ | 
| 45 | 
            +
                          request.env[CLOUDKIT_AUTH_CHALLENGE].merge('Content-Type' => 'text/html'),
         | 
| 46 46 | 
             
                          401)
         | 
| 47 | 
            -
                      elsif !request.via.include?( | 
| 47 | 
            +
                      elsif !request.via.include?(CLOUDKIT_OAUTH_FILTER_KEY)
         | 
| 48 48 | 
             
                        store_location(request)
         | 
| 49 49 | 
             
                        login_redirect(request)
         | 
| 50 50 | 
             
                      else
         | 
| 51 | 
            -
                         | 
| 51 | 
            +
                        Rack::Response.new('server misconfigured', 500).finish
         | 
| 52 52 | 
             
                      end
         | 
| 53 53 | 
             
                    end
         | 
| 54 54 | 
             
                  end
         | 
| @@ -63,7 +63,7 @@ module CloudKit | |
| 63 63 | 
             
                  json = JSON.generate(user)
         | 
| 64 64 | 
             
                  @users.put(user_uri, :etag => result.etag, :json => json)
         | 
| 65 65 |  | 
| 66 | 
            -
                  request.env[ | 
| 66 | 
            +
                  request.env[CLOUDKIT_AUTH_KEY] = nil
         | 
| 67 67 | 
             
                  request.flash['info'] = 'You have been logged out.'
         | 
| 68 68 | 
             
                  response = Rack::Response.new(
         | 
| 69 69 | 
             
                    [],
         | 
| @@ -86,7 +86,7 @@ module CloudKit | |
| 86 86 | 
             
                  end
         | 
| 87 87 |  | 
| 88 88 | 
             
                  redirect_url = response.redirect_url(base_url(request), full_url(request))
         | 
| 89 | 
            -
                  [302, {'Location' => redirect_url | 
| 89 | 
            +
                  Rack::Response.new([], 302, {'Location' => redirect_url}).finish
         | 
| 90 90 | 
             
                end
         | 
| 91 91 |  | 
| 92 92 | 
             
                def complete_openid_login(request)
         | 
| @@ -142,7 +142,7 @@ module CloudKit | |
| 142 142 | 
             
                end
         | 
| 143 143 |  | 
| 144 144 | 
             
                def login_redirect(request)
         | 
| 145 | 
            -
                  [302, {'Location' => request.login_url | 
| 145 | 
            +
                  Rack::Response.new([], 302, {'Location' => request.login_url}).finish
         | 
| 146 146 | 
             
                end
         | 
| 147 147 |  | 
| 148 148 | 
             
                def base_url(request)
         | 
| @@ -172,7 +172,7 @@ module CloudKit | |
| 172 172 | 
             
                end
         | 
| 173 173 |  | 
| 174 174 | 
             
                def valid_auth_key?(request)
         | 
| 175 | 
            -
                  request.env[ | 
| 175 | 
            +
                  request.env[CLOUDKIT_AUTH_KEY] && request.env[CLOUDKIT_AUTH_KEY] != ''
         | 
| 176 176 | 
             
                end
         | 
| 177 177 |  | 
| 178 178 | 
             
                def openid_consumer(request)
         | 
| @@ -8,9 +8,9 @@ module Rack #:nodoc: | |
| 8 8 | 
             
                def to_app
         | 
| 9 9 | 
             
                  default_app = lambda do |env|
         | 
| 10 10 | 
             
                    if (env['PATH_INFO'] == '/')
         | 
| 11 | 
            -
                       | 
| 11 | 
            +
                      Rack::Response.new(welcome).finish
         | 
| 12 12 | 
             
                    else
         | 
| 13 | 
            -
                       | 
| 13 | 
            +
                      Rack::Response.new('not found', 404).finish
         | 
| 14 14 | 
             
                    end
         | 
| 15 15 | 
             
                  end
         | 
| 16 16 | 
             
                  @ins << default_app if @last_cloudkit_id == @ins.last.object_id
         | 
| @@ -51,7 +51,7 @@ doc = <<HTML | |
| 51 51 | 
             
            <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
         | 
| 52 52 | 
             
            <head>
         | 
| 53 53 | 
             
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
         | 
| 54 | 
            -
              <title>CloudKit | 
| 54 | 
            +
              <title>CloudKit</title>
         | 
| 55 55 | 
             
              <style type="text/css">
         | 
| 56 56 | 
             
                body {
         | 
| 57 57 | 
             
                  font-family: 'Helvetica', 'Arial', san-serif;
         | 
    
        data/lib/cloudkit/request.rb
    CHANGED
    
    | @@ -14,6 +14,12 @@ module CloudKit | |
| 14 14 | 
             
                  @cloudkit_params ||= cloudkit_params.merge(oauth_header_params)
         | 
| 15 15 | 
             
                end
         | 
| 16 16 |  | 
| 17 | 
            +
                # Return the JSON content from the request body
         | 
| 18 | 
            +
                def json
         | 
| 19 | 
            +
                  self.body.rewind
         | 
| 20 | 
            +
                  self.body.read
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
             | 
| 17 23 | 
             
                # Return true if method, path, and required_params match.
         | 
| 18 24 | 
             
                def match?(method, path, required_params=[])
         | 
| 19 25 | 
             
                  (request_method == method) &&
         | 
| @@ -78,7 +84,7 @@ module CloudKit | |
| 78 84 | 
             
                # not use the header because the transition from one piece of middleware to
         | 
| 79 85 | 
             
                # the next does not use HTTP.
         | 
| 80 86 | 
             
                def via
         | 
| 81 | 
            -
                  @env[ | 
| 87 | 
            +
                  @env[CLOUDKIT_VIA].split(', ') rescue []
         | 
| 82 88 | 
             
                end
         | 
| 83 89 |  | 
| 84 90 | 
             
                # Return parsed contents of an If-Match header.
         | 
| @@ -99,29 +105,29 @@ module CloudKit | |
| 99 105 | 
             
                # Add a via entry to the Rack environment.
         | 
| 100 106 | 
             
                def inject_via(key)
         | 
| 101 107 | 
             
                  items = via << key
         | 
| 102 | 
            -
                  @env[ | 
| 108 | 
            +
                  @env[CLOUDKIT_VIA] = items.join(', ')
         | 
| 103 109 | 
             
                end
         | 
| 104 110 |  | 
| 105 111 | 
             
                # Return the current user URI.
         | 
| 106 112 | 
             
                def current_user
         | 
| 107 | 
            -
                  return nil unless @env[ | 
| 108 | 
            -
                  @env[ | 
| 113 | 
            +
                  return nil unless @env[CLOUDKIT_AUTH_KEY] && @env[CLOUDKIT_AUTH_KEY] != ''
         | 
| 114 | 
            +
                  @env[CLOUDKIT_AUTH_KEY]
         | 
| 109 115 | 
             
                end
         | 
| 110 116 |  | 
| 111 117 | 
             
                # Set the current user URI.
         | 
| 112 118 | 
             
                def current_user=(user)
         | 
| 113 | 
            -
                  @env[ | 
| 119 | 
            +
                  @env[CLOUDKIT_AUTH_KEY] = user
         | 
| 114 120 | 
             
                end
         | 
| 115 121 |  | 
| 116 122 | 
             
                # Return true if authentication is being used.
         | 
| 117 123 | 
             
                def using_auth?
         | 
| 118 | 
            -
                  @env[ | 
| 124 | 
            +
                  @env[CLOUDKIT_AUTH_PRESENCE] != nil
         | 
| 119 125 | 
             
                end
         | 
| 120 126 |  | 
| 121 127 | 
             
                # Report to downstream middleware that authentication is in use.
         | 
| 122 128 | 
             
                def announce_auth(via)
         | 
| 123 129 | 
             
                  inject_via(via)
         | 
| 124 | 
            -
                  @env[ | 
| 130 | 
            +
                  @env[CLOUDKIT_AUTH_PRESENCE] = 1
         | 
| 125 131 | 
             
                end
         | 
| 126 132 |  | 
| 127 133 | 
             
                # Return the session associated with this request.
         | 
| @@ -133,27 +139,27 @@ module CloudKit | |
| 133 139 | 
             
                # environment so the OpenID and OAuth middleware can cooperate during the
         | 
| 134 140 | 
             
                # token authorization step in the OAuth flow.
         | 
| 135 141 | 
             
                def login_url
         | 
| 136 | 
            -
                  @env[ | 
| 142 | 
            +
                  @env[CLOUDKIT_LOGIN_URL] || '/login'
         | 
| 137 143 | 
             
                end
         | 
| 138 144 |  | 
| 139 145 | 
             
                # Set the login url for this request.
         | 
| 140 146 | 
             
                def login_url=(url)
         | 
| 141 | 
            -
                  @env[ | 
| 147 | 
            +
                  @env[CLOUDKIT_LOGIN_URL] = url
         | 
| 142 148 | 
             
                end
         | 
| 143 149 |  | 
| 144 150 | 
             
                # Return the logout URL for this request.
         | 
| 145 151 | 
             
                def logout_url
         | 
| 146 | 
            -
                  @env[ | 
| 152 | 
            +
                  @env[CLOUDKIT_LOGOUT_URL] || '/logout'
         | 
| 147 153 | 
             
                end
         | 
| 148 154 |  | 
| 149 155 | 
             
                # Set the logout URL for this request.
         | 
| 150 156 | 
             
                def logout_url=(url)
         | 
| 151 | 
            -
                  @env[ | 
| 157 | 
            +
                  @env[CLOUDKIT_LOGOUT_URL] = url
         | 
| 152 158 | 
             
                end
         | 
| 153 159 |  | 
| 154 160 | 
             
                # Return the flash session for this request.
         | 
| 155 161 | 
             
                def flash
         | 
| 156 | 
            -
                  session[ | 
| 162 | 
            +
                  session[CLOUDKIT_FLASH] ||= CloudKit::FlashSession.new
         | 
| 157 163 | 
             
                end
         | 
| 158 164 | 
             
              end
         | 
| 159 165 | 
             
            end
         |