Class: RESTHelpers::Endpoint

Inherits:
Object
  • Object
show all
Defined in:
backend/app/lib/rest.rb

Constant Summary

@@endpoints =
[]
@@param_types =
{
  :repo_id => [Integer,
               "The Repository ID",
               {:validation => ["The Repository must exist", ->(v){Repository.exists?(v)}]}],
  :resolve => [[String], "A list of references to resolve and embed in the response",
               :optional => true],
  :id => [Integer, "The ID of the record"]
}
@@return_types =
{
  :created => '{:status => "Created", :id => (id of created object), :warnings => {(warnings)}}',
  :updated => '{:status => "Updated", :id => (id of updated object)}',
  :suppressed => '{:status => "Suppressed", :id => (id of updated object), :suppressed_state => (true|false)}',
  :error => '{:error => (description of error)}'
}

Class Method Summary (collapse)

Instance Method Summary (collapse)

Constructor Details

- (Endpoint) initialize(method)

Returns a new instance of Endpoint



72
73
74
75
76
77
78
79
80
81
82
83
# File 'backend/app/lib/rest.rb', line 72

def initialize(method)
  @method = method
  @uri = ""
  @description = "-- No description provided --"
  @permissions = []
  @preconditions = []
  @required_params = []
  @paginated = false
  @use_transaction = :unspecified
  @returns = []
  @request_context_keyvals = {}
end

Class Method Details

+ (Object) all



92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'backend/app/lib/rest.rb', line 92

def self.all
  @@endpoints.map do |e|
    e.instance_eval do
      {
        :uri => @uri,
        :description => @description,
        :method => @method,
        :params => @required_params,
        :paginated => @paginated,
        :returns => @returns
      }
    end
  end
end

+ (Object) delete(uri)



110
# File 'backend/app/lib/rest.rb', line 110

def self.delete(uri) self.method(:delete).uri(uri) end

+ (Object) get(uri)



108
# File 'backend/app/lib/rest.rb', line 108

def self.get(uri) self.method(:get).uri(uri) end

+ (Boolean) is_potentially_destructive_request?(env)

Returns:

  • (Boolean)


118
119
120
# File 'backend/app/lib/rest.rb', line 118

def self.is_potentially_destructive_request?(env)
  env["REQUEST_METHOD"] != "GET"
end

+ (Boolean) is_toplevel_request?(env)

Helpers

Returns:

  • (Boolean)


114
115
116
# File 'backend/app/lib/rest.rb', line 114

def self.is_toplevel_request?(env)
  env["ASPACE_REENTRANT"].nil?
end

+ (Object) method(method)



111
# File 'backend/app/lib/rest.rb', line 111

def self.method(method) Endpoint.new(method) end

+ (Object) post(uri)



109
# File 'backend/app/lib/rest.rb', line 109

def self.post(uri) self.method(:post).uri(uri) end

Instance Method Details

- (Object) [](key)



85
86
87
88
89
# File 'backend/app/lib/rest.rb', line 85

def [](key)
  if instance_variable_defined?("@#{key}")
    instance_variable_get("@#{key}")
  end
end

- (Object) description(description)



124
# File 'backend/app/lib/rest.rb', line 124

def description(description) @description = description; self end

- (Object) paginated(val)



163
164
165
166
167
# File 'backend/app/lib/rest.rb', line 163

def paginated(val)
  @paginated = val

  self
end

- (Object) params(*params)



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'backend/app/lib/rest.rb', line 146

def params(*params)
  @required_params = params.map do |p|
    param_name, param_type = p

    if @@param_types[param_type]
      # This parameter type has a standard definition
      defn = @@param_types[param_type]
      [param_name, *defn]
    else
      p
    end
  end

  self
end

- (Object) permissions(permissions)



128
129
130
131
132
133
134
135
136
# File 'backend/app/lib/rest.rb', line 128

def permissions(permissions)
  @has_permissions = true

  permissions.each do |permission|
    @preconditions << proc { |request| current_user.can?(permission) }
  end

  self
end

- (Object) preconditions(*preconditions)



125
# File 'backend/app/lib/rest.rb', line 125

def preconditions(*preconditions) @preconditions += preconditions; self end

- (Object) request_context(hash)



139
140
141
142
143
# File 'backend/app/lib/rest.rb', line 139

def request_context(hash)
  @request_context_keyvals = hash

  self
end

- (Object) returns(*returns, &block)



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'backend/app/lib/rest.rb', line 177

def returns(*returns, &block)
  raise "No .permissions declaration for endpoint #{@method.to_s.upcase} #{@uri}" if !@has_permissions

  @returns = returns.map { |r| r[1] = @@return_types[r[1]] || r[1]; r }

  @@endpoints << self

  preconditions = @preconditions
  rp = @required_params
  paginated = @paginated
  use_transaction = @use_transaction
  uri = @uri
  method = @method
  request_context = @request_context_keyvals

  if ArchivesSpaceService.development?
    # Undefine any pre-existing routes (sinatra reloader seems to have trouble
    # with this for our instances)
    ArchivesSpaceService.instance_eval {
      new_route = compile(uri)

      if @routes[method.to_s.upcase]
        @routes[method.to_s.upcase].reject! do |route|
          route[0..1] == new_route
        end
      end
    }
  end

  ArchivesSpaceService.send(@method, @uri, {}) do
    RequestContext.open(request_context) do
      DB.open do |db|
        ensure_params(rp, paginated)
      end

      Log.debug("Post-processed params: #{Log.filter_passwords(params).inspect}")

      RequestContext.put(:repo_id, params[:repo_id])
      RequestContext.put(:is_high_priority, high_priority_request?)

      if Endpoint.is_toplevel_request?(env) || Endpoint.is_potentially_destructive_request?(env)
        unless preconditions.all? { |precondition| self.instance_eval &precondition }
          raise AccessDeniedException.new("Access denied")
        end
      end

      DB.open((use_transaction == :unspecified) ? true : use_transaction) do
        RequestContext.put(:current_username, current_user.username)

        # If the current user is a manager, show them suppressed records
        # too.
        if RequestContext.get(:repo_id)
          if current_user.can?(:index_system)
            # Don't mess with the search user
            RequestContext.put(:enforce_suppression, false)
          else
            RequestContext.put(:enforce_suppression,
                               !((current_user.can?(:manage_repository) ||
                                  current_user.can?(:view_suppressed) ||
                                  current_user.can?(:suppress_archival_record)) &&
                                 Preference.defaults['show_suppressed']))
          end
        end

        self.instance_eval &block
      end
    end
  end
end

- (Object) uri(uri)



123
# File 'backend/app/lib/rest.rb', line 123

def uri(uri) @uri = uri; self end

- (Object) use_transaction(val)



170
171
172
173
174
# File 'backend/app/lib/rest.rb', line 170

def use_transaction(val)
  @use_transaction = val

  self
end