do not munge hash keys in client-provided request. fixes #1516
[arvados.git] / services / api / app / controllers / arvados / v1 / schema_controller.rb
index ee268654044ec29bb3d202ceacffc3e1c76ccff3..35bf880d537e29afcbf4e29f17ab712201135a33 100644 (file)
@@ -1,6 +1,6 @@
 class Arvados::V1::SchemaController < ApplicationController
   skip_before_filter :find_object_by_uuid
-  skip_before_filter :login_required
+  skip_before_filter :require_auth_scope_all
 
   def show
     classes = Rails.cache.fetch 'arvados_v1_schema' do
@@ -87,8 +87,12 @@ class Arvados::V1::SchemaController < ApplicationController
       }
       
       ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |k|
-        next if k == ApiClientAuthorization
-        next if k == ApiClient
+        begin
+          ctl_class = "Arvados::V1::#{k.to_s.pluralize}Controller".constantize
+        rescue
+          # No controller -> no discovery.
+          next
+        end
         object_properties = {}
         k.columns.
           select { |col| col.name != 'id' }.
@@ -202,6 +206,16 @@ class Arvados::V1::SchemaController < ApplicationController
                   type: "string",
                   description: "Query string for searching #{k.to_s.underscore.pluralize}.",
                   location: "query"
+                },
+                where: {
+                  type: "object",
+                  description: "Conditions for filtering #{k.to_s.underscore.pluralize}.",
+                  location: "query"
+                },
+                order: {
+                  type: "string",
+                  description: "Order in which to return matching #{k.to_s.underscore.pluralize}.",
+                  location: "query"
                 }
               },
               response: {
@@ -220,13 +234,18 @@ class Arvados::V1::SchemaController < ApplicationController
               parameters: {
                 k.to_s.underscore => {
                   type: "object",
-                  required: true,
+                  required: false,
                   location: "query",
                   properties: object_properties
                 }
               },
               request: {
-                "$ref" => k.to_s
+                required: false,
+                properties: {
+                  k.to_s => {
+                    "$ref" => k.to_s
+                  }
+                }
               },
               response: {
                 "$ref" => k.to_s
@@ -249,13 +268,18 @@ class Arvados::V1::SchemaController < ApplicationController
                 },
                 k.to_s.underscore => {
                   type: "object",
-                  required: true,
+                  required: false,
                   location: "query",
                   properties: object_properties
                 }
               },
               request: {
-                "$ref" => k.to_s
+                required: false,
+                properties: {
+                  k.to_s => {
+                    "$ref" => k.to_s
+                  }
+                }
               },
               response: {
                 "$ref" => k.to_s
@@ -286,6 +310,57 @@ class Arvados::V1::SchemaController < ApplicationController
             }
           }
         }
+        # Check for Rails routes that don't match the usual actions
+        # listed above
+        d_methods = discovery[:resources][k.to_s.underscore.pluralize][:methods]
+        Rails.application.routes.routes.each do |route|
+          action = route.defaults[:action]
+          httpMethod = (route.verb && route.verb.length > 0) ? route.verb : 'GET'
+          if route.defaults[:controller] == 'arvados/v1/' + k.to_s.underscore.pluralize and
+              !d_methods[action.to_sym] and
+              ctl_class.action_methods.include? action
+            method = {
+              id: "arvados.#{k.to_s.underscore.pluralize}.#{action}",
+              path: route.path.sub('/arvados/v1/','').sub('(.:format)','').sub(/:(uu)?id/,'{uuid}'),
+              httpMethod: httpMethod,
+              description: "#{route.defaults[:action]} #{k.to_s.underscore.pluralize}",
+              parameters: {},
+              response: {
+                "$ref" => (action == 'index' ? "#{k.to_s}List" : k.to_s)
+              },
+              scopes: [
+                       "https://api.clinicalfuture.com/auth/arvados"
+                      ]
+            }
+            route.segment_keys.each do |key|
+              if key != :format
+                key = :uuid if key == :id
+                method[:parameters][key] = {
+                  type: "string",
+                  description: "",
+                  required: true,
+                  location: "path"
+                }
+              end
+            end
+            if ctl_class.respond_to? "_#{action}_requires_parameters".to_sym
+              ctl_class.send("_#{action}_requires_parameters".to_sym).each do |k, v|
+                if v.is_a? Hash
+                  method[:parameters][k] = v
+                else
+                  method[:parameters][k] = {}
+                end
+                method[:parameters][k][:type] ||= 'string'
+                method[:parameters][k][:description] ||= ''
+                method[:parameters][k][:location] = (route.segment_keys.include?(k) ? 'path' : 'query')
+                if method[:parameters][k][:required].nil?
+                  method[:parameters][k][:required] = v != false
+                end
+              end
+            end
+            d_methods[route.defaults[:action].to_sym] = method
+          end
+        end
       end
       discovery
     end