Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
ninoseki committed Apr 10, 2019
1 parent 8bb6fe0 commit bfe414d
Show file tree
Hide file tree
Showing 47 changed files with 1,045 additions and 5 deletions.
11 changes: 7 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/tmp/

# Used by dotenv library to load environment variables.
# .env
.env

## Specific to RubyMotion:
.dat*
Expand Down Expand Up @@ -42,9 +42,12 @@ build-iPhoneSimulator/

# for a library or gem, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# Gemfile.lock
# .ruby-version
# .ruby-gemset
Gemfile.lock
.ruby-version
.ruby-gemset

# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
.rvmrc

## RSpec
.rspec_status
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--format documentation
--color
--require spec_helper
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
sudo: false
language: ruby
cache: bundler
rvm:
- 2.6
before_install:
- gem update --system
- gem install bundler
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source "https://rubygems.org"

# Specify your gem's dependencies in koji.gemspec
gemspec
90 changes: 89 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,89 @@
# koji
# koji

[![Build Status](https://travis-ci.org/ninoseki/koji.svg?branch=master)](https://travis-ci.org/ninoseki/koji)
[![Coverage Status](https://coveralls.io/repos/github/ninoseki/koji/badge.svg?branch=master)](https://coveralls.io/github/ninoseki/koji?branch=master)

koji (`工事`) is a development/staging environment detector.

## Features

- Web app debug feature detection (CodeIgniter, Django, FuelPHP and etc.)
- Suspicious domain detection (e.g. `dev.*.com`, `stg.*.com`)
- Self-signed certificate detection

## Installation

```bash
gem install koji
```

## Usage

### As a CLI

```bash
$ koji help
Commands:
koji check URL # check a given URL
koji help [COMMAND] # Describe available commands or one specific command

$ koji check https://github.com/ninoseki/koji
{
"verdict": "Not underconstruction",
"score": 0
}

$ koji check https://dev.example.com
{
"verdict": "Possibly underconstruction",
"score": 50
}

$ koji check http://phpdebugbar.com/
{
"verdict": "Underconstruction",
"score": 100
}

$ koji check http://phpdebugbar.com/ --verbose
{
"verdict": "Underconstruction",
"score": 100,
"plugin_reports": [
{
"name": "PHPDebugBar",
"evidence_list": [
"The website contains PHP DebugBar"
],
"score": 100
}
]
}

$ koji check https://self-signed.badssl.com/ --verbose
{
"verdict": "Underconstruction",
"score": 100,
"plugin_reports": [
{
"name": "SelfSignedCertificate",
"evidence_list": [
"The website has a self-signed certificate"
],
"score": 100
}
]
}
```

### As a library

```ruby
require "koji"

website = Koji::Website.new("http://example.com")
detector = Koji::Detector.new(website)

puts detector.report
puts detector.detailed_report
```
8 changes: 8 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

require "bundler/gem_tasks"
require "rspec/core/rake_task"

RSpec::Core::RakeTask.new(:spec)

task default: :spec
14 changes: 14 additions & 0 deletions bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env ruby

require "bundler/setup"
require "koji"

# You can add fixtures and/or initialization code here to make experimenting
# with your gem easier. You can also use a different console, if you like.

# (If you use this, don't forget to add pry to your Gemfile!)
# require "pry"
# Pry.start

require "irb"
IRB.start(__FILE__)
8 changes: 8 additions & 0 deletions bin/setup
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
set -vx

bundle install

# Do any other automated setup that you need to do here
8 changes: 8 additions & 0 deletions exe/koji
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

$LOAD_PATH.unshift("#{__dir__}/../lib")

require "koji"

Koji::CLI.start
39 changes: 39 additions & 0 deletions koji.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

lib = File.expand_path('lib', __dir__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require "koji/version"

Gem::Specification.new do |spec|
spec.name = "koji"
spec.version = Koji::VERSION
spec.authors = ["Manabu Niseki"]
spec.email = ["manabu.niseki@gmail.com"]

spec.summary = 'A development/staging environment detector.'
spec.description = 'A development/staging environment detector.'
spec.homepage = "https://github.com/ninoseki/koji"
spec.license = "MIT"

# Specify which files should be added to the gem when it is released.
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
spec.files = Dir.chdir(File.expand_path(__dir__)) do
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
end
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 2.0"
spec.add_development_dependency "coveralls", "~> 0.8"
spec.add_development_dependency "rake", "~> 12.3"
spec.add_development_dependency "rspec", "~> 3.8"
spec.add_development_dependency "webmock", "~> 3.5"

spec.add_dependency "http", "~> 4.1"
spec.add_dependency "mem", "~> 0.1"
spec.add_dependency "oga", "~> 2.15"
spec.add_dependency "public_suffix", "~> 3.0"
spec.add_dependency "require_all", "~> 2.0"
spec.add_dependency "thor", "~> 0.19"
end
33 changes: 33 additions & 0 deletions lib/koji.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require "mem"

module Koji
class << self
include Mem

def plugins
[]
end
memoize :plugins
end
end

require "koji/version"
require "koji/error"

require "koji/website"

require "koji/plugins/base"
require "koji/plugins/cakephp"
require "koji/plugins/codeigniter"
require "koji/plugins/django"
require "koji/plugins/domain"
require "koji/plugins/fuelphp"
require "koji/plugins/php_debugbar"
require "koji/plugins/phpinfo"
require "koji/plugins/self_signed_cert"
require "koji/plugins/symfony"

require "koji/detector"
require "koji/cli"
19 changes: 19 additions & 0 deletions lib/koji/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

require "thor"
require "json"

module Koji
class CLI < Thor
desc "check URL", "check a given URL"
option :verbose, type: :boolean, default: false
def check(url)
website = Website.new(url)
detector = Detector.new(website)
verbose = options.dig("verbose") || false
report = verbose ? detector.detailed_report : detector.report

puts JSON.pretty_generate(report)
end
end
end
44 changes: 44 additions & 0 deletions lib/koji/detector.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# frozen_string_literal: true

module Koji
class Detector
attr_reader :website

def initialize(website)
@website = website
end

def score
plugins.map(&:score).sum
end

def verdict
case score.to_i
when -Float::INFINITY..49
"Not underconstruction"
when 50..99
"Possibly underconstruction"
when 100..Float::INFINITY
"Underconstruction"
end
end

def report
{
verdict: verdict,
score: score
}
end

def detailed_report
plugin_reports = plugins.map(&:report).select { |report| report.dig(:score).to_i.positive? }
report.merge(plugin_reports: plugin_reports)
end

private

def plugins
@plugins ||= Koji.plugins.map { |klass| klass.new website }
end
end
end
5 changes: 5 additions & 0 deletions lib/koji/error.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# frozen_string_literal: true

module Koji
class Error < StandardError; end
end
37 changes: 37 additions & 0 deletions lib/koji/plugins/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# frozen_string_literal: true

module Koji
module Plugins
class Base
def self.inherited(child)
Koji.plugins << child
end

attr_reader :website

def initialize(website)
@website = website
end

def evidence_list
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end

def score
raise NotImplementedError, "You must implement #{self.class}##{__method__}"
end

def name
self.class.to_s.split("::").last
end

def report
{
name: name,
evidence_list: evidence_list,
score: score
}
end
end
end
end
21 changes: 21 additions & 0 deletions lib/koji/plugins/cakephp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Koji
module Plugins
class CakePHP < Base
def debug_toolbar
website.body&.to_s&.include?("js_debug_toolbar.js") && website.body&.to_s&.include?("debug_toolbar.css")
end

def evidence_list
@evidence_list ||= [].tap do |out|
out << "The website contains CakePHP's debug toolbar" if debug_toolbar
end
end

def score
evidence_list.empty? ? 0 : 100
end
end
end
end

0 comments on commit bfe414d

Please sign in to comment.