http_observatory 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/lib/http_observatory.rb +4 -0
  5. data/lib/http_observatory/api.rb +47 -0
  6. data/lib/http_observatory/connection.rb +19 -0
  7. data/lib/http_observatory/engine.rb +16 -0
  8. data/lib/http_observatory/models/base.rb +17 -0
  9. data/lib/http_observatory/models/grade_distribution.rb +16 -0
  10. data/lib/http_observatory/models/host_history.rb +23 -0
  11. data/lib/http_observatory/models/recent_scans.rb +15 -0
  12. data/lib/http_observatory/models/scan.rb +35 -0
  13. data/lib/http_observatory/models/scanner_states.rb +20 -0
  14. data/lib/http_observatory/models/test_result.rb +25 -0
  15. data/lib/http_observatory/request.rb +39 -0
  16. data/lib/http_observatory/version.rb +3 -0
  17. data/lib/tasks/http_observatory_tasks.rake +4 -0
  18. data/test/api_test.rb +21 -0
  19. data/test/dummy/README.rdoc +28 -0
  20. data/test/dummy/Rakefile +6 -0
  21. data/test/dummy/app/assets/javascripts/application.js +13 -0
  22. data/test/dummy/app/assets/stylesheets/application.css +15 -0
  23. data/test/dummy/app/controllers/application_controller.rb +5 -0
  24. data/test/dummy/app/helpers/application_helper.rb +2 -0
  25. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  26. data/test/dummy/bin/bundle +3 -0
  27. data/test/dummy/bin/rails +4 -0
  28. data/test/dummy/bin/rake +4 -0
  29. data/test/dummy/bin/setup +29 -0
  30. data/test/dummy/config.ru +4 -0
  31. data/test/dummy/config/application.rb +26 -0
  32. data/test/dummy/config/boot.rb +5 -0
  33. data/test/dummy/config/database.yml +25 -0
  34. data/test/dummy/config/environment.rb +5 -0
  35. data/test/dummy/config/environments/development.rb +41 -0
  36. data/test/dummy/config/environments/production.rb +79 -0
  37. data/test/dummy/config/environments/test.rb +42 -0
  38. data/test/dummy/config/initializers/assets.rb +11 -0
  39. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  40. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  41. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  42. data/test/dummy/config/initializers/inflections.rb +16 -0
  43. data/test/dummy/config/initializers/mime_types.rb +4 -0
  44. data/test/dummy/config/initializers/session_store.rb +3 -0
  45. data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
  46. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  47. data/test/dummy/config/locales/en.yml +23 -0
  48. data/test/dummy/config/routes.rb +56 -0
  49. data/test/dummy/config/secrets.yml +22 -0
  50. data/test/dummy/db/test.sqlite3 +0 -0
  51. data/test/dummy/log/test.log +360 -0
  52. data/test/dummy/public/404.html +67 -0
  53. data/test/dummy/public/422.html +67 -0
  54. data/test/dummy/public/500.html +66 -0
  55. data/test/dummy/public/favicon.ico +0 -0
  56. data/test/http_observatory_test.rb +8 -0
  57. data/test/test_helper.rb +21 -0
  58. metadata +196 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8705f933037bbacf62aeaedbc2ff9780863c7435
4
+ data.tar.gz: 8bcce65b569a306e0cbe1c19c62fc206534f27e0
5
+ SHA512:
6
+ metadata.gz: 43842f6bd243c41ab1dd41c8e26df00b6bacd7bc7cbd5cddc672db54762ead8cd966f2a683b92e5a30f207128d931e5d8cc9357ef131ec358e88d868b695840a
7
+ data.tar.gz: 082eee075dc7aafd81a027d6304588e07acf387a11a3d4dcb64ee61ec08cca5fb76175c90b5b0a9dd78b6356e1bdc69021b765d5960e7f98242b171b717cb98b
@@ -0,0 +1,20 @@
1
+ Copyright 2017 Simon Franzen
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'HttpObservatory'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,4 @@
1
+ require "http_observatory/engine"
2
+ module HttpObservatory
3
+ end
4
+
@@ -0,0 +1,47 @@
1
+ module HttpObservatory
2
+ #
3
+ # Api for application
4
+ #
5
+ class Api
6
+ class << self
7
+
8
+ def get_analyze(host)
9
+ response = Request.get('analyze', { 'host' => host })
10
+ Scan.new(response)
11
+ end
12
+
13
+ def post_analyze(host, params={})
14
+ response = Request.post('analyze', { 'host' => host, 'hidden' => params[:hidden], 'rescan' => params[:rescan] })
15
+ Scan.new(response)
16
+ end
17
+
18
+ def get_scan_results(scan_id)
19
+ response = Request.get("getScanResults", { 'scan' => scan_id })
20
+ response.keys.map{|key| TestResult.new(response[key]) }
21
+ end
22
+
23
+ def get_recent_scans(params={})
24
+ params[:min] = params[:min] ? params[:min] : 0
25
+ params[:max] = params[:max] ? params[:max] : 20
26
+ response = Request.get('getRecentScans', { min: params[:min], max: params[:max] })
27
+ RecentScans.new(response)
28
+ end
29
+
30
+ def get_host_history(host)
31
+ response = Request.get("getHostHistory", { 'host' => host })
32
+ response.map{|history| HostHistory.new(history) }
33
+ end
34
+
35
+ def get_grade_distribution
36
+ response = Request.get('getGradeDistribution')
37
+ GradeDistribution.new(response)
38
+ end
39
+
40
+ def get_scanner_states
41
+ response = Request.get('getScannerStates')
42
+ ScannerStates.new(response)
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,19 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module HttpObservatory
5
+ #
6
+ # See https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md
7
+ #
8
+ class Connection
9
+ BASE = 'https://http-observatory.security.mozilla.org/api/v1'
10
+
11
+ def self.api
12
+ Faraday.new(url: BASE) do |faraday|
13
+ faraday.response :logger
14
+ faraday.adapter Faraday.default_adapter
15
+ faraday.headers['Content-Type'] = 'application/json'
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require "http_observatory/models/base"
2
+ require "http_observatory/models/grade_distribution"
3
+ require "http_observatory/models/host_history"
4
+ require "http_observatory/models/recent_scans"
5
+ require "http_observatory/models/scan"
6
+ require "http_observatory/models/test_result"
7
+ require "http_observatory/models/scanner_states"
8
+ require "http_observatory/connection"
9
+ require "http_observatory/request"
10
+ require "http_observatory/api"
11
+
12
+ module HttpObservatory
13
+ class Engine < ::Rails::Engine
14
+ isolate_namespace HttpObservatory
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module HttpObservatory
2
+
3
+ #
4
+ # Base Class for API objects
5
+ #
6
+ class Base
7
+ attr_accessor :errors
8
+
9
+ def initialize(args = {})
10
+ args.each do |name, value|
11
+ attr_name = name.to_s.downcase.underscore
12
+ send("#{attr_name}=", value) if respond_to?("#{attr_name}=")
13
+ end
14
+ end
15
+ end
16
+
17
+ end
@@ -0,0 +1,16 @@
1
+ module HttpObservatory
2
+
3
+ #
4
+ # Host History Object
5
+ #
6
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#grade-distribution
7
+ #
8
+ class GradeDistribution < Base
9
+ attr_accessor :distribution
10
+
11
+ def initialize(args = {})
12
+ self.distribution = args
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module HttpObservatory
2
+
3
+ #
4
+ # Host History Object
5
+ #
6
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#host-history
7
+ #
8
+ class HostHistory < Base
9
+
10
+ attr_accessor :end_time,
11
+ :end_time_unix_timestamp,
12
+ :grade,
13
+ :scan_id,
14
+ :score
15
+
16
+ # def initialize(args = {})
17
+ # super(args)
18
+ # end
19
+
20
+ end
21
+
22
+
23
+ end
@@ -0,0 +1,15 @@
1
+ module HttpObservatory
2
+ #
3
+ # Recent Scans Object
4
+ #
5
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#recent-scans
6
+ #
7
+ class RecentScans < Base
8
+ attr_accessor :results
9
+
10
+ def initialize(args = {})
11
+ self.results = args
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,35 @@
1
+ module HttpObservatory
2
+
3
+ #
4
+ # Scan Object
5
+ #
6
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#scan
7
+ #
8
+ # The scan can exist in one of six states:
9
+ # * ABORTED aborted for internal technical reasons
10
+ # * FAILED failed to complete, typically due to the site being unavailable or timing out
11
+ # * FINISHED completed successfully
12
+ # * PENDING issued by the API but not yet picked up by a scanner instance
13
+ # * STARTING assigned to a scanning instance
14
+ # * RUNNING currently in the process of scanning a website
15
+
16
+ class Scan < Base
17
+ attr_accessor :end_time, # timestamp for when the scan completed
18
+ :grade, # final grade assessed upon a completed scan
19
+ :hidden, # whether the scan results are unlisted on the recent results page
20
+ :response_headers, # the entirety of the HTTP response headers
21
+ :likelihood_indicator, # Mozilla risk likelihod indicator that is the equivalent of the grade
22
+ :scan_id, # unique ID number assigned to the scan
23
+ :score, # final score assessed upon a completed (FINISHED) scan
24
+ :start_time, # timestamp for when the scan was first requested
25
+ :state, # the current state of the scan
26
+ :tests_failed, # the number of subtests that were assigned a fail result
27
+ :tests_passed, # the number of subtests that were assigned a passing result
28
+ :tests_quantity # the total number of tests available and assessed at the time of the scan
29
+
30
+ # def initialize(args = {})
31
+ # super(args)
32
+ # end
33
+
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module HttpObservatory
2
+ #
3
+ # Scanner State
4
+ #
5
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#scanner-state
6
+ #
7
+ class ScannerStates < Base
8
+
9
+ attr_accessor :aborted, # aborted for internal technical reasons
10
+ :failed, # failed to complete, typically due to the site being unavailable or timing out
11
+ :finished, # completed successfully
12
+ :pending, # issued by the API but not yet picked up by a scanner instance
13
+ :starting, # assigned to a scanning instance
14
+ :running # currently in the process of scanning a website
15
+
16
+ # def initialize(args = {})
17
+ # super(args)
18
+ # end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ module HttpObservatory
2
+ #
3
+ # Scan Object
4
+ #
5
+ # https://github.com/mozilla/http-observatory/blob/master/httpobs/docs/api.md#tests
6
+ #
7
+ class TestResult < Base
8
+
9
+ attr_accessor :expectation, # the expectation for a test result going in
10
+ :name, # the name of the test; this should be the same as the parent object's name
11
+ :output, # artifacts related to the test; these can vary widely between tests and are not guaranteed to be stable
12
+ :pass, # whether the test passed or failed; a test that meets or exceeds the expectation will be marked as passed
13
+ :result, # result of the test
14
+ :score_description, # short description describing what result means
15
+ :score_modifier # how much the result of the test affected the final score; should range between +5 and -50
16
+
17
+ # output data
18
+ # data generally as close to the raw output of the test as is possible. For example, in the strict-transport-security test, output -> data contains the raw Strict-Transport-Security header
19
+ # ???? other values under output have keys that vary; for example, the strict-transport-security test has a includeSubDomains key that is either set to True or False. Similarly, the redirection test contains a route key that contains an array of the URLs that were redirected to. See example below for more available keys.
20
+
21
+ # def initialize(args = {})
22
+ # super(args)
23
+ # end
24
+ end
25
+ end
@@ -0,0 +1,39 @@
1
+ module HttpObservatory
2
+
3
+ class Request
4
+ class << self
5
+
6
+ def get(path, query = {})
7
+ response, status = get_json(path, query)
8
+ status == 200 ? response : errors(response)
9
+ end
10
+
11
+ def post(path, query)
12
+ response, status = post_json(path, query)
13
+ status == 201 ? response : errors(response)
14
+ end
15
+
16
+ def errors(response)
17
+ error = { errors: { status: response["status"], message: response["message"] } }
18
+ response.merge(error)
19
+ end
20
+
21
+ def get_json(root_path, query = {})
22
+ query_string = query.map{|k,v| "#{k}=#{v}"}.join("&")
23
+ response = api.get("#{root_path}?#{query_string}")
24
+ [JSON.parse(response.body), response.status]
25
+ end
26
+
27
+ def post_json(root_path, query = {})
28
+ query_string = query.map{|k,v| "#{k}=#{v}"}.join("&")
29
+ response = api.post("#{root_path}?#{query_string}")
30
+ [JSON.parse(response.body), response.status]
31
+ end
32
+
33
+ def api
34
+ Connection.api
35
+ end
36
+ end
37
+ end
38
+
39
+ end
@@ -0,0 +1,3 @@
1
+ module HttpObservatory
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :http_observatory do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,21 @@
1
+ require 'test_helper'
2
+
3
+ class ApiTest < ActiveSupport::TestCase
4
+
5
+ # just a test if requests are working
6
+ setup do
7
+ WebMock.stub_request(:any, /api\/v1/).to_return(body: {}.to_json, status: 200,
8
+ headers: { 'Content-Length' => 3 })
9
+ end
10
+
11
+ test 'api_text' do
12
+ HttpObservatory::Api.get_analyze('www.zauberware.com')
13
+ HttpObservatory::Api.post_analyze('www.zauberware.com')
14
+ HttpObservatory::Api.get_scan_results(123123123)
15
+ HttpObservatory::Api.get_host_history('www.zauberware.com')
16
+ HttpObservatory::Api.get_recent_scans
17
+ HttpObservatory::Api.get_grade_distribution
18
+ HttpObservatory::Api.get_scanner_states
19
+ end
20
+
21
+ end
@@ -0,0 +1,28 @@
1
+ == README
2
+
3
+ This README would normally document whatever steps are necessary to get the
4
+ application up and running.
5
+
6
+ Things you may want to cover:
7
+
8
+ * Ruby version
9
+
10
+ * System dependencies
11
+
12
+ * Configuration
13
+
14
+ * Database creation
15
+
16
+ * Database initialization
17
+
18
+ * How to run the test suite
19
+
20
+ * Services (job queues, cache servers, search engines, etc.)
21
+
22
+ * Deployment instructions
23
+
24
+ * ...
25
+
26
+
27
+ Please feel free to use a different markup language if you do not plan to run
28
+ <tt>rake doc:app</tt>.
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .