Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integrations and other update #8

Merged
merged 41 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
37e55a0
add beta version integration api description
celuchmarek Apr 11, 2024
9352f5f
update integrations api and add jwts
celuchmarek Apr 12, 2024
d6d44bf
update api
celuchmarek Apr 12, 2024
ca6194f
separate jwts for device and integration in openapi
celuchmarek Apr 12, 2024
a5c63b9
add document encryption
celuchmarek Apr 13, 2024
4968ba1
add tmp debug output
celuchmarek Apr 13, 2024
1024d41
do not enforce strict base64 key for now
celuchmarek Apr 13, 2024
c269b78
temporary add single byte to encryption key
celuchmarek Apr 13, 2024
a778771
temporary add single byte to encryption key
celuchmarek Apr 13, 2024
2fa77bb
use urlsafe base64 key
celuchmarek Apr 13, 2024
f69165d
use urlsafe base64 key
celuchmarek Apr 13, 2024
84fbc43
rm key parameter from document views
celuchmarek Apr 13, 2024
33aa7f5
add pushkey to pairing qr code
celuchmarek Apr 16, 2024
faaa95e
update qr code example path
celuchmarek Apr 16, 2024
4e7f99d
update api
celuchmarek Apr 17, 2024
4cb03f8
drop requirement for payloadMimeType and guess it based on filename i…
celuchmarek Apr 17, 2024
e3e7848
add notifications
celuchmarek Apr 17, 2024
c9c15a6
add fcm callback description
celuchmarek Apr 17, 2024
96a869d
fix type in FcmNotifier class
celuchmarek Apr 17, 2024
d847bfc
updatea api, minor fixes, allow cammelCase and snake_case parameters
celuchmarek Apr 18, 2024
e085885
expect camelCase nested params for data_to_sign_structure
celuchmarek Apr 19, 2024
e7b9f4e
add good_job, token management, and automatic document deletion
celuchmarek Apr 22, 2024
52178a5
handle SIGNATURE_NOT_IN_TACT
celuchmarek Apr 22, 2024
40ca1bb
fix error handling for unknown mime type extensions
celuchmarek Apr 23, 2024
aa6b497
minor api description update
celuchmarek Apr 24, 2024
79b74d9
add well known volume
celuchmarek Apr 26, 2024
d5c9389
add last modified headers
celuchmarek Apr 27, 2024
939eb1c
add GET signature-level
celuchmarek Apr 30, 2024
3768806
add parameters endpoint
celuchmarek Apr 30, 2024
de47fa2
handle plaintext xsd ans xslt
celuchmarek May 5, 2024
86cadd8
optimize polling on GET document and uodate swagger
celuchmarek May 5, 2024
8ce6f1d
add apple app association file
celuchmarek May 6, 2024
d683e3c
add ntfy web hook integration
celuchmarek May 15, 2024
96e7664
fix push message encryption
celuchmarek May 15, 2024
edf0a0c
fix push message encryption
celuchmarek May 15, 2024
21f83c6
fix notifications finally
celuchmarek May 15, 2024
01dda83
retun empty json on sign request
celuchmarek May 15, 2024
b5f0a1e
add redirect from qr code to app page
celuchmarek May 20, 2024
dda47a1
use custom column for signing time changes
celuchmarek Jun 10, 2024
ff15c3d
save document on sign
celuchmarek Jun 10, 2024
4521533
add self
celuchmarek Jun 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add document encryption
  • Loading branch information
celuchmarek committed Apr 13, 2024
commit a5c63b9188e9e217c6e1af113d9fa2a0b8aa4366
12 changes: 8 additions & 4 deletions app/controllers/api/v1/documents_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,18 @@ def set_document
end

def set_key
@key = request.headers.to_h['HTTP_X_ENCRYPTION_KEY'] || params[:encryptionKey]
begin
@key = Base64.strict_decode64(request.headers.to_h['HTTP_X_ENCRYPTION_KEY'] || params[:encryptionKey])
rescue => e
raise AvmUnauthorizedError.new("ENCRYPTION_KEY_MALFORMED", "Encryption key Base64 decryption failed.", e.message)
end

raise AvmUnauthorizedError.new("ENCRYPTION_KEY_MISSING", "Encryption key not provided.", "Encryption key must be provided either in X-Encryption-Key header or as encryptionKey query parameter.") unless @key
# TODO
# raise AvmUnauthorizedError.new("ENCRYPTION_KEY_MALFORMED", "Encryption key invalid.", "Encryption key must be a 64 character long hexadecimal string.") unless validate_key(@key)
raise AvmUnauthorizedError.new("ENCRYPTION_KEY_MALFORMED", "Encryption key invalid.", "Encryption key must be a base64 string encoding 32 bytes long key.") unless validate_key(@key)
end

def validate_key(key)
key.length == 64 and !key[/\H/]
key.length == 32
end

def decrypt_document_content
Expand Down
7 changes: 0 additions & 7 deletions app/errors/avm_bad_encryption_key_error.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
class AvmBadEncryptionKeyError < StandardError
def initialize(body_str)
@message = body_str
end

def message
@message
end
end
18 changes: 12 additions & 6 deletions app/models/document.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
class Document < ApplicationRecord
has_one_attached :encrypted_content
attr_accessor :decrypted_content

def decrypt_content(key)
@decrypted_content = encrypted_content.download
end

def decrypted_content
Base64.strict_encode64(@decrypted_content)
decryptor = ActiveSupport::MessageEncryptor.new(key)
begin
@decrypted_content = Base64.strict_encode64(decryptor.decrypt_and_verify(encrypted_content.download).first)
rescue ActiveSupport::MessageEncryptor::InvalidMessage => e
raise AvmBadEncryptionKeyError.new
end
end

def decrypted_content_mimetype_b64
Expand All @@ -17,7 +19,11 @@ def encrypt_file(key, filename, mimetype, content)
if mimetype.include?('base64')
content = Base64.decode64(content)
end
encrypted_content.attach(filename: filename, content_type: mimetype, io: StringIO.new(content))

encryptor = ActiveSupport::MessageEncryptor.new(key)
encrypted_data = encryptor.encrypt_and_sign(StringIO.new(content))

encrypted_content.attach(filename: filename, content_type: mimetype, io: StringIO.new(encrypted_data))
end

def validate_parameters(content)
Expand Down
2 changes: 1 addition & 1 deletion app/views/api/v1/documents/show.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
json.filename @document.encrypted_content.filename
json.mimeType @document.decrypted_content_mimetype_b64
json.content @document.decrypted_content
json.content @document.decrypted_content(key)
json.signers @signers
2 changes: 1 addition & 1 deletion app/views/api/v1/documents/sign.json.jbuilder
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
json.filename @document.encrypted_content.filename
json.mimeType @document.decrypted_content_mimetype_b64
json.content @document.decrypted_content
json.content @document.decrypted_content(key)
json.signedBy @signer['signedBy']
json.issuedBy @signer['issuedBy']
10 changes: 5 additions & 5 deletions public/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -683,7 +683,7 @@ paths:
get:
tags:
- QR code
description: "Example: `https://autogram.slovensko.digital/api/v1?guid=e7e95411-66a1-d401-e063-0a64dbb6b796&key=1796de0b0309cef87d45fe5b5c0941b03ed1b98071341b251c70bf3a3f52f8d2&integration=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiI3OGQ5MWRlNy0xY2MyLTQwZTQtOWE3MS0zODU4YjRmMDMxOWQiLCJleHAiOjE3MTI5MDk3MjAsImp0aSI6IjAwZTAxN2Y1LTI4MTAtNDkyNS04ODRlLWNiN2FhZDAzZDFhNiIsImF1ZCI6ImRldmljZSJ9.7Op6W2BvbX2_mgj9dkz1IiolEsQ1Z2a0AzpS5bj4pcG3CJ4Z8j9W3RQE95wrAj3t6nmd9JaGZSlCJNSV_myyLQ`"
description: "Example: `https://autogram.slovensko.digital/api/v1?guid=e7e95411-66a1-d401-e063-0a64dbb6b796&key=EeESAfZQh9OTf5qZhHZtgaDJpYtxZD6TIOQJzRgRFgQ%3D&integration=eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiI3OGQ5MWRlNy0xY2MyLTQwZTQtOWE3MS0zODU4YjRmMDMxOWQiLCJleHAiOjE3MTI5MDk3MjAsImp0aSI6IjAwZTAxN2Y1LTI4MTAtNDkyNS04ODRlLWNiN2FhZDAzZDFhNiIsImF1ZCI6ImRldmljZSJ9.7Op6W2BvbX2_mgj9dkz1IiolEsQ1Z2a0AzpS5bj4pcG3CJ4Z8j9W3RQE95wrAj3t6nmd9JaGZSlCJNSV_myyLQ`"
parameters:
- name: guid
in: query
Expand All @@ -693,7 +693,7 @@ paths:
- name: key
in: query
description: Encryption key for the document
example: 1796de0b0309cef87d45fe5b5c0941b03ed1b98071341b251c70bf3a3f52f8d2
example: EeESAfZQh9OTf5qZhHZtgaDJpYtxZD6TIOQJzRgRFgQ=
required: true
- name: integration
in: query
Expand All @@ -715,7 +715,7 @@ components:
document_encryption_key:
type: string
description: AES256 encryption key in hexadecimal form (64 characters) that is used to encrypt and decrypt signing doucment.
example: 5e0523acd9ec45f7d08295a029cc296f5cb5e713588c2e2b6fd95ed4a8a4b404
example: EeESAfZQh9OTf5qZhHZtgaDJpYtxZD6TIOQJzRgRFgQ=
required:
- document_guid
- document_encryption_key
Expand Down Expand Up @@ -1464,13 +1464,13 @@ components:
type: apiKey
in: header
name: X-Encryption-Key
description: AES256 encryption key in hexadecimal form (64 characters) that is used to encrypt and decrypt signing doucment.
description: AES256 encryption key in Base64 form (44 base64 characters == 32 bytes) that is used to encrypt and decrypt signing doucment.

Parameter:
type: apiKey
in: query
name: encryptionKey
description: AES256 encryption key in hexadecimal form (64 characters) that is used to encrypt and decrypt signing doucment.
description: AES256 encryption key in Base64 form (44 base64 characters == 32 bytes) that is used to encrypt and decrypt signing doucment.

Device JWT:
description: |
Expand Down