Module: Client

Included in:
NaviClient::Cloud, NaviClient::Local
Defined in:
lib/client.rb

Overview

This module provides the common functionality that will be needed for local and cloud module.

Instance Method Summary collapse

Instance Method Details

#depcrecated_encrypt(data) ⇒ Object



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/client.rb', line 167

def depcrecated_encrypt(data)
  cipher = OpenSSL::Cipher::AES.new(256, :CFB)
  cipher.encrypt

  yml_config = config

  key_iv_exists = (yml_config['key'] && yml_config['iv']) ? (!yml_config['key'].empty? && !yml_config['iv'].empty? ) : false

  if key_iv_exists
    # this condition must be true for cloud version
    cipher.key = Base64.decode64(File.read(yml_config['key']))
    cipher.iv = Base64.decode64(File.read(yml_config['iv']))
  else
    cipher.key = key = cipher.random_key
    cipher.iv = iv = cipher.random_iv

    key_path, iv_path = save_aes_key_iv(key, iv)

    yml_config['key'] = key_path
    yml_config['iv'] = iv_path

    update_config(yml_config)
  end

  encrypted = cipher.update(data)
  Base64.encode64(encrypted)
end

#encrypt(data) ⇒ Object



163
164
165
# File 'lib/client.rb', line 163

def encrypt(data)
  Base64.encode64(data)
end

#errorsObject



27
28
29
# File 'lib/client.rb', line 27

def errors
  @errors
end

#imap_connection(server, username, password, exitOnFail = true) ⇒ Object

imap_connection

connect the app with imap server



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/client.rb', line 36

def imap_connection(server, username, password, exitOnFail = true)
  # connect to IMAP server
  imap = Net::IMAP.new server, ssl: true, certs: nil, verify: false

  Net::IMAP.debug = @net_imap_debug

  # http://ruby-doc.org/stdlib-2.1.5/libdoc/net/imap/rdoc/Net/IMAP.html#method-i-capability
  capabilities = imap.capability

  @logger.debug("imap capabilities: #{capabilities.join(',')}") if @debug

  if @client_type == 'local'
    unless capabilities.include? "IDLE" || @debug
      @logger.info "'IDLE' IMAP capability not available in server: #{server}"
      imap.disconnect
      exit if exitOnFail
    end
  end

  begin
    # login
    imap. username, password
  rescue Net::IMAP::NoResponseError => e
    # mostly due to credentials error
    @errors = {exception: e}
  rescue Net::IMAP::BadResponseError => e
    @errors = {exception: e}
  rescue
    @errors = {exception: e}
  end

  # return IMAP connection handler
  imap
end

#loggerObject



23
24
25
# File 'lib/client.rb', line 23

def logger
  @logger
end

#logToLoggly(messageBody) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/client.rb', line 211

def logToLoggly(messageBody)

  if(@logglyTag)
    begin
      HTTParty.post("http://logs-01.loggly.com/bulk/0d67f93b-6568-4b00-9eca-97d0ea0bd5a1/tag/#{@logglyTag}/",
                    body: messageBody.to_json,
                    headers: { 'Content-Type' => 'application/json' } )
    rescue
      true
    end

  else
    if @debug && !@logger.nil?
      @logger.info "Logging to Loggly disabled"
      @logger.info messageBody
    end
  end

end

#process_email(mail, uid, stamp = nil) ⇒ Object

Process each email downloaded from imap-server and creates meta file that will be sent over to the navi-ai service. Meta will content information like: [‘from’, ‘to’, ‘cc’, …, ‘body_url’]. This information is then used by navi-ai to parse the body content.



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/client.rb', line 135

def process_email(mail, uid, stamp = nil)
  meta = Hash.new
  custom_uid = (Time.now.to_f * 1000).to_s + "_" + mail.__id__.to_s

  meta["from"] = mail[:from].to_s
  meta["to"] = mail[:to].to_s
  meta["cc"] = mail[:cc].to_s
  meta["subject"] = mail.subject
  meta["date"] = mail.date.to_s

  if mail.multipart?
    for i in 0...mail.parts.length
      m = download(mail.parts[i], custom_uid)
      meta.merge!(m) unless m.nil?
    end
  else
    m = download(mail, custom_uid)
    meta.merge!(m) unless m.nil?
  end

  if stamp.nil?
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}")
  else
    save(meta, "meta/#{uid.to_s + '_' + custom_uid}", stamp)
  end

end

#retrieve_emails(imap, search_condition, folder, &process_email_block) ⇒ Object

retrieve_emails

retrieve any mail from a folder, followin specified serach condition for any mail retrieved call a specified block



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/client.rb', line 77

def retrieve_emails(imap, search_condition, folder, &process_email_block)

  # examine will read email and sets flags unread
  # https://stackoverflow.com/questions/16516464/read-gmail-xoauth-mails-without-marking-it-read
  imap.examine folder

  message_ids = imap.uid_search(search_condition)

  meta_dir = @download_path + 'meta/'

  message_ids_saved = getMessageUUIds(meta_dir)

  message_ids = message_ids - message_ids_saved
  message_ids = message_ids&.sort {|msg_a, msg_b| msg_b <=> msg_a}

  if @debug
    if message_ids.empty?
      @logger.info "No new emails found..."
    elsif message_ids_saved.any?
      @logger.info "Found emails saved in your #{@client_type}. Downloading only #{message_ids.count} new emails..."
    else
      @logger.info "Downloading #{message_ids.count} emails."
    end
  end

  message_ids.each_with_index do |message_id, i|
    begin
      # fetch all the email contents
      data = imap.uid_fetch(message_id, "RFC822")
      data.each do |d|
        msg = d.attr['RFC822']
        # instantiate a Mail object to avoid further IMAP parameters nightmares
        mail = Mail.read_from_string msg

        # call the block with mail object as param
        process_email_block.call mail, i, i == message_ids.length-1, message_id

        # mark as read
        if @mark_as_read
          imap.store(message_id, "+FLAGS", [:Seen])
        end
      end
    rescue => e
      unless logger.nil?
        logger.info "Issue processing email for uuid ##{message_id}, #{e.message}"
      end

      logToLoggly({event:"EMAIL_SYNC_FAILED", env: @env, storage: @client_type, email: @current_user_email, uuid: message_id, error: e.message})
      raise e
    end
  end
end

#setupLoggly(tag) ⇒ Object



231
232
233
# File 'lib/client.rb', line 231

def setupLoggly(tag)
  @logglyTag = tag
end

#shutdown(imap) ⇒ Object

If the gem is being used for local-lockbox mode, after fetching all emails, the process will go idle mode. If user send the interrupt command, it will call shutdown to disconnect the connection with imap server



202
203
204
205
206
207
208
209
# File 'lib/client.rb', line 202

def shutdown(imap)
  imap.idle_done
  imap.logout unless imap.disconnected?
  imap.disconnect

  @logger.info "#{$0} has ended (crowd applauds)"
  exit 0
end

#time_nowObject



195
196
197
# File 'lib/client.rb', line 195

def time_now
  Time.now.utc.iso8601(3)
end