Merge branch 'master' into ruby-2.7
This commit is contained in:
Коммит
07baf71840
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
engines:
|
||||
bundler-audit:
|
||||
enabled: true
|
||||
enabled: false
|
||||
csslint:
|
||||
enabled: false
|
||||
duplication:
|
||||
|
@ -15,6 +15,8 @@ engines:
|
|||
enabled: true
|
||||
rubocop:
|
||||
enabled: true
|
||||
config:
|
||||
file: .rubocop.yml
|
||||
ratings:
|
||||
paths:
|
||||
- Gemfile.lock
|
||||
|
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
- name: Set up Ruby ${{ matrix.ruby }}
|
||||
uses: actions/setup-ruby@v1
|
||||
with:
|
||||
version: ${{ matrix.ruby }}
|
||||
ruby-version: ${{ matrix.ruby }}
|
||||
- name: Build and test with Rake
|
||||
run: |
|
||||
gem install bundler
|
||||
|
@ -27,3 +27,4 @@ jobs:
|
|||
bundle exec rake db:schema:load
|
||||
bundle exec rake db:migrate
|
||||
bundle exec rspec spec
|
||||
bundle exec rubocop
|
||||
|
|
1160
.rubocop.yml
1160
.rubocop.yml
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
29
Gemfile
29
Gemfile
|
@ -1,33 +1,38 @@
|
|||
source 'https://rubygems.org'
|
||||
# frozen_string_literal: true
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
gemspec
|
||||
|
||||
gem "activerecord"
|
||||
gem "dalli"
|
||||
gem "rack_csrf"
|
||||
gem "sinatra-activerecord"
|
||||
gem "rake"
|
||||
gem "sinatra"
|
||||
gem "sinatra-activerecord"
|
||||
gem "sinatra-contrib"
|
||||
gem "dalli"
|
||||
|
||||
group :development do
|
||||
gem "jdbc-sqlite3", platform: :jruby
|
||||
gem "pry-nav"
|
||||
gem "jdbc-sqlite3", :platform => :jruby
|
||||
gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
|
||||
gem "sqlite3", platform: [:ruby, :mswin, :mingw]
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "mechanize"
|
||||
gem "watir"
|
||||
gem "vcr"
|
||||
gem "webmock"
|
||||
gem "rspec"
|
||||
gem "database_cleaner"
|
||||
gem "guard-rspec"
|
||||
gem "ruby_gntp"
|
||||
gem "mechanize"
|
||||
gem "poltergeist"
|
||||
gem "rspec"
|
||||
gem "rubocop", "< 0.68"
|
||||
gem "rubocop-github"
|
||||
gem "rubocop-performance"
|
||||
gem "ruby_gntp"
|
||||
gem "simplecov"
|
||||
gem "simplecov-json"
|
||||
gem "database_cleaner"
|
||||
gem "vcr"
|
||||
gem "watir"
|
||||
gem "webmock"
|
||||
end
|
||||
|
||||
group :production do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
guard :rspec, cmd: "bundle exec rspec", all_after_pass: true do
|
||||
require "guard/rspec/dsl"
|
||||
dsl = Guard::RSpec::Dsl.new(self)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
[![Build Status](https://travis-ci.org/github/darrrr.svg?branch=master)](https://travis-ci.org/github/darrrr) [![Code Climate](https://codeclimate.com/github/github/darrrr/badges/gpa.svg)](https://codeclimate.com/github/github/darrrr)
|
||||
[![Code Climate](https://codeclimate.com/github/github/darrrr/badges/gpa.svg)](https://codeclimate.com/github/github/darrrr)
|
||||
![Build + Test](https://github.com/github/darrrr/workflows/Build%20+%20Test/badge.svg?branch=master)
|
||||
|
||||
The Delegated Account Recovery Rigid Reusable Ruby (aka D.a.r.r.r.r. or "Darrrr") library is meant to be used as the fully-complete plumbing in your Rack application when implementing the [Delegated Account Recovery specification](https://github.com/facebook/DelegatedRecoverySpecification). This library is currently used for the implementation at [GitHub](https://githubengineering.com/recover-accounts-elsewhere/).
|
||||
|
||||
|
|
26
Rakefile
26
Rakefile
|
@ -1,8 +1,10 @@
|
|||
#!/usr/bin/env rake
|
||||
require 'bundler/gem_tasks'
|
||||
require 'net/http'
|
||||
require 'net/https'
|
||||
require 'date'
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "bundler/gem_tasks"
|
||||
require "net/http"
|
||||
require "net/https"
|
||||
require "date"
|
||||
|
||||
require_relative "app"
|
||||
require_relative "lib/darrrr"
|
||||
|
@ -16,7 +18,7 @@ end
|
|||
|
||||
|
||||
unless ENV["RACK_ENV"] == "production"
|
||||
require 'rspec/core/rake_task'
|
||||
require "rspec/core/rake_task"
|
||||
desc "Run RSpec"
|
||||
RSpec::Core::RakeTask.new do |t|
|
||||
t.verbose = false
|
||||
|
@ -27,16 +29,16 @@ unless ENV["RACK_ENV"] == "production"
|
|||
end
|
||||
|
||||
begin
|
||||
require 'rdoc/task'
|
||||
require "rdoc/task"
|
||||
rescue LoadError
|
||||
require 'rdoc/rdoc'
|
||||
require 'rake/rdoctask'
|
||||
require "rdoc/rdoc"
|
||||
require "rake/rdoctask"
|
||||
RDoc::Task = Rake::RDocTask
|
||||
end
|
||||
|
||||
RDoc::Task.new(:rdoc) do |rdoc|
|
||||
rdoc.rdoc_dir = 'rdoc'
|
||||
rdoc.title = 'SecureHeaders'
|
||||
rdoc.options << '--line-numbers'
|
||||
rdoc.rdoc_files.include('lib/**/*.rb')
|
||||
rdoc.rdoc_dir = "rdoc"
|
||||
rdoc.title = "SecureHeaders"
|
||||
rdoc.options << "--line-numbers"
|
||||
rdoc.rdoc_files.include("lib/**/*.rb")
|
||||
end
|
||||
|
|
4
app.rb
4
app.rb
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "sinatra"
|
||||
require "sinatra/multi_route"
|
||||
require "rack/csrf"
|
||||
|
@ -28,7 +30,7 @@ class MainController < Sinatra::Base
|
|||
|
||||
before do
|
||||
unless request.ssl?
|
||||
halt 401, "Not authorized\n" if ENV['RACK_ENV'] == :production
|
||||
halt 401, "Not authorized\n" if ENV["RACK_ENV"] == :production
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
$stdout.sync = true
|
||||
require_relative "app"
|
||||
require_relative "controllers/account_provider_controller"
|
||||
|
@ -5,9 +7,9 @@ require_relative "controllers/recovery_provider_controller"
|
|||
require_relative "controllers/well_known_config_controller"
|
||||
|
||||
configure do
|
||||
use Rack::Session::Cookie, :secret => ENV["COOKIE_SECRET"]
|
||||
use Rack::Session::Cookie, secret: ENV["COOKIE_SECRET"]
|
||||
unless Sinatra::Application.environment == :test
|
||||
use Rack::Csrf, :raise => true, :skip => MainController::UNAUTHED_ENDPOINTS
|
||||
use Rack::Csrf, raise: true, skip: MainController::UNAUTHED_ENDPOINTS
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ end
|
|||
Darrrr.register_account_provider(Darrrr.authority)
|
||||
Darrrr.register_recovery_provider(Darrrr.authority)
|
||||
|
||||
options = { :namespace => "app_v1", :compress => true }
|
||||
options = { namespace: "app_v1", compress: true }
|
||||
|
||||
# Uncomment to use memcached
|
||||
# Darrrr.cache = Dalli::Client.new('localhost:11211', options)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AccountProviderController < MainController
|
||||
# 1 select recovery provider
|
||||
get "/" do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../models/token"
|
||||
|
||||
class RecoveryProviderController < MainController
|
||||
|
@ -21,7 +23,7 @@ class RecoveryProviderController < MainController
|
|||
response[:status] = "save-failure"
|
||||
end
|
||||
|
||||
redirect to("#{account_provider.save_token_return}?#{response.map{|key, value| "#{key}=#{value}"}.join("&")}")
|
||||
redirect to("#{account_provider.save_token_return}?#{response.map { |key, value| "#{key}=#{value}" }.join("&")}")
|
||||
end
|
||||
|
||||
route :get, :post, "/recover-account" do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class WellKnownConfigController < MainController
|
||||
get "/.well-known/delegated-account-recovery/configuration" do
|
||||
JSON.pretty_generate(Darrrr.account_and_recovery_provider_config)
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
# coding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
Gem::Specification.new do |gem|
|
||||
gem.name = "darrrr"
|
||||
gem.version = "0.1.5"
|
||||
gem.licenses = ['MIT']
|
||||
gem.licenses = ["MIT"]
|
||||
|
||||
gem.summary = "Client library for the Delegated Recovery spec"
|
||||
gem.description = "See https://www.facebook.com/notes/protect-the-graph/improving-account-security-with-delegated-recovery/1833022090271267/"
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateTokens < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :tokens do |t|
|
||||
|
@ -5,6 +7,6 @@ class CreateTokens < ActiveRecord::Migration[5.2]
|
|||
t.text :token_blob
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddTokenIdToToken < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :tokens, :token_id, :string
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProviderToTokens < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :tokens, :provider, :string
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SeparateTokens < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
rename_table :tokens, :recovery_tokens
|
||||
|
|
12
db/schema.rb
12
db/schema.rb
|
@ -1,12 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This file is auto-generated from the current state of the database. Instead
|
||||
# of editing this file, please use the migrations feature of Active Record to
|
||||
# incrementally modify your database, and then regenerate this schema definition.
|
||||
#
|
||||
# Note that this schema.rb definition is the authoritative source for your
|
||||
# database schema. If you need to create the application database on another
|
||||
# system, you should be using db:schema:load, not running all the migrations
|
||||
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
||||
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
||||
# This file is the source Rails uses to define your schema when running `rails
|
||||
# db:schema:load`. When creating a new database, `rails db:schema:load` tends to
|
||||
# be faster and is potentially less error prone than running all of your
|
||||
# migrations from scratch. Old migrations may fail to apply correctly if those
|
||||
# migrations use external dependencies or application code.
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Darrrr
|
||||
module DefaultEncryptor
|
||||
class << self
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
module Darrrr
|
||||
class EncryptedDataIO < BinData::Record
|
||||
uint8 :version
|
||||
array :auth_tag, :type => :uint8, :initial_length => EncryptedData::AUTH_TAG_LENGTH
|
||||
array :iv, :type => :uint8, :initial_length => EncryptedData::IV_LENGTH
|
||||
array :ciphertext, :type => :uint8, :read_until => :eof
|
||||
array :auth_tag, type: :uint8, initial_length: EncryptedData::AUTH_TAG_LENGTH
|
||||
array :iv, type: :uint8, initial_length: EncryptedData::IV_LENGTH
|
||||
array :ciphertext, type: :uint8, read_until: :eof
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,7 +33,7 @@ module Darrrr
|
|||
# Returns the crypto API to be used. A thread local instance overrides the
|
||||
# globally configured value which overrides the default encryptor.
|
||||
def encryptor
|
||||
Thread.current[encryptor_key()] || @encryptor || DefaultEncryptor
|
||||
Thread.current[encryptor_key] || @encryptor || DefaultEncryptor
|
||||
end
|
||||
|
||||
# Overrides the global `encryptor` API to use
|
||||
|
@ -53,14 +53,14 @@ module Darrrr
|
|||
raise ArgumentError, "custom encryption class must respond to all of #{REQUIRED_CRYPTO_OPS}"
|
||||
end
|
||||
|
||||
Thread.current[encryptor_key()] = encryptor
|
||||
Thread.current[encryptor_key] = encryptor
|
||||
yield
|
||||
ensure
|
||||
Thread.current[encryptor_key()] = nil
|
||||
Thread.current[encryptor_key] = nil
|
||||
end
|
||||
|
||||
private def valid_encryptor?(encryptor)
|
||||
REQUIRED_CRYPTO_OPS.all? {|m| encryptor.respond_to?(m)}
|
||||
REQUIRED_CRYPTO_OPS.all? { |m| encryptor.respond_to?(m) }
|
||||
end
|
||||
|
||||
# Lazily loads attributes if attrs is nil. It makes an http call to the
|
||||
|
|
|
@ -4,17 +4,17 @@ module Darrrr
|
|||
class RecoveryTokenReader < BinData::Record
|
||||
uint8 :version
|
||||
uint8 :token_type
|
||||
array :token_id, :type => :uint8, :read_until => lambda { index + 1 == Darrrr::TOKEN_ID_BYTE_LENGTH }
|
||||
array :token_id, type: :uint8, read_until: lambda { index + 1 == Darrrr::TOKEN_ID_BYTE_LENGTH }
|
||||
uint8 :options
|
||||
uint16be :issuer_length
|
||||
string :issuer, :read_length => :issuer_length
|
||||
string :issuer, read_length: :issuer_length
|
||||
uint16be :audience_length
|
||||
string :audience, :read_length => :audience_length
|
||||
string :audience, read_length: :audience_length
|
||||
uint16be :issued_time_length
|
||||
string :issued_time, :read_length => :issued_time_length
|
||||
string :issued_time, read_length: :issued_time_length
|
||||
uint16be :data_length
|
||||
string :data, :read_length => :data_length
|
||||
string :data, read_length: :data_length
|
||||
uint16be :binding_data_length
|
||||
string :binding_data, :read_length => :binding_data_length
|
||||
string :binding_data, read_length: :binding_data_length
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,17 +4,17 @@ module Darrrr
|
|||
class RecoveryTokenWriter < BinData::Record
|
||||
uint8 :version
|
||||
uint8 :token_type
|
||||
array :token_id, :type => :uint8, :initial_length => Darrrr::TOKEN_ID_BYTE_LENGTH
|
||||
array :token_id, type: :uint8, initial_length: Darrrr::TOKEN_ID_BYTE_LENGTH
|
||||
uint8 :options
|
||||
uint16be :issuer_length, :value => lambda { issuer.length }
|
||||
uint16be :issuer_length, value: lambda { issuer.length }
|
||||
string :issuer
|
||||
uint16be :audience_length, :value => lambda { audience.length }
|
||||
uint16be :audience_length, value: lambda { audience.length }
|
||||
string :audience
|
||||
uint16be :issued_time_length, :value => lambda { issued_time.length }
|
||||
uint16be :issued_time_length, value: lambda { issued_time.length }
|
||||
string :issued_time
|
||||
uint16be :data_length, :value => lambda { data.length }
|
||||
uint16be :data_length, value: lambda { data.length }
|
||||
string :data
|
||||
uint16be :binding_data_length, :value => lambda { binding_data.length }
|
||||
uint16be :binding_data_length, value: lambda { binding_data.length }
|
||||
string :binding_data
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RecoveryToken < ActiveRecord::Base
|
||||
end
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require_relative "../../spec_helper"
|
||||
|
||||
module Darrrr
|
||||
describe AccountProvider, vcr: { :cassette_name => "delegated_account_recovery/recovery_provider" } do
|
||||
describe AccountProvider, vcr: { cassette_name: "delegated_account_recovery/recovery_provider" } do
|
||||
let(:recovery_provider) { example_recovery_provider }
|
||||
let(:account_provider) { AccountProvider.this }
|
||||
let(:token) { account_provider.generate_recovery_token(data: "hai", audience: recovery_provider).first }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require_relative "../../spec_helper"
|
||||
|
||||
module Darrrr
|
||||
describe RecoveryProvider, vcr: { :cassette_name => "delegated_account_recovery/recovery_provider" } do
|
||||
describe RecoveryProvider, vcr: { cassette_name: "delegated_account_recovery/recovery_provider" } do
|
||||
include DelegatedRecoveryHelpers
|
||||
|
||||
let(:recovery_provider) { example_recovery_provider }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require_relative "../../spec_helper"
|
||||
|
||||
module Darrrr
|
||||
describe RecoveryToken, vcr: { :cassette_name => "delegated_account_recovery/recovery_provider" } do
|
||||
describe RecoveryToken, vcr: { cassette_name: "delegated_account_recovery/recovery_provider" } do
|
||||
let(:binding) { SecureRandom.hex }
|
||||
let(:recovery_provider) { example_account_provider }
|
||||
let(:token) { AccountProvider.this.generate_recovery_token(data: "hai", audience: recovery_provider).first }
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require_relative "../spec_helper"
|
||||
|
||||
describe Darrrr, vcr: { :cassette_name => "delegated_account_recovery/recovery_provider", match_requests_on: [:method, :uri] } do
|
||||
describe Darrrr, vcr: { cassette_name: "delegated_account_recovery/recovery_provider", match_requests_on: [:method, :uri] } do
|
||||
context "#recovery_provider" do
|
||||
it "raises an error if you ask for an unregistered recovery provider" do
|
||||
expect {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../../spec_helper"
|
||||
|
||||
describe "AccountProviderController", vcr: { cassette_name: "delegated_account_recovery/integration_test" } do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../../spec_helper"
|
||||
|
||||
describe "Integration test", vcr: { cassette_name: "delegated_account_recovery/integration_test" } do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../../spec_helper"
|
||||
|
||||
describe "AccountProviderController", vcr: { cassette_name: "delegated_account_recovery/integration_test" } do
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "bundler/setup"
|
||||
require "pry"
|
||||
require "vcr"
|
||||
|
@ -9,7 +11,7 @@ require "capybara/dsl"
|
|||
require "capybara/poltergeist"
|
||||
require "sinatra"
|
||||
require "securerandom"
|
||||
require 'database_cleaner'
|
||||
require "database_cleaner"
|
||||
|
||||
ENV["ACCOUNT_PROVIDER_PUBLIC_KEY"] = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEks3CjRTWrTnEDEiz36ICsy3mOX7fhauJ3Jj3R6hN7rp0Q6zh3WKIhGMBR8Ccc1VKZ4eMqLmw/WQLHSAn22GD4g=="
|
||||
ENV["ACCOUNT_PROVIDER_PRIVATE_KEY"] = "MHcCAQEEIKrHDRd0Bn3PkY9fU4AaDErNIKPkMCdL9tGNvwyWXdPqoAoGCCqGSM49AwEHoUQDQgAEks3CjRTWrTnEDEiz36ICsy3mOX7fhauJ3Jj3R6hN7rp0Q6zh3WKIhGMBR8Ccc1VKZ4eMqLmw/WQLHSAn22GD4g=="
|
||||
|
@ -19,8 +21,8 @@ ENV["RECOVERY_PROVIDER_PUBLIC_KEY"] = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEcUoYO
|
|||
ENV["COOKIE_SECRET"] = SecureRandom.hex
|
||||
ENV["RACK_ENV"] = "test"
|
||||
|
||||
require 'simplecov'
|
||||
require 'simplecov-json'
|
||||
require "simplecov"
|
||||
require "simplecov-json"
|
||||
SimpleCov.formatters = [
|
||||
SimpleCov::Formatter::JSONFormatter,
|
||||
SimpleCov::Formatter::HTMLFormatter,
|
||||
|
|
Загрузка…
Ссылка в новой задаче