mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
Add brakeman and some tests
This commit is contained in:
parent
67916c10c4
commit
41604d71a6
9 changed files with 166 additions and 19 deletions
1
Gemfile
1
Gemfile
|
|
@ -45,6 +45,7 @@ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
|
|||
gem 'jwt'
|
||||
|
||||
group :development, :test do
|
||||
gem 'brakeman', require: false
|
||||
gem 'debug', platforms: %i[mri mingw x64_mingw]
|
||||
gem 'dotenv-rails'
|
||||
gem 'factory_bot_rails'
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@ GEM
|
|||
bigdecimal (3.1.9)
|
||||
bootsnap (1.18.4)
|
||||
msgpack (~> 1.2)
|
||||
brakeman (7.0.2)
|
||||
racc
|
||||
builder (3.3.0)
|
||||
byebug (11.1.3)
|
||||
chartkick (5.1.3)
|
||||
|
|
@ -476,6 +478,7 @@ DEPENDENCIES
|
|||
aws-sdk-kms (~> 1.96.0)
|
||||
aws-sdk-s3 (~> 1.177.0)
|
||||
bootsnap
|
||||
brakeman
|
||||
chartkick
|
||||
data_migrate
|
||||
database_consistency
|
||||
|
|
|
|||
|
|
@ -31,6 +31,12 @@ class ApplicationController < ActionController::Base
|
|||
redirect_to root_path, notice: 'Your account is not active.', status: :see_other
|
||||
end
|
||||
|
||||
def authenticate_non_self_hosted!
|
||||
return unless DawarichSettings.self_hosted?
|
||||
|
||||
redirect_to root_path, notice: 'You are not authorized to perform this action.', status: :see_other
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_self_hosted_status
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class Settings::SubscriptionsController < ApplicationController
|
||||
before_action :authenticate_user!
|
||||
before_action :authenticate_non_self_hosted!
|
||||
|
||||
def index; end
|
||||
|
||||
|
|
@ -16,13 +17,12 @@ class Settings::SubscriptionsController < ApplicationController
|
|||
{ algorithm: 'HS256' }
|
||||
).first.symbolize_keys
|
||||
|
||||
# Verify this is for the current user
|
||||
unless decoded_token[:user_id] == current_user.id
|
||||
redirect_to settings_subscriptions_path, alert: 'Invalid subscription update request.'
|
||||
return
|
||||
end
|
||||
|
||||
current_user.update!(status: decoded_token[:status])
|
||||
current_user.update!(status: decoded_token[:status], active_until: decoded_token[:active_until])
|
||||
|
||||
redirect_to settings_subscriptions_path, notice: 'Your subscription has been updated successfully!'
|
||||
rescue JWT::DecodeError
|
||||
|
|
|
|||
|
|
@ -59,12 +59,11 @@ module Distanceable
|
|||
return 0 if points.length < 2
|
||||
|
||||
total_meters = points.each_cons(2).sum do |point1, point2|
|
||||
connection.select_value(<<-SQL.squish)
|
||||
SELECT ST_Distance(
|
||||
ST_GeomFromEWKT('#{point1.lonlat}')::geography,
|
||||
ST_GeomFromEWKT('#{point2.lonlat}')::geography
|
||||
)
|
||||
SQL
|
||||
connection.select_value(
|
||||
'SELECT ST_Distance(ST_GeomFromEWKT($1)::geography, ST_GeomFromEWKT($2)::geography)',
|
||||
nil,
|
||||
[point1.lonlat, point2.lonlat]
|
||||
)
|
||||
end
|
||||
|
||||
total_meters.to_f / DISTANCE_UNITS[unit.to_sym]
|
||||
|
|
|
|||
|
|
@ -12,13 +12,17 @@ module Visits
|
|||
end
|
||||
|
||||
def call
|
||||
bounding_box = "ST_MakeEnvelope(#{sw_lng}, #{sw_lat}, #{ne_lng}, #{ne_lat}, 4326)"
|
||||
|
||||
Visit
|
||||
.includes(:place)
|
||||
.where(user:)
|
||||
.joins(:place)
|
||||
.where("ST_Contains(#{bounding_box}, ST_SetSRID(places.lonlat::geometry, 4326))")
|
||||
.where(
|
||||
'ST_Contains(ST_MakeEnvelope(?, ?, ?, ?, 4326), ST_SetSRID(places.lonlat::geometry, 4326))',
|
||||
sw_lng,
|
||||
sw_lat,
|
||||
ne_lng,
|
||||
ne_lat
|
||||
)
|
||||
.order(started_at: :desc)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ RSpec.describe BulkVisitsSuggestingJob, type: :job do
|
|||
let(:start_at) { 1.day.ago.beginning_of_day }
|
||||
let(:end_at) { 1.day.ago.end_of_day }
|
||||
let(:user) { create(:user) }
|
||||
let(:inactive_user) { create(:user, status: :inactive) }
|
||||
let(:inactive_user) { create(:user, :inactive) }
|
||||
let(:user_with_points) { create(:user) }
|
||||
let(:time_chunks) { [[start_at, end_at]] }
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ RSpec.describe User, type: :model do
|
|||
|
||||
describe '#activate' do
|
||||
context 'when self-hosted' do
|
||||
let!(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
||||
let!(:user) { create(:user, :inactive) }
|
||||
|
||||
before do
|
||||
allow(DawarichSettings).to receive(:self_hosted?).and_return(true)
|
||||
|
|
@ -49,7 +49,7 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
|
||||
it 'does not activate user' do
|
||||
user = create(:user, status: :inactive, active_until: 1.day.ago)
|
||||
user = create(:user, :inactive)
|
||||
|
||||
expect(user.active?).to be_falsey
|
||||
expect(user.active_until).to be_within(1.minute).of(1.day.ago)
|
||||
|
|
@ -194,7 +194,7 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
|
||||
context 'when user is inactive' do
|
||||
let(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
||||
let(:user) { create(:user, :inactive) }
|
||||
|
||||
it 'returns false' do
|
||||
expect(user.can_subscribe?).to be_falsey
|
||||
|
|
@ -216,7 +216,7 @@ RSpec.describe User, type: :model do
|
|||
end
|
||||
|
||||
context 'when user is inactive' do
|
||||
let(:user) { create(:user, status: :inactive, active_until: 1.day.ago) }
|
||||
let(:user) { create(:user, :inactive) }
|
||||
|
||||
it 'returns true' do
|
||||
expect(user.can_subscribe?).to be_truthy
|
||||
|
|
|
|||
|
|
@ -1,7 +1,141 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe "Settings::Subscriptions", type: :request do
|
||||
describe "GET /index" do
|
||||
pending "add some examples (or delete) #{__FILE__}"
|
||||
RSpec.describe 'Settings::Subscriptions', type: :request do
|
||||
let(:user) { create(:user, :inactive) }
|
||||
let(:jwt_secret) { ENV['JWT_SECRET_KEY'] }
|
||||
|
||||
before do
|
||||
stub_const('ENV', ENV.to_h.merge('JWT_SECRET_KEY' => 'test_secret'))
|
||||
stub_request(:any, 'https://api.github.com/repos/Freika/dawarich/tags')
|
||||
.to_return(status: 200, body: '[{"name": "1.0.0"}]', headers: {})
|
||||
end
|
||||
|
||||
context 'when Dawarich is not self-hosted' do
|
||||
before do
|
||||
allow(DawarichSettings).to receive(:self_hosted?).and_return(false)
|
||||
end
|
||||
|
||||
describe 'GET /settings/subscriptions' do
|
||||
context 'when user is not authenticated' do
|
||||
it 'redirects to login page' do
|
||||
get settings_subscriptions_path
|
||||
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is authenticated' do
|
||||
before { sign_in user }
|
||||
|
||||
it 'returns successful response' do
|
||||
get settings_subscriptions_path
|
||||
|
||||
expect(response).to be_successful
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /settings/subscriptions/callback' do
|
||||
context 'when user is not authenticated' do
|
||||
it 'redirects to login page' do
|
||||
get subscription_callback_settings_subscriptions_path(token: 'invalid')
|
||||
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user is authenticated' do
|
||||
before { sign_in user }
|
||||
|
||||
context 'with valid token' do
|
||||
let(:token) do
|
||||
JWT.encode(
|
||||
{ user_id: user.id, status: 'active', active_until: 1.year.from_now },
|
||||
jwt_secret,
|
||||
'HS256'
|
||||
)
|
||||
end
|
||||
|
||||
it 'updates user status and redirects with success message' do
|
||||
get subscription_callback_settings_subscriptions_path(token: token)
|
||||
|
||||
expect(user.reload.status).to eq('active')
|
||||
expect(user.active_until).to be_within(1.day).of(1.year.from_now)
|
||||
expect(response).to redirect_to(settings_subscriptions_path)
|
||||
expect(flash[:notice]).to eq('Your subscription has been updated successfully!')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token for different user' do
|
||||
let(:other_user) { create(:user) }
|
||||
let(:token) do
|
||||
JWT.encode(
|
||||
{ user_id: other_user.id, status: 'active' },
|
||||
jwt_secret,
|
||||
'HS256'
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not update status and redirects with error' do
|
||||
get subscription_callback_settings_subscriptions_path(token: token)
|
||||
|
||||
expect(user.reload.status).not_to eq('active')
|
||||
expect(response).to redirect_to(settings_subscriptions_path)
|
||||
expect(flash[:alert]).to eq('Invalid subscription update request.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid token' do
|
||||
it 'redirects with decode error message' do
|
||||
get subscription_callback_settings_subscriptions_path(token: 'invalid')
|
||||
|
||||
expect(response).to redirect_to(settings_subscriptions_path)
|
||||
expect(flash[:alert]).to eq('Failed to verify subscription update.')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with malformed token data' do
|
||||
let(:token) do
|
||||
JWT.encode({ user_id: 'invalid', status: nil }, jwt_secret, 'HS256')
|
||||
end
|
||||
|
||||
it 'redirects with invalid data message' do
|
||||
get subscription_callback_settings_subscriptions_path(token: token)
|
||||
|
||||
expect(response).to redirect_to(settings_subscriptions_path)
|
||||
expect(flash[:alert]).to eq('Invalid subscription update request.')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when Dawarich is self-hosted' do
|
||||
before do
|
||||
allow(DawarichSettings).to receive(:self_hosted?).and_return(true)
|
||||
sign_in user
|
||||
end
|
||||
|
||||
describe 'GET /settings/subscriptions' do
|
||||
context 'when user is not authenticated' do
|
||||
it 'redirects to root path' do
|
||||
get settings_subscriptions_path
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /settings/subscriptions/callback' do
|
||||
context 'when user is not authenticated' do
|
||||
it 'redirects to root path' do
|
||||
get subscription_callback_settings_subscriptions_path(token: 'invalid')
|
||||
|
||||
expect(response).to redirect_to(root_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in a new issue