Class: AdsedareMattermost::Provider

Inherits:
Starship::TwoFactorProvider
  • Object
show all
Includes:
Logging
Defined in:
lib/adsedare_mattermost.rb

Instance Method Summary collapse

Constructor Details

#initialize(extract_2fa_code = nil) ⇒ Provider

Returns a new instance of Provider.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
# File 'lib/adsedare_mattermost.rb', line 14

def initialize(
  extract_2fa_code = nil
)
  @extract_2fa_code = extract_2fa_code
  unless @extract_2fa_code
    raise Error, "Pass extract_2fa_code block"
  end

  @token = ENV["ADSEDARE_MM_TOKEN"]
  @mm_host = ENV["ADSEDARE_MM_HOST"]

  @team_id = ENV["ADSEDARE_MM_TEAM_ID"]
  team_name = ENV["ADSEDARE_MM_TEAM_NAME"]

  @channel_id = ENV["ADSEDARE_MM_CHANNEL_ID"]
  channel_name = ENV["ADSEDARE_MM_CHANNEL_NAME"]

  unless @token
    raise Error, "ADSEDARE_MM_TOKEN is not set"
  end

  unless @mm_host
    raise Error, "ADSEDARE_MM_HOST is not set"
  end

  unless team_name || @team_id
    raise Error, "ADSEDARE_MM_TEAM_NAME and ADSEDARE_MM_TEAM_ID is not set"
  end

  unless @team_id
    logger.warn "ADSEDARE_MM_TEAM_ID is not set, will find by name: #{team_name}"
    @team_id = my_teams.find { |team| team["display_name"] == team_name }["id"]
    raise Error, "Team #{team_name} not found" unless @team_id
    logger.info "Using team: #{@team_id}"
  end

  unless channel_name || @channel_id
    raise Error, "ADSEDARE_MM_CHANNEL_NAME and ADSEDARE_MM_CHANNEL_ID is not set"
  end

  unless @channel_id
    logger.warn "ADSEDARE_MM_CHANNEL_ID is not set, will find by name: #{channel_name}"
    @channel_id = my_channels.find { |channel| channel["display_name"] == channel_name }["id"]
    raise Error, "Channel #{channel_name} not found" unless @channel_id
    logger.info "Using channel: #{@channel_id}"
  end

  @timeout_seconds = ENV["ADSEDARE_MM_TIMEOUT_SECONDS"] || 5
  @retry_limit = ENV["ADSEDARE_MM_RETRY_LIMIT"] || 5
  @since = Time.now

  @retry_counter = 0
end

Instance Method Details

#get_code(session_id, scnt) ⇒ Object

Raises:



119
120
121
122
123
124
125
126
127
128
# File 'lib/adsedare_mattermost.rb', line 119

def get_code(session_id, scnt)      
  @retry_counter = 1
  # Just to be sure we dont miss messages because Apple sends it before we got there
  @since = (Time.now.to_f * 1000).to_i - 3000
  
  code = retry_get_code

  return code if code
  raise Error, "2FA code not found"
end

#latest_postsObject

Raises:



86
87
88
89
90
91
92
93
# File 'lib/adsedare_mattermost.rb', line 86

def latest_posts
  response = Faraday.get("#{@mm_host}/api/v4/channels/#{@channel_id}/posts?since=#{@since.to_i}") do |req|
    req.headers["Authorization"] = "Bearer #{@token}"
  end
  raise Error, "Failed to get messages" unless response.success?

  JSON.parse(response.body)["posts"]
end

#my_channelsObject

Raises:



77
78
79
80
81
82
83
84
# File 'lib/adsedare_mattermost.rb', line 77

def my_channels
  response = Faraday.get("#{@mm_host}/api/v4/users/me/teams/#{@team_id}/channels") do |req|
    req.headers["Authorization"] = "Bearer #{@token}"
  end
  raise Error, "Failed to get channels" unless response.success?

  JSON.parse(response.body)
end

#my_teamsObject

Raises:



68
69
70
71
72
73
74
75
# File 'lib/adsedare_mattermost.rb', line 68

def my_teams
  response = Faraday.get("#{@mm_host}/api/v4/users/me/teams") do |req|
    req.headers["Authorization"] = "Bearer #{@token}"
  end
  raise Error, "Failed to get teams" unless response.success?

  JSON.parse(response.body)
end

#retry_get_codeObject



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/adsedare_mattermost.rb', line 95

def retry_get_code
  if @retry_counter > @retry_limit
    return nil
  end

  logger.info "Retry #{@retry_counter} of #{@retry_limit}"
  logger.info "Waiting for #{@timeout_seconds} seconds for 2FA code..."

  sleep(@timeout_seconds)
  
  # Update before request, since we dont want to miss messages due to any network delays
  new_since = (Time.now.to_f * 1000).to_i

  latest_messages = latest_posts.values.map { |post| post["message"] }
  code = @extract_2fa_code.call(latest_messages)

  @since = new_since
  @retry_counter += 1

  return code if code

  retry_get_code
end

#two_factor_typeObject



130
131
132
# File 'lib/adsedare_mattermost.rb', line 130

def two_factor_type
  "phone"
end