Class: OmniAuth::Slack::VerifySlackSignature

Inherits:
Object
  • Object
show all
Includes:
Debug
Defined in:
lib/omniauth-slack/slack.rb

Overview

Rack middleware to verify incoming slack request signature.

use OmniAuth::Slack::VerifySlackSignature

ENV ... TODO: Complete this section of required env variables. or consider having accepting a config block in the 'use' call.

Constant Summary

Constants included from Debug

Debug::LOG_ALL, Debug::LOG_NONE

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Debug

#debug, included

Methods included from CallerMethodName

#caller_method_name, included

Constructor Details

#initialize(app) ⇒ VerifySlackSignature

Returns a new instance of VerifySlackSignature.



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/omniauth-slack/slack.rb', line 43

def initialize(app)
  @app             = app
  @app_id          = nil
  @signing_secret  = nil
  
  middleware_instance = self
  
  if block_given?
    # Can set app_id and signing_secret from here.
    yield(middleware_instance)
  end
end

Instance Attribute Details

#app_idObject

Returns the value of attribute app_id.



41
42
43
# File 'lib/omniauth-slack/slack.rb', line 41

def app_id
  @app_id
end

#signing_secretObject

Returns the value of attribute signing_secret.



41
42
43
# File 'lib/omniauth-slack/slack.rb', line 41

def signing_secret
  @signing_secret
end

Instance Method Details

#call(env) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
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
# File 'lib/omniauth-slack/slack.rb', line 56

def call(env)
  @env = env
  @logger = logger = OmniAuth.logger
          
  debug{"calling middleware"}

  env['rack.input'].rewind
  body_string = env['rack.input'].read
  env['rack.input'].rewind
  
  debug{"VerifySlackSignature body_string: #{body_string}"}
  
  body_hash =
    begin
      body_string && JSON.load(body_string)
    rescue
      {}
    end
  
  if body_hash.to_a.size == 0
    debug{"not detecting JSON body"}
    pass
    
  else
    api_app_id      = body_hash['api_app_id']
    slack_signature = env['HTTP_X_SLACK_SIGNATURE']
    slack_timestamp = env['HTTP_X_SLACK_REQUEST_TIMESTAMP']
    
    if ! [api_app_id, slack_signature, slack_timestamp].all?
      logger.debug("(slack) VerifySlackSignature not detecting incoming Slack request")
      pass
      
    elsif signing_secret.to_s.empty?
      logger.info("(slack) VerifySlackSignature missing signing_secret")
      pass
      
    elsif app_id && app_id.to_s != api_app_id.to_s
      logger.info("(slack) VerifySlackSignature app_id mismatch")
      pass
      
    else
      computed_signature = 'v0=' + OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), signing_secret, "v0:#{slack_timestamp}:#{body_string}").to_s
      rslt = (slack_signature == computed_signature)
      
      if rslt
        logger.info("(slack) VerifySlackSignature: #{rslt}")
      else
        logger.info("(slack) VerifySlackSignature: #{rslt}  (slack: #{slack_signature}, computed: #{computed_signature})")
      end
      
      pass rslt
    end
  end
end

#pass(result = nil) ⇒ Object



111
112
113
114
115
# File 'lib/omniauth-slack/slack.rb', line 111

def pass(result = nil)
  @env['omniauth.slack.verification'] = result
  debug{"set env omniauth.slack.verification to: #{result}"}
  @app.call(@env)
end