Sha256: f4a97007dcc1d46e5f93123eb9bf77123051411573963fe4dd6fac0f882d05a1

Contents?: true

Size: 1.58 KB

Versions: 3

Compression:

Stored size: 1.58 KB

Contents

require 'rmega/storage'
require 'rmega/request_error'
require 'rmega/crypto/crypto'
require 'rmega/utils'

module Rmega
  def self.login(email, password)
    Session.new(email, password).storage
  end

  class Session
    include Loggable

    attr_reader :email, :request_id, :sid, :master_key

    def initialize(email, password)
      @email = email
      @request_id = random_request_id

      login(password)
    end

    def options
      Rmega.options
    end

    delegate :api_url, :api_request_timeout, to: :options

    def storage
      @storage ||= Storage.new(self)
    end

    def login(password)
      uh = Crypto.stringhash Crypto.prepare_key_pw(password), email.downcase
      resp = request(a: 'us', user: email, uh: uh)

      # Decrypts the master key
      encrypted_key = Crypto.prepare_key_pw(password)
      @master_key = Crypto.decrypt_key(encrypted_key, Utils.base64_to_a32(resp['k']))

      # Generates the session id
      @sid = Crypto.decrypt_sid(@master_key, resp['csid'], resp['privk'])
    end

    def random_request_id
      rand(1E7..1E9).to_i
    end

    def request_url
      "#{api_url}?id=#{@request_id}".tap do |url|
        url << "&sid=#{@sid}" if @sid
      end
    end

    def request(body)
      @request_id += 1
      logger.debug "POST #{request_url}\n#{body.inspect}"
      response = HTTPClient.new.post(request_url, [body].to_json, timeout: api_request_timeout)
      logger.debug "#{response.code}\n#{response.body}"
      resp = JSON.parse(response.body).first
      raise RequestError.new(resp) if RequestError.error_code?(resp)
      resp
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
rmega-0.1.5 lib/rmega/session.rb
rmega-0.1.4 lib/rmega/session.rb
rmega-0.1.3 lib/rmega/session.rb