Skip to content

Commit 42371d7

Browse files
authored
Merge from docusealco/wip
2 parents b6bb4d2 + 4116746 commit 42371d7

19 files changed

+229
-75
lines changed

.annotaterb.yml

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
:position: before
3+
:position_in_additional_file_patterns: before
4+
:position_in_class: before
5+
:position_in_factory: before
6+
:position_in_fixture: before
7+
:position_in_routes: before
8+
:position_in_serializer: before
9+
:position_in_test: before
10+
:classified_sort: true
11+
:exclude_controllers: true
12+
:exclude_factories: true
13+
:exclude_fixtures: false
14+
:exclude_helpers: true
15+
:exclude_scaffolds: true
16+
:exclude_serializers: false
17+
:exclude_sti_subclasses: false
18+
:exclude_tests: false
19+
:force: false
20+
:format_markdown: false
21+
:format_rdoc: false
22+
:format_yard: false
23+
:frozen: false
24+
:ignore_model_sub_dir: false
25+
:ignore_unknown_models: false
26+
:include_version: false
27+
:show_check_constraints: false
28+
:show_complete_foreign_keys: false
29+
:show_foreign_keys: true
30+
:show_indexes: true
31+
:simple_indexes: false
32+
:sort: false
33+
:timestamp: false
34+
:trace: false
35+
:with_comment: true
36+
:with_column_comments: true
37+
:with_table_comments: true
38+
:active_admin: false
39+
:command:
40+
:debug: false
41+
:hide_default_column_types: ''
42+
:hide_limit_column_types: ''
43+
:ignore_columns:
44+
:ignore_routes:
45+
:models: true
46+
:routes: false
47+
:skip_on_db_migrate: false
48+
:target_action: :do_annotations
49+
:wrapper:
50+
:wrapper_close:
51+
:wrapper_open:
52+
:classes_default_to_s: []
53+
:additional_file_patterns: []
54+
:model_dir:
55+
- app/models
56+
:require: []
57+
:root_dir:
58+
- ''

.github/workflows/ci.yml

+27
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,33 @@ jobs:
7777
run: |
7878
./node_modules/eslint/bin/eslint.js "app/javascript/**/*.js"
7979
80+
brakeman:
81+
name: Brakeman
82+
runs-on: ubuntu-latest
83+
steps:
84+
- uses: actions/checkout@v4
85+
- name: Install Ruby
86+
uses: ruby/setup-ruby@v1
87+
with:
88+
ruby-version: 3.4.1
89+
- name: Cache gems
90+
uses: actions/cache@v4
91+
with:
92+
path: vendor/bundle
93+
key: ${{ runner.os }}-gem-${{ hashFiles('**/Gemfile.lock') }}
94+
restore-keys: |
95+
${{ runner.os }}-gem-
96+
- name: Install gems
97+
run: |
98+
gem install bundler
99+
bundle config path vendor/bundle
100+
bundle install --jobs 4 --retry 4
101+
yarn install
102+
sudo apt-get update
103+
sudo apt-get install libvips
104+
- name: Run Brakeman
105+
run: bundle exec brakeman -q --exit-on-warn
106+
80107
rspec:
81108
name: RSpec
82109
runs-on: ubuntu-latest

Gemfile

+3-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ gem 'twitter_cldr', require: false
4646
gem 'tzinfo-data'
4747

4848
group :development, :test do
49-
gem 'annotate'
5049
gem 'better_html'
5150
gem 'bullet'
5251
gem 'debug'
@@ -63,6 +62,9 @@ group :development, :test do
6362
end
6463

6564
group :development do
65+
gem 'annotaterb'
66+
gem 'brakeman', require: false
67+
gem 'foreman', require: false
6668
gem 'letter_opener_web'
6769
gem 'web-console'
6870
end

Gemfile.lock

+7-4
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,7 @@ GEM
7474
uri (>= 0.13.1)
7575
addressable (2.8.7)
7676
public_suffix (>= 2.0.2, < 7.0)
77-
annotate (2.6.5)
78-
activerecord (>= 2.3.0)
79-
rake (>= 0.8.7)
77+
annotaterb (4.14.0)
8078
arabic-letter-connector (0.1.1)
8179
ast (2.4.2)
8280
aws-eventstream (1.3.0)
@@ -120,6 +118,8 @@ GEM
120118
bindex (0.8.1)
121119
bootsnap (1.18.4)
122120
msgpack (~> 1.2)
121+
brakeman (7.0.0)
122+
racc
123123
builder (3.3.0)
124124
bullet (8.0.0)
125125
activesupport (>= 3.0.0)
@@ -229,6 +229,7 @@ GEM
229229
ffi (1.17.1-arm64-darwin)
230230
ffi (1.17.1-x86_64-linux-gnu)
231231
ffi (1.17.1-x86_64-linux-musl)
232+
foreman (0.88.1)
232233
geom2d (0.4.1)
233234
globalid (1.2.1)
234235
activesupport (>= 6.1)
@@ -588,13 +589,14 @@ PLATFORMS
588589
x86_64-linux-musl
589590

590591
DEPENDENCIES
591-
annotate
592+
annotaterb
592593
arabic-letter-connector
593594
aws-sdk-s3
594595
aws-sdk-secretsmanager
595596
azure-storage-blob
596597
better_html
597598
bootsnap
599+
brakeman
598600
bullet
599601
cancancan
600602
capybara
@@ -610,6 +612,7 @@ DEPENDENCIES
610612
faker
611613
faraday
612614
faraday-follow_redirects
615+
foreman
613616
google-cloud-storage
614617
hexapdf
615618
image_processing

app/controllers/account_configs_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def load_account_config
3939
end
4040

4141
def account_config_params
42-
params.required(:account_config).permit!.tap do |attrs|
42+
params.required(:account_config).permit(:key, :value, { value: {} }, { value: [] }).tap do |attrs|
4343
attrs[:value] = attrs[:value] == '1' if attrs[:value].in?(%w[1 0])
4444
end
4545
end

app/controllers/notifications_settings_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def load_reminder_config
3939
end
4040

4141
def email_config_params
42-
params.require(:account_config).permit!.tap do |attrs|
42+
params.require(:account_config).permit(:key, :value, { value: {} }, { value: [] }).tap do |attrs|
4343
attrs[:key] = nil unless attrs[:key].in?([AccountConfig::BCC_EMAILS, AccountConfig::SUBMITTER_REMINDERS])
4444
end
4545
end

app/controllers/personalization_settings_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def load_and_authorize_account_config
5050
end
5151

5252
def account_config_params
53-
attrs = params.require(:account_config).permit!
53+
attrs = params.require(:account_config).permit(:key, :value, { value: {} }, { value: [] })
5454

5555
return attrs if attrs[:value].is_a?(String)
5656

app/controllers/submissions_preview_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def show
2020

2121
@submission ||= Submission.find_by!(slug: params[:slug])
2222

23-
raise ActionController::RoutingError if @submission.account.archived_at?
23+
raise ActionController::RoutingError, I18n.t('not_found') if @submission.account.archived_at?
2424

2525
if !@submission.submitters.all?(&:completed_at?) && !signature_valid &&
2626
(!current_user || !current_ability.can?(:read, @submission))

app/controllers/user_configs_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def load_user_config
2626
end
2727

2828
def user_config_params
29-
params.required(:user_config).permit!.tap do |attrs|
29+
params.required(:user_config).permit(:key, :value, { value: {} }, { value: [] }).tap do |attrs|
3030
attrs[:value] = attrs[:value] == '1' if attrs[:value].in?(%w[1 0])
3131
end
3232
end

app/controllers/users_controller.rb

+7-5
Original file line numberDiff line numberDiff line change
@@ -45,17 +45,16 @@ def update
4545
return redirect_to settings_users_path, notice: I18n.t('unable_to_update_user') if Docuseal.demo?
4646

4747
attrs = user_params.compact_blank.merge(user_params.slice(:archived_at))
48-
attrs.delete(:role) if !role_valid?(attrs[:role]) || current_user == @user
4948

5049
if params.dig(:user, :account_id).present?
51-
account = Account.accessible_by(current_ability).find(params[:user][:account_id])
50+
account = Account.accessible_by(current_ability).find(params.dig(:user, :account_id))
5251

5352
authorize!(:manage, account)
5453

5554
@user.account = account
5655
end
5756

58-
if @user.update(attrs)
57+
if @user.update(attrs.except(current_user == @user ? :role : nil))
5958
redirect_back fallback_location: settings_users_path, notice: I18n.t('user_has_been_updated')
6059
else
6160
render turbo_stream: turbo_stream.replace(:modal, template: 'users/edit'), status: :unprocessable_entity
@@ -84,8 +83,11 @@ def build_user
8483

8584
def user_params
8685
if params.key?(:user)
87-
params.require(:user).permit(:email, :first_name, :last_name, :password,
88-
:role, :archived_at, :account_id)
86+
permitted_params = %i[email first_name last_name password archived_at]
87+
88+
permitted_params << :role if role_valid?(params.dig(:user, :role))
89+
90+
params.require(:user).permit(permitted_params)
8991
else
9092
{}
9193
end

app/models/submitter.rb

+11
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ class Submitter < ApplicationRecord
5555
has_many_attached :attachments
5656
has_many_attached :preview_documents
5757
has_many :template_accesses, through: :template
58+
has_many :email_events, as: :emailable, dependent: (Docuseal.multitenant? ? nil : :destroy)
5859

5960
has_many :document_generation_events, dependent: :destroy
6061
has_many :submission_events, dependent: :destroy
@@ -63,6 +64,8 @@ class Submitter < ApplicationRecord
6364

6465
scope :completed, -> { where.not(completed_at: nil) }
6566

67+
after_destroy :anonymize_email_events, if: -> { Docuseal.multitenant? }
68+
6669
def status
6770
if declined_at?
6871
'declined'
@@ -108,4 +111,12 @@ def with_signature_fields?
108111
fields.any? { |f| f['submitter_uuid'] == uuid && signature_field_types.include?(f['type']) }
109112
end
110113
end
114+
115+
private
116+
117+
def anonymize_email_events
118+
email_events.each do |event|
119+
event.update!(email: Digest::MD5.base64digest(event.email))
120+
end
121+
end
111122
end

config/brakeman.ignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"ignored_warnings": [
3+
{
4+
"fingerprint": "25f4ce5fee1e1180fa1919dc4ee78db3ab3457a956e4679503aa745771a43836",
5+
"note": "Permitted parameters are necessary for creating submitters via API"
6+
}
7+
]
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
class CreateConsole1984Tables < ActiveRecord::Migration[7.0]
4+
def change
5+
create_table :console1984_sessions do |t|
6+
t.text :reason
7+
t.references :user, null: false, index: false
8+
t.timestamps
9+
10+
t.index :created_at
11+
t.index %i[user_id created_at]
12+
end
13+
14+
create_table :console1984_users do |t|
15+
t.string :username, null: false
16+
t.timestamps
17+
18+
t.index [:username]
19+
end
20+
21+
create_table :console1984_commands do |t|
22+
t.text :statements
23+
t.references :sensitive_access
24+
t.references :session, null: false, index: false
25+
t.timestamps
26+
27+
t.index %i[session_id created_at sensitive_access_id], name: 'on_session_and_sensitive_chronologically'
28+
end
29+
30+
create_table :console1984_sensitive_accesses do |t|
31+
t.text :justification
32+
t.references :session, null: false
33+
34+
t.timestamps
35+
end
36+
end
37+
end

db/schema.rb

+35-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.2].define(version: 2024_12_07_172237) do
13+
ActiveRecord::Schema[8.0].define(version: 2025_02_25_111255) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "plpgsql"
1616

@@ -112,6 +112,40 @@
112112
t.index ["submitter_id"], name: "index_completed_submitters_on_submitter_id", unique: true
113113
end
114114

115+
create_table "console1984_commands", force: :cascade do |t|
116+
t.text "statements"
117+
t.bigint "sensitive_access_id"
118+
t.bigint "session_id", null: false
119+
t.datetime "created_at", null: false
120+
t.datetime "updated_at", null: false
121+
t.index ["sensitive_access_id"], name: "index_console1984_commands_on_sensitive_access_id"
122+
t.index ["session_id", "created_at", "sensitive_access_id"], name: "on_session_and_sensitive_chronologically"
123+
end
124+
125+
create_table "console1984_sensitive_accesses", force: :cascade do |t|
126+
t.text "justification"
127+
t.bigint "session_id", null: false
128+
t.datetime "created_at", null: false
129+
t.datetime "updated_at", null: false
130+
t.index ["session_id"], name: "index_console1984_sensitive_accesses_on_session_id"
131+
end
132+
133+
create_table "console1984_sessions", force: :cascade do |t|
134+
t.text "reason"
135+
t.bigint "user_id", null: false
136+
t.datetime "created_at", null: false
137+
t.datetime "updated_at", null: false
138+
t.index ["created_at"], name: "index_console1984_sessions_on_created_at"
139+
t.index ["user_id", "created_at"], name: "index_console1984_sessions_on_user_id_and_created_at"
140+
end
141+
142+
create_table "console1984_users", force: :cascade do |t|
143+
t.string "username", null: false
144+
t.datetime "created_at", null: false
145+
t.datetime "updated_at", null: false
146+
t.index ["username"], name: "index_console1984_users_on_username"
147+
end
148+
115149
create_table "document_generation_events", force: :cascade do |t|
116150
t.bigint "submitter_id", null: false
117151
t.string "event_name", null: false

lib/send_webhook_request.rb

+19-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,28 @@
33
module SendWebhookRequest
44
USER_AGENT = 'DocuSeal.com Webhook'
55

6+
LOCALHOSTS = %w[0.0.0.0 127.0.0.1 localhost].freeze
7+
8+
HttpsError = Class.new(StandardError)
9+
LocalhostError = Class.new(StandardError)
10+
611
module_function
712

813
def call(webhook_url, event_type:, data:)
9-
Faraday.post(webhook_url.url) do |req|
14+
uri = begin
15+
URI(webhook_url.url)
16+
rescue URI::Error
17+
Addressable::URI.parse(webhook_url.url).normalize
18+
end
19+
20+
if Docuseal.multitenant?
21+
raise HttpsError, 'Only HTTPS is allowed.' if uri.scheme != 'https' &&
22+
!AccountConfig.exists?(key: :allow_http,
23+
account_id: webhook_url.account_id)
24+
raise LocalhostError, "Can't send to localhost." if uri.host.in?(LOCALHOSTS)
25+
end
26+
27+
Faraday.post(uri) do |req|
1028
req.headers['Content-Type'] = 'application/json'
1129
req.headers['User-Agent'] = USER_AGENT
1230
req.headers.merge!(webhook_url.secret.to_h) if webhook_url.secret.present?

0 commit comments

Comments
 (0)