An unofficial, mostly Bitwarden-compatible API server written in Ruby (Sinatra and ActiveRecord)
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

move request helpers to module and include in spec_helper add inital stab at "factory" for creating and logging in users

authored by

Johannes and committed by
joshua stein
8208d89c eafbf20f

+83 -152
+1 -1
lib/app.rb
··· 30 30 register Sinatra::Namespace 31 31 register Sinatra::ActiveRecordExtension 32 32 33 - set :root, File.dirname(__FILE__) 33 + set :root, File.expand_path("..", File.dirname(__FILE__)) 34 34 35 35 configure do 36 36 enable :logging
+2 -33
spec/attachment_spec.rb
··· 8 8 before do 9 9 User.all.delete_all 10 10 11 - post "/api/accounts/register", { 12 - :name => nil, 13 - :email => "api@example.com", 14 - :masterPasswordHash => Bitwarden.hashPassword("asdf", "api@example.com", 15 - User::DEFAULT_KDF_TYPE, 16 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 17 - :masterPasswordHint => nil, 18 - :key => Bitwarden.makeEncKey( 19 - Bitwarden.makeKey("adsf", "api@example.com", 20 - User::DEFAULT_KDF_TYPE, 21 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 22 - ), 23 - :kdf => Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE], 24 - :kdfIterations => Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE], 25 - } 26 - last_response.status.must_equal 200 27 - 28 - post "/identity/connect/token", { 29 - :grant_type => "password", 30 - :username => "api@example.com", 31 - :password => Bitwarden.hashPassword("asdf", "api@example.com", 32 - User::DEFAULT_KDF_TYPE, 33 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 34 - :scope => "api offline_access", 35 - :client_id => "browser", 36 - :deviceType => 3, 37 - :deviceIdentifier => SecureRandom.uuid, 38 - :deviceName => "firefox", 39 - :devicePushToken => "" 40 - } 41 - last_response.status.must_equal 200 42 - 43 - @access_token = last_json_response["access_token"] 11 + Rubywarden::Test::Factory.create_user 12 + @access_token = Rubywarden::Test::Factory.login_user 44 13 45 14 post_json "/api/ciphers", { 46 15 :type => 1,
+1 -15
spec/bitwarden_importer_spec.rb
··· 10 10 @master_key = Bitwarden.makeKey(@password, @email, 11 11 User::DEFAULT_KDF_TYPE, 12 12 Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]) 13 - 14 - post "/api/accounts/register", { 15 - :name => nil, 16 - :email => @email, 17 - :masterPasswordHash => Bitwarden.hashPassword(@password, @email, 18 - User::DEFAULT_KDF_TYPE, 19 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 20 - :masterPasswordHint => nil, 21 - :key => Bitwarden.makeEncKey(@master_key), 22 - :kdf => Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE], 23 - :kdfIterations => Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE], 24 - } 25 - last_response.status.must_equal 200 26 - 27 - @user = User.where(:email => @email).first! 13 + @user = Rubywarden::Test::Factory.create_user email: @email, password: @password 28 14 end 29 15 30 16 it "imports all expected data" do
+2 -33
spec/cipher_spec.rb
··· 6 6 before do 7 7 User.all.delete_all 8 8 9 - post "/api/accounts/register", { 10 - :name => nil, 11 - :email => "api@example.com", 12 - :masterPasswordHash => Bitwarden.hashPassword("asdf", "api@example.com", 13 - User::DEFAULT_KDF_TYPE, 14 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 15 - :masterPasswordHint => nil, 16 - :key => Bitwarden.makeEncKey( 17 - Bitwarden.makeKey("adsf", "api@example.com", 18 - User::DEFAULT_KDF_TYPE, 19 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 20 - ), 21 - :kdf => Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE], 22 - :kdfIterations => Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE], 23 - } 24 - last_response.status.must_equal 200 25 - 26 - post "/identity/connect/token", { 27 - :grant_type => "password", 28 - :username => "api@example.com", 29 - :password => Bitwarden.hashPassword("asdf", "api@example.com", 30 - User::DEFAULT_KDF_TYPE, 31 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 32 - :scope => "api offline_access", 33 - :client_id => "browser", 34 - :deviceType => 3, 35 - :deviceIdentifier => SecureRandom.uuid, 36 - :deviceName => "firefox", 37 - :devicePushToken => "" 38 - } 39 - last_response.status.must_equal 200 40 - 41 - @access_token = last_json_response["access_token"] 9 + Rubywarden::Test::Factory.create_user 10 + @access_token = Rubywarden::Test::Factory.login_user 42 11 end 43 12 44 13 it "should not allow access with bogus bearer token" do
+2 -36
spec/folder_spec.rb
··· 6 6 before do 7 7 User.all.delete_all 8 8 9 - post "/api/accounts/register", { 10 - :name => nil, 11 - :email => "api@example.com", 12 - :masterPasswordHash => Bitwarden.hashPassword("asdf", "api@example.com", 13 - User::DEFAULT_KDF_TYPE, 14 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 15 - :masterPasswordHint => nil, 16 - :key => Bitwarden.makeEncKey( 17 - Bitwarden.makeKey("adsf", "api@example.com", User::DEFAULT_KDF_TYPE, 18 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 19 - ), 20 - :kdf => Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE], 21 - :kdfIterations => Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE], 22 - } 23 - if last_response.status != 200 24 - raise last_response.inspect 25 - end 26 - 27 - post "/identity/connect/token", { 28 - :grant_type => "password", 29 - :username => "api@example.com", 30 - :password => Bitwarden.hashPassword("asdf", "api@example.com", 31 - User::DEFAULT_KDF_TYPE, 32 - Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 33 - :scope => "api offline_access", 34 - :client_id => "browser", 35 - :deviceType => 3, 36 - :deviceIdentifier => SecureRandom.uuid, 37 - :deviceName => "firefox", 38 - :devicePushToken => "" 39 - } 40 - if last_response.status != 200 41 - raise last_response.inspect 42 - end 43 - 44 - @access_token = last_json_response["access_token"] 9 + Rubywarden::Test::Factory.create_user 10 + @access_token = Rubywarden::Test::Factory.login_user 45 11 end 46 12 47 13 it "should not allow access with bogus bearer token" do
+3 -24
spec/spec_helper.rb
··· 18 18 ActiveRecord::Migrator.up "db/migrate" 19 19 20 20 # in case migrations changed what we're testing 21 - [ User, Cipher, Device, Folder ].each do |c| 21 + [ Attachment, User, Cipher, Device, Folder ].each do |c| 22 22 c.send(:reset_column_information) 23 23 end 24 24 25 25 include Rack::Test::Methods 26 26 27 - def last_json_response 28 - JSON.parse(last_response.body) 29 - end 30 - 31 - def get_json(path, params = {}, headers = {}) 32 - json_request :get, path, params, headers 33 - end 27 + Dir[Rubywarden::App.settings.root + '/spec/support/**/*.rb'].sort.each { |f| require f } 28 + include Rubywarden::Test::RequestHelpers 34 29 35 - def post_json(path, params = {}, headers = {}) 36 - json_request :post, path, params, headers 37 - end 38 - 39 - def put_json(path, params = {}, headers = {}) 40 - json_request :put, path, params, headers 41 - end 42 - 43 - def delete_json(path, params = {}, headers = {}) 44 - json_request :delete, path, params, headers 45 - end 46 - 47 - def json_request(verb, path, params = {}, headers = {}) 48 - send verb, path, params.to_json, 49 - headers.merge({ "CONTENT_TYPE" => "application/json" }) 50 - end 51 30 52 31 def app 53 32 Rubywarden::App
+41
spec/support/factories.rb
··· 1 + module Rubywarden 2 + module Test 3 + class Factory 4 + USER_EMAIL = "user@example.com" 5 + USER_PASSWORD = "p4ssw0rd" 6 + 7 + def self.create_user email: USER_EMAIL, password: USER_PASSWORD 8 + u = User.new 9 + u.email = email 10 + u.kdf_type = Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE] 11 + u.kdf_iterations = Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE] 12 + u.password_hash = Bitwarden.hashPassword(password, email, 13 + Bitwarden::KDF::TYPES[u.kdf_type], u.kdf_iterations) 14 + u.password_hint = "it's like password but not" 15 + u.key = Bitwarden.makeEncKey(Bitwarden.makeKey(password, email, 16 + Bitwarden::KDF::TYPES[u.kdf_type], u.kdf_iterations)) 17 + u.save 18 + u 19 + end 20 + 21 + def self.login_user email: USER_EMAIL, password: USER_PASSWORD 22 + post "/identity/connect/token", { 23 + :grant_type => "password", 24 + :username => email, 25 + :password => Bitwarden.hashPassword(password, email, 26 + User::DEFAULT_KDF_TYPE, 27 + Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE]), 28 + :scope => "api offline_access", 29 + :client_id => "browser", 30 + :deviceType => 3, 31 + :deviceIdentifier => SecureRandom.uuid, 32 + :deviceName => "firefox", 33 + :devicePushToken => "" 34 + } 35 + last_response.status.must_equal 200 36 + 37 + last_json_response["access_token"] 38 + end 39 + end 40 + end 41 + end
+30
spec/support/request_helpers.rb
··· 1 + module Rubywarden 2 + module Test 3 + module RequestHelpers 4 + def last_json_response 5 + JSON.parse(last_response.body) 6 + end 7 + 8 + def get_json(path, params = {}, headers = {}) 9 + json_request :get, path, params, headers 10 + end 11 + 12 + def post_json(path, params = {}, headers = {}) 13 + json_request :post, path, params, headers 14 + end 15 + 16 + def put_json(path, params = {}, headers = {}) 17 + json_request :put, path, params, headers 18 + end 19 + 20 + def delete_json(path, params = {}, headers = {}) 21 + json_request :delete, path, params, headers 22 + end 23 + 24 + def json_request(verb, path, params = {}, headers = {}) 25 + send verb, path, params.to_json, 26 + headers.merge({ "CONTENT_TYPE" => "application/json" }) 27 + end 28 + end 29 + end 30 + end
+1 -10
spec/user_spec.rb
··· 7 7 before do 8 8 User.all.delete_all 9 9 10 - u = User.new 11 - u.email = USER_EMAIL 12 - u.kdf_type = Bitwarden::KDF::TYPE_IDS[User::DEFAULT_KDF_TYPE] 13 - u.kdf_iterations = Bitwarden::KDF::DEFAULT_ITERATIONS[User::DEFAULT_KDF_TYPE] 14 - u.password_hash = Bitwarden.hashPassword(USER_PASSWORD, USER_EMAIL, 15 - Bitwarden::KDF::TYPES[u.kdf_type], u.kdf_iterations) 16 - u.password_hint = "it's like password but not" 17 - u.key = Bitwarden.makeEncKey(Bitwarden.makeKey(USER_PASSWORD, USER_EMAIL, 18 - Bitwarden::KDF::TYPES[u.kdf_type], u.kdf_iterations)) 19 - u.save 10 + u = Rubywarden::Test::Factory.create_user email: USER_EMAIL, password: USER_PASSWORD 20 11 end 21 12 22 13 it "should compare a user's hash" do