class GitLfsS3::Application

Attributes

auth_callback[R]

Public Class Methods

authentication_enabled?() click to toggle source
# File lib/git-lfs-s3/application.rb, line 17
def authentication_enabled?
  !auth_callback.nil?
end
on_authenticate(&block) click to toggle source
# File lib/git-lfs-s3/application.rb, line 13
def on_authenticate(&block)
  @auth_callback = block
end
perform_authentication(username, password, is_safe) click to toggle source
# File lib/git-lfs-s3/application.rb, line 21
def perform_authentication(username, password, is_safe)
  auth_callback.call(username, password, is_safe)
end

Public Instance Methods

authorized?() click to toggle source
# File lib/git-lfs-s3/application.rb, line 37
def authorized?
  @auth ||= Rack::Auth::Basic::Request.new(request.env)
  @auth.provided? &&
    @auth.basic? &&
    @auth.credentials &&
    self.class.auth_callback.call(
      @auth.credentials[0], @auth.credentials[1], request.safe?
    )
end
download(authenticated, params) click to toggle source
# File lib/git-lfs-s3/application.rb, line 121
def download(authenticated, params)
  # Handle git-lfs batch downloads.
  objects = []
  params[:objects].each do |obj_json|
    obj_json = Sinatra::IndifferentHash[obj_json]
    obj = object_data(obj_json[:oid])
    if valid_obj?(obj_json)
      if obj.exists?
        objects.push(obj_download(authenticated, obj, obj_json))
      else
        objects.push(obj_error(404, 'Object does not exist', obj_json))
      end
    else
      objects.push(obj_error(422, 'Validation error', obj_json))
    end
  end
  objects
end
error_resp(status_code, message) click to toggle source
# File lib/git-lfs-s3/application.rb, line 169
def error_resp(status_code, message)
  # Error git-lfs batch response.
  status(status_code)
  resp = {
    'message'    => message,
    'request_id' => SecureRandom.uuid
  }
  body MultiJson.dump(resp)
end
expire_at() click to toggle source
# File lib/git-lfs-s3/application.rb, line 68
def expire_at
  DateTime.now.next_day.to_time.utc.iso8601
end
lfs_resp(objects) click to toggle source
# File lib/git-lfs-s3/application.rb, line 159
def lfs_resp(objects)
  # Successful git-lfs batch response.
  status(200)
  resp = {
    'transfer' => 'basic',
    'objects'  => objects
  }
  body MultiJson.dump(resp)
end
logger() click to toggle source
# File lib/git-lfs-s3/application.rb, line 32
def logger
  settings.logger
end
obj_download(authenticated, obj, obj_json) click to toggle source
# File lib/git-lfs-s3/application.rb, line 72
def obj_download(authenticated, obj, obj_json)
  # Format a single download object.
  oid = obj_json[:oid]
  size = obj_json[:size]
  {
    'oid'           => oid,
    'size'          => size,
    'authenticated' => authenticated,
    'actions'       => {
      'download' => {
        'href'       => obj.presigned_url(:get,
                                          expires_in: 86_400),
        'expires_at' => expire_at,
      },
    },
  }
end
obj_error(error, message, obj_json) click to toggle source
# File lib/git-lfs-s3/application.rb, line 109
def obj_error(error, message, obj_json)
  # Format a single error object.
  {
    'oid'   => obj_json[:oid],
    'size'  => obj_json[:size],
    'error' => {
      'code'    => error,
      'message' => message,
    },
  }
end
obj_upload(authenticated, obj, obj_json) click to toggle source
# File lib/git-lfs-s3/application.rb, line 90
def obj_upload(authenticated, obj, obj_json)
  # Format a single upload object.
  oid = obj_json[:oid]
  size = obj_json[:size]
  {
    'oid'           => oid,
    'size'          => size,
    'authenticated' => authenticated,
    'actions'       => {
      'upload' => {
        'href'       => obj.presigned_url(:put,
                                          acl:        'public-read',
                                          expires_in: 86_400),
        'expires_at' => expire_at,
      },
    },
  }
end
protected!() click to toggle source
# File lib/git-lfs-s3/application.rb, line 47
def protected!
  return unless authorized?

  response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
  throw(:halt, [401, 'Invalid username or password'])
end
public_read_grant() click to toggle source
# File lib/git-lfs-s3/application.rb, line 235
def public_read_grant
  grantee = Aws::S3::Types::Grantee.new(
    display_name: nil, email_address: nil, id: nil, type: nil,
    uri: 'http://acs.amazonaws.com/groups/global/AllUsers'
  )
  Aws::S3::Types::Grant.new(grantee: grantee, permission: 'READ')
end
upload(authenticated, params) click to toggle source
# File lib/git-lfs-s3/application.rb, line 140
def upload(authenticated, params)
  # Handle git-lfs batch uploads.
  objects = []
  params[:objects].each do |obj_json|
    obj_json = Sinatra::IndifferentHash[obj_json]
    obj = object_data(obj_json[:oid])
    if valid_obj?(obj_json)
      if obj.exists?
        objects.push(obj_download(authenticated, obj, obj_json))
      else
        objects.push(obj_upload(authenticated, obj, obj_json))
      end
    else
      objects.push(obj_error(422, 'Validation error', obj_json))
    end
  end
  objects
end
valid_obj?(obj) click to toggle source
# File lib/git-lfs-s3/application.rb, line 58
def valid_obj?(obj)
  # Validate that size >= 0 and oid is a SHA256 hash.
  oid = obj[:oid]
  return unless obj[:size] >= 0

  (oid.hex.size <= 32) && (oid.size == 64) && (oid =~ /^[0-9a-f]+$/)
  # XXX what exception needs to be ignored here?
rescue Exception
end