├── log
└── .keep
├── tmp
└── .keep
├── vendor
└── .keep
├── lib
├── tasks
│ ├── .keep
│ └── eform.rake
├── parameters.rb
├── upvs
│ ├── logback.xml
│ ├── .gitignore
│ ├── cfg
│ │ ├── logback.xml
│ │ ├── ws-techcert.xml
│ │ ├── ws-onbehalf.xml
│ │ ├── context.xml
│ │ ├── ws-onbehalf-id.xml
│ │ └── eks
│ │ │ └── EKSService_1.xsd
│ └── src
│ │ └── digital
│ │ └── slovensko
│ │ └── upvs
│ │ ├── internals
│ │ ├── StringToElementConverter.java
│ │ ├── PasswordCallbackHandler.java
│ │ └── LoggerPropertyDefiner.java
│ │ └── UpvsProxy.java
├── upvs.rb
└── keystore.rb
├── public
├── robots.txt
└── install.md
├── security
├── .keep
├── sso
│ └── .keep
├── sts
│ └── .keep
└── tls
│ └── .keep
├── .java-version
├── app
├── models
│ ├── concerns
│ │ └── .keep
│ ├── cep.rb
│ ├── iam.rb
│ ├── edesk.rb
│ ├── eform.rb
│ ├── sktalk.rb
│ ├── administration.rb
│ ├── heartbeat.rb
│ ├── application_record.rb
│ ├── upvs.rb
│ ├── form_template_related_document.rb
│ ├── form_template.rb
│ └── message.rb
├── services
│ ├── concerns
│ │ └── .keep
│ ├── upvs_proxy.rb
│ ├── cep_signer.rb
│ ├── eform_service.rb
│ ├── sktalk_receiver.rb
│ └── environment.rb
├── controllers
│ ├── concerns
│ │ ├── .keep
│ │ ├── pagination.rb
│ │ ├── sktalk_receiving.rb
│ │ └── edesk_rescuable.rb
│ ├── application_controller.rb
│ ├── errors_controller.rb
│ ├── edesk
│ │ ├── folders_controller.rb
│ │ └── messages_controller.rb
│ ├── administration
│ │ ├── eform_controller.rb
│ │ └── certificates_controller.rb
│ ├── cep_controller.rb
│ ├── iam
│ │ └── identities_controller.rb
│ ├── sktalk_controller.rb
│ └── eform_controller.rb
├── jobs
│ ├── application_job.rb
│ ├── download_form_templates_job.rb
│ └── download_form_template_job.rb
├── helpers
│ ├── sktalk_messages.rb
│ ├── integers.rb
│ ├── callback_helper.rb
│ └── upvs_objects.rb
└── views
│ ├── iam
│ ├── _corporate_body_name.json.jbuilder
│ ├── identities
│ │ ├── show.json.jbuilder
│ │ ├── _corporate_body_name.json.jbuilder
│ │ ├── search.json.jbuilder
│ │ ├── _enumeration.json.jbuilder
│ │ ├── _affix.json.jbuilder
│ │ ├── _natural_person_name.json.jbuilder
│ │ ├── _corporate_body.json.jbuilder
│ │ └── _natural_person.json.jbuilder
│ ├── _enumeration.json.jbuilder
│ ├── _affix.json.jbuilder
│ ├── _natural_person_name.json.jbuilder
│ ├── _corporate_body.json.jbuilder
│ └── _natural_person.json.jbuilder
│ ├── edesk
│ ├── folders
│ │ └── index.json.jbuilder
│ └── messages
│ │ ├── index.json.jbuilder
│ │ ├── search.json.jbuilder
│ │ └── show.json.jbuilder
│ └── cep
│ └── signatures_info.json.jbuilder
├── .rspec
├── .ruby-version
├── CHECKS
├── spec
├── support
│ ├── rack_environment.rb
│ ├── active_job.rb
│ ├── factory_bot.rb
│ ├── json_responses.rb
│ ├── time_helpers.rb
│ ├── database_cleaner.rb
│ ├── java_object_proxies.rb
│ ├── request_errors.rb
│ ├── fixture_names.rb
│ ├── redis_cache_stores.rb
│ ├── upvs_support.rb
│ ├── eform_matchers.rb
│ ├── sktalk_matchers.rb
│ ├── upvs_object_matchers.rb
│ └── authenticity_tokens.rb
├── fixtures
│ ├── eks
│ │ ├── move_message_response.xml
│ │ ├── delete_message_response.xml
│ │ ├── delete_message
│ │ │ ├── no_message_response.xml
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── box_not_exist_fault.xml
│ │ │ └── message_permission_denied_fault.xml
│ │ ├── confirm_notification_report_response.xml
│ │ ├── general_fault.xml
│ │ ├── get_folders
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── box_not_exist_fault.xml
│ │ │ └── no_folders_response.xml
│ │ ├── get_message
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── box_not_exist_fault.xml
│ │ │ ├── no_message_response.xml
│ │ │ └── message_permission_denied_fault.xml
│ │ ├── get_messages
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── box_not_exist_fault.xml
│ │ │ ├── folder_permission_denied_fault.xml
│ │ │ └── no_messages_response.xml
│ │ ├── move_message
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── box_not_exist_fault.xml
│ │ │ ├── message_not_exist_fault.xml
│ │ │ ├── folder_not_exist_fault.xml
│ │ │ ├── message_permission_denied_fault.xml
│ │ │ └── folder_permission_denied_fault.xml
│ │ ├── authorize_message
│ │ │ ├── box_inactive_fault.xml
│ │ │ ├── no_message_fault.xml
│ │ │ ├── already_authorized_fault.xml
│ │ │ ├── message_permission_denied_fault.xml
│ │ │ └── non_delivery_notification_fault.xml
│ │ └── get_folders_response.xml
│ ├── sktalk
│ │ ├── forms
│ │ │ ├── general_agenda.asice
│ │ │ ├── general_agenda.xml
│ │ │ ├── delivery_report_authorization.xml
│ │ │ └── delivery_report_notification.xml
│ │ ├── egov_application_empty_general_agenda.xml
│ │ ├── egov_application_general_agenda.xml
│ │ ├── edesk_save_application_to_drafts_general_agenda.xml
│ │ ├── edesk_save_application_to_outbox_general_agenda.xml
│ │ └── ed_delivery_notification.xml
│ ├── iam
│ │ ├── get_identity
│ │ │ ├── undefined_fault.xml
│ │ │ ├── no_indentifier_fault.xml
│ │ │ └── invalid_identifier_fault.xml
│ │ ├── get_edesk_info
│ │ │ ├── undefined_fault.xml
│ │ │ ├── invalid_query_fault.xml
│ │ │ └── no_query_fault.xml
│ │ └── get_identity_response.xml
│ ├── cep
│ │ └── general_agenda.xml
│ ├── api
│ │ └── edesk
│ │ │ └── folders.json
│ ├── ez
│ │ ├── eform
│ │ │ ├── find_form_templates_request.xml
│ │ │ ├── get_form_template_status
│ │ │ │ ├── input_parameter_type_mismatch_request.xml
│ │ │ │ ├── unset_object_reference_request.xml
│ │ │ │ ├── no_form_template_request.xml
│ │ │ │ └── invalid_form_template_request.xml
│ │ │ ├── get_form_template_status_response.xml
│ │ │ ├── get_form_template_status_request.xml
│ │ │ ├── get_related_document_by_type_request.xml
│ │ │ └── get_related_document_by_type_response.xml
│ │ └── cep
│ │ │ └── zisti_typ_a_formu_podpisu
│ │ │ ├── response_unsigned.xml
│ │ │ └── response_signed.xml
│ └── oam
│ │ ├── slo_response_different_user.xml
│ │ └── slo_request.query
├── helpers
│ └── upvs_objects_spec.rb
├── services
│ ├── upvs_proxy_spec.rb
│ ├── environment_spec.rb
│ └── upvs_environment_spec.rb
├── jobs
│ ├── download_form_templates_job_spec.rb
│ └── download_form_template_job_spec.rb
├── factories
│ └── form_templates.rb
└── rails_helper.rb
├── .dockerignore
├── bin
├── rake
├── bundle
└── rails
├── .gitignore
├── .env.test
├── app.json
├── Procfile
├── chart
├── test
│ ├── testdata
│ │ ├── service-definition.yaml
│ │ ├── custom-cilium-policy.yaml
│ │ ├── custom-policy.yaml
│ │ ├── full-spec-policy.yaml
│ │ ├── modsecurity-ingress.yaml
│ │ └── volume-mounts.yaml
│ ├── go.mod
│ └── templates
│ │ ├── db_migrate_hook_test.go
│ │ └── db_initialize_job_test.go
├── Chart.yaml
├── templates
│ ├── network-policy.yaml
│ ├── service-account.yaml
│ ├── NOTES.txt
│ ├── postgres-instance.yaml
│ ├── cilium-network-policy.yaml
│ ├── pdb.yaml
│ ├── pvc.yaml
│ ├── hpa.yaml
│ ├── service.yaml
│ ├── db-initialize-job.yaml
│ ├── db-migrate-hook.yaml
│ └── _helpers.tpl
├── LICENSE
└── CONTRIBUTING.md
├── config
├── boot.rb
├── environment.rb
├── initializers
│ ├── filter_parameter_logging.rb
│ ├── mime_types.rb
│ ├── application_controller_renderer.rb
│ ├── backtrace_silencers.rb
│ ├── json_encoding.rb
│ ├── wrap_parameters.rb
│ ├── inflections.rb
│ └── upvs_authentication.rb
├── clock.rb
├── database.yml
├── locales
│ └── en.yml
├── puma.rb
├── environments
│ ├── test.rb
│ ├── development.rb
│ ├── production.rb
│ └── staging.rb
├── routes.rb
└── application.rb
├── config.ru
├── doc
└── templates
│ ├── .env
│ ├── .env.with_obo
│ ├── .env.with_upvs_sso
│ ├── docker-compose.yml
│ ├── docker-compose.with_eform_sync.yml
│ └── podaas_fix.metadata.xml
├── .env.test.with_upvs_sso
├── Rakefile
├── db
├── migrate
│ ├── 20181219193446_create_heartbeats.rb
│ ├── 20181210113900_create_form_templates.rb
│ ├── 20181210164801_create_form_template_related_documents.rb
│ └── 20181211152434_create_delayed_jobs.rb
├── seeds.rb
└── schema.rb
├── Dockerfile
├── Gemfile
├── README.md
├── .gitlab-ci.yml
├── .github
└── workflows
│ └── slovensko_digital_ci.yml
└── .gitlab
└── auto-deploy-values.yaml
/log/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tmp/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/vendor/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/security/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/security/sso/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/security/sts/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/security/tls/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.java-version:
--------------------------------------------------------------------------------
1 | 17
2 |
--------------------------------------------------------------------------------
/app/models/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/services/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --require spec_helper
2 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | jruby-9.3.15.0
2 |
--------------------------------------------------------------------------------
/app/controllers/concerns/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/install.md:
--------------------------------------------------------------------------------
1 | ../INSTALL.md
--------------------------------------------------------------------------------
/app/models/cep.rb:
--------------------------------------------------------------------------------
1 | module Cep
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/iam.rb:
--------------------------------------------------------------------------------
1 | module Iam
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/edesk.rb:
--------------------------------------------------------------------------------
1 | module Edesk
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/eform.rb:
--------------------------------------------------------------------------------
1 | module Eform
2 | end
3 |
--------------------------------------------------------------------------------
/app/models/sktalk.rb:
--------------------------------------------------------------------------------
1 | module Sktalk
2 | end
3 |
--------------------------------------------------------------------------------
/CHECKS:
--------------------------------------------------------------------------------
1 | TIMEOUT=120
2 | WAIT=60
3 |
4 | /health
5 |
--------------------------------------------------------------------------------
/app/models/administration.rb:
--------------------------------------------------------------------------------
1 | module Administration
2 | end
3 |
--------------------------------------------------------------------------------
/spec/support/rack_environment.rb:
--------------------------------------------------------------------------------
1 | ENV['RACK_ENV'] = 'test'
2 |
--------------------------------------------------------------------------------
/spec/support/active_job.rb:
--------------------------------------------------------------------------------
1 | ActiveJob::Base.queue_adapter = :test
2 |
--------------------------------------------------------------------------------
/app/models/heartbeat.rb:
--------------------------------------------------------------------------------
1 | class Heartbeat < ApplicationRecord
2 | end
3 |
--------------------------------------------------------------------------------
/app/jobs/application_job.rb:
--------------------------------------------------------------------------------
1 | class ApplicationJob < ActiveJob::Base
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/sktalk_messages.rb:
--------------------------------------------------------------------------------
1 | SktalkMessages = digital.slovensko.upvs.SktalkMessages
2 |
--------------------------------------------------------------------------------
/app/views/iam/_corporate_body_name.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.name corporate_body.corporate_body_name
2 |
--------------------------------------------------------------------------------
/app/views/iam/identities/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.partial! 'iam/identity', identity: @identity
2 |
--------------------------------------------------------------------------------
/app/views/iam/identities/_corporate_body_name.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.name corporate_body.corporate_body_name
2 |
--------------------------------------------------------------------------------
/app/views/iam/identities/search.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @identities, partial: 'iam/identity', as: :identity
2 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | .git
2 |
3 | .gitlab-ci.yml
4 | .gitlab
5 |
6 | /log/*
7 | /tmp/*
8 |
9 | /security/*
10 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | require_relative '../config/boot'
3 | require 'rake'
4 | Rake.application.run
5 |
--------------------------------------------------------------------------------
/spec/support/factory_bot.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.include FactoryBot::Syntax::Methods
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | self.abstract_class = true
3 | end
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .bundle
3 | .opensource
4 |
5 | *.local
6 |
7 | /log/*
8 | /tmp/*
9 |
10 | /security/*
11 |
--------------------------------------------------------------------------------
/lib/parameters.rb:
--------------------------------------------------------------------------------
1 | class ActionController::Parameters
2 | def to_options
3 | to_h.deep_symbolize_keys
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | RAILS_ENV=test
2 |
3 | UPVS_ENV=fix
4 |
5 | # STS examples: rspec -t sts
6 |
7 | STS_CB_SUBJECT=
8 | STS_PA_SUBJECT=
9 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "scripts": {
3 | "dokku": {
4 | "postdeploy": "bundle exec rails db:migrate"
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/lib/upvs/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | clock: bundle exec clockwork config/clock.rb
2 | web: bundle exec puma -C config/puma.rb
3 | worker: bundle exec rake jobs:work
4 |
--------------------------------------------------------------------------------
/lib/tasks/eform.rake:
--------------------------------------------------------------------------------
1 | namespace :eform do
2 | task sync: :environment do
3 | DownloadFormTemplatesJob.perform_later
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/lib/upvs/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .metadata
3 | .project
4 | .settings
5 |
6 | *.local
7 |
8 | /bin/*
9 | /log/*
10 | /tmp/*
11 |
--------------------------------------------------------------------------------
/bin/bundle:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3 | load Gem.bin_path('bundler', 'bundle')
4 |
--------------------------------------------------------------------------------
/app/models/upvs.rb:
--------------------------------------------------------------------------------
1 | module Upvs
2 | def self.env
3 | @env ||= ActiveSupport::StringInquirer.new(ENV.fetch('UPVS_ENV', 'dev'))
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/support/json_responses.rb:
--------------------------------------------------------------------------------
1 | class ActionDispatch::TestResponse
2 | def object
3 | JSON.parse(body, symbolize_names: true)
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/chart/test/testdata/service-definition.yaml:
--------------------------------------------------------------------------------
1 | service:
2 | extraPorts:
3 | - port: 443
4 | targetPort: 443
5 | protocol: TCP
6 | name: port-443
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
2 |
3 | require 'bundler/setup' # Set up gems listed in the Gemfile.
4 |
--------------------------------------------------------------------------------
/app/views/iam/_enumeration.json.jbuilder:
--------------------------------------------------------------------------------
1 | return json.nil! unless value
2 |
3 | json.id value.id
4 | json.name value.title_sk
5 | json.description value.desc
6 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative 'config/environment'
4 |
5 | run Rails.application
6 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | APP_PATH = File.expand_path('../config/application', __dir__)
3 | require_relative '../config/boot'
4 | require 'rails/commands'
5 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/forms/general_agenda.asice:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/slovensko-digital/slovensko-sk-api/HEAD/spec/fixtures/sktalk/forms/general_agenda.asice
--------------------------------------------------------------------------------
/app/views/iam/identities/_enumeration.json.jbuilder:
--------------------------------------------------------------------------------
1 | return json.nil! unless value
2 |
3 | json.id value.id
4 | json.name value.title_sk
5 | json.description value.desc
6 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative 'application'
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/spec/support/time_helpers.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.include ActiveSupport::Testing::TimeHelpers
3 |
4 | config.after(:example) { travel_back }
5 | end
6 |
--------------------------------------------------------------------------------
/lib/upvs.rb:
--------------------------------------------------------------------------------
1 | root = File.expand_path('upvs', __dir__)
2 |
3 | Dir[File.join(root, 'bin', 'lib', '*.jar')].each { |jar| require jar }
4 |
5 | require File.join(root, 'bin', 'upvs-0.0.0.jar')
6 |
--------------------------------------------------------------------------------
/doc/templates/.env:
--------------------------------------------------------------------------------
1 | # See installation guide for a complete list of environment variables
2 |
3 | RAILS_ENV=production
4 | SECRET_KEY_BASE=
5 |
6 | UPVS_ENV=fix
7 | UPVS_KS_SALT=
8 | UPVS_PK_SALT=
9 |
--------------------------------------------------------------------------------
/app/views/iam/_affix.json.jbuilder:
--------------------------------------------------------------------------------
1 | return json.nil! unless affix
2 |
3 | json.type affix.type.underscore.remove('_title').tap { |t| t.replace('military') if t == 'form_of_address' }
4 | json.value affix.value
5 |
--------------------------------------------------------------------------------
/chart/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | description: GitLab's Auto-deploy Helm Chart
3 | name: auto-deploy-app
4 | version: 2.26.0
5 | icon: https://gitlab.com/gitlab-com/gitlab-artwork/raw/master/logo/logo-square.png
6 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | # TODO drop this and rename ApiController to ApplicationController
2 |
3 | class ApplicationController < ActionController::Base
4 | protect_from_forgery with: :exception
5 | end
6 |
--------------------------------------------------------------------------------
/app/views/iam/identities/_affix.json.jbuilder:
--------------------------------------------------------------------------------
1 | return json.nil! unless affix
2 |
3 | json.type affix.type.underscore.remove('_title').tap { |t| t.replace('military') if t == 'form_of_address' }
4 | json.value affix.value
5 |
--------------------------------------------------------------------------------
/.env.test.with_upvs_sso:
--------------------------------------------------------------------------------
1 | RAILS_ENV=test
2 |
3 | UPVS_ENV=fix
4 |
5 | SSO_SP_SUBJECT=
6 | SSO_PROXY_SUBJECT=
7 |
8 | LOGIN_CALLBACK_URL=https://example.com/login-callback
9 | LOGOUT_CALLBACK_URL=https://example.com/logout-callback
10 |
--------------------------------------------------------------------------------
/app/views/edesk/folders/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @folders do |folder|
2 | json.id folder.id_folder
3 | json.parent_id folder.id_folder_parent.value
4 | json.name folder.name.value
5 | json.system folder.is_system_folder
6 | end
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/delete_message_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
--------------------------------------------------------------------------------
/doc/templates/.env.with_obo:
--------------------------------------------------------------------------------
1 | # See installation guide for a complete list of environment variables
2 |
3 | RAILS_ENV=production
4 | SECRET_KEY_BASE=
5 |
6 | UPVS_ENV=fix
7 | UPVS_KS_SALT=
8 | UPVS_PK_SALT=
9 |
10 | SSO_PROXY_SUBJECT=
11 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative 'config/application'
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/app/controllers/errors_controller.rb:
--------------------------------------------------------------------------------
1 | class ErrorsController < ApiController
2 | skip_before_action(:verify_request_body)
3 | skip_before_action(:verify_format)
4 |
5 | def internal_server_error
6 | render_internal_server_error
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | # Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/delete_message/no_message_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | true
4 |
5 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | Mime::Type.register 'application/health+json', :health
5 | Mime::Type.register 'application/samlassertion+xml', :saml
6 |
--------------------------------------------------------------------------------
/app/controllers/edesk/folders_controller.rb:
--------------------------------------------------------------------------------
1 | class Edesk::FoldersController < ApiController
2 | include EdeskRescuable
3 |
4 | before_action { authenticate(allow_sub: true) }
5 |
6 | def index
7 | @folders = edesk_service(upvs_identity).folders
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20181219193446_create_heartbeats.rb:
--------------------------------------------------------------------------------
1 | class CreateHeartbeats < ActiveRecord::Migration[5.2]
2 | def change
3 | create_table :heartbeats do |t|
4 | t.string :name, index: { unique: true }, null: false
5 |
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/controllers/administration/eform_controller.rb:
--------------------------------------------------------------------------------
1 | class Administration::EformController < ApiController
2 | before_action { authenticate(allow_plain: true) }
3 |
4 | def synchronize
5 | DownloadFormTemplatesJob.perform_later
6 |
7 | head :no_content
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/chart/test/testdata/custom-cilium-policy.yaml:
--------------------------------------------------------------------------------
1 | ciliumNetworkPolicy:
2 | enabled: true
3 | alerts:
4 | enabled: true
5 | spec:
6 | endpointSelector: {}
7 | ingress:
8 | - fromEndpoints:
9 | - matchLabels:
10 | app.gitlab.com/managed_by: gitlab
11 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_identity/undefined_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 00000000
4 | Nedefinovaná chyba!
5 |
6 |
--------------------------------------------------------------------------------
/app/helpers/integers.rb:
--------------------------------------------------------------------------------
1 | module Integers
2 | def self.parse_positive(s)
3 | return s if s.is_a?(Integer) && s > 0
4 | return s.to_i if match_positive?(s)
5 | raise ArgumentError
6 | end
7 |
8 | def self.match_positive?(s)
9 | s =~ /\A[1-9]\d*\z/
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/config/initializers/application_controller_renderer.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # ActiveSupport::Reloader.to_prepare do
4 | # ApplicationController.renderer.defaults.merge!(
5 | # http_host: 'example.org',
6 | # https: false
7 | # )
8 | # end
9 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_edesk_info/undefined_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 00000000
4 | Nedefinovaná chyba!
5 |
6 |
--------------------------------------------------------------------------------
/app/controllers/cep_controller.rb:
--------------------------------------------------------------------------------
1 | class CepController < ApiController
2 | before_action { authenticate(allow_sub: true) }
3 |
4 | def signatures_info
5 | content = params.require(:content)
6 |
7 | @response = cep_signer(upvs_identity).signatures_info(content)
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/fixtures/cep/general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Všeobecný predmet
4 | Všeobecný text
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_identity/no_indentifier_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 41227
4 | Nesprávne vstupné parametre!
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/confirm_notification_report_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4903713857
4 |
5 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_identity/invalid_identifier_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 00074421
4 | Nastala chyba: IDENTITY_ID_FAULT
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/forms/general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Všeobecný predmet
4 | Všeobecný text
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/general_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | General
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/chart/test/testdata/custom-policy.yaml:
--------------------------------------------------------------------------------
1 | networkPolicy:
2 | enabled: true
3 | spec:
4 | podSelector:
5 | matchLabels:
6 | foo: bar
7 | ingress:
8 | - from:
9 | - podSelector:
10 | matchLabels: {}
11 | - namespaceSelector:
12 | matchLabels:
13 | name: foo
14 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_edesk_info/invalid_query_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 01000999
4 | Chybný vstup, kombinácia PhysicalPerson a CorporateBody
5 |
6 |
--------------------------------------------------------------------------------
/chart/templates/network-policy.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.networkPolicy.enabled -}}
2 | apiVersion: networking.k8s.io/v1
3 | kind: NetworkPolicy
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | labels:
7 | {{ include "sharedlabels" . | indent 4}}
8 | spec:
9 | {{ toYaml .Values.networkPolicy.spec | indent 2 }}
10 | {{- end -}}
11 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_folders/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_folders/box_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskNotExist
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_message/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_message/box_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskNotExist
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_messages/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_messages/box_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskNotExist
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/box_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskNotExist
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_edesk_info/no_query_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 01000999
4 | Vstupné dáta potrebné na vyhľadanie používateľov nie sú vyplnené!
5 |
6 |
--------------------------------------------------------------------------------
/doc/templates/.env.with_upvs_sso:
--------------------------------------------------------------------------------
1 | # See installation guide for a complete list of environment variables
2 |
3 | RAILS_ENV=production
4 | SECRET_KEY_BASE=
5 |
6 | UPVS_ENV=fix
7 | UPVS_KS_SALT=
8 | UPVS_PK_SALT=
9 |
10 | SSO_SP_SUBJECT=
11 | SSO_PROXY_SUBJECT=
12 |
13 | LOGIN_CALLBACK_URL=localhost
14 | LOGOUT_CALLBACK_URL=localhost
15 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/authorize_message/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/delete_message/box_inactive_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskInactive
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/delete_message/box_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskNotExist
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_message/no_message_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/message_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MessageNotExist
4 |
5 | Správa neexistuje.
6 |
7 |
--------------------------------------------------------------------------------
/app/models/form_template_related_document.rb:
--------------------------------------------------------------------------------
1 | # TODO this is too long, rename just to RelatedDocument as is sk.gov.schemas.servicebusserviceprovider.ness.eformprovider._1.RelatedDocument
2 | class FormTemplateRelatedDocument < ApplicationRecord
3 | belongs_to :form_template
4 |
5 | # TODO rename document_type to type
6 | # TODO rename data to content
7 | end
8 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/folder_not_exist_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | FolderNotExist
4 |
5 | Cieľový priečinok neexistuje.
6 |
7 |
--------------------------------------------------------------------------------
/app/views/edesk/messages/index.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @messages do |message|
2 | json.id message.id_message
3 | json.class message.clazz.value
4 | json.message_id message.message_id.value
5 | json.correlation_id message.correlation_id.value
6 | json.subject message.title.value
7 | json.delivered_at EdeskMessageParser.parse_delivery_time(message.date_delivery)
8 | end
9 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/authorize_message/no_message_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | IncorrectConfirmRequest
4 |
5 | Správa 5603713960 neexistuje.
6 |
7 |
--------------------------------------------------------------------------------
/app/views/edesk/messages/search.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.array! @messages do |message|
2 | json.id message.id_message
3 | json.class message.clazz.value
4 | json.message_id message.message_id.value
5 | json.correlation_id message.correlation_id.value
6 | json.subject message.title.value
7 | json.delivered_at EdeskMessageParser.parse_delivery_time(message.date_delivery)
8 | end
9 |
--------------------------------------------------------------------------------
/chart/templates/service-account.yaml:
--------------------------------------------------------------------------------
1 | {{- with .Values.serviceAccount -}}
2 | {{- if .createNew }}
3 | apiVersion: v1
4 | kind: ServiceAccount
5 | metadata:
6 | name: {{ .name | quote }}
7 | labels:
8 | {{ include "sharedlabels" $ | indent 4 }}
9 | {{- if .annotations }}
10 | annotations:
11 | {{ toYaml .annotations | indent 4 }}
12 | {{- end }}
13 | {{- end }}
14 | {{- end -}}
15 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_message/message_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskPermissionDenied
4 |
5 | Užívateľ nemá právo čítať danú správu.
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_messages/folder_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskPermissionDenied
4 |
5 | Užívateľ nemá právo čítať daný priečinok.
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/message_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskPermissionDenied
4 |
5 | Užívateľ nemá právo presunúť správu.
6 |
7 |
--------------------------------------------------------------------------------
/app/helpers/callback_helper.rb:
--------------------------------------------------------------------------------
1 | module CallbackHelper
2 | def callback_match?(template, callback = params[:callback])
3 | uri_scheme_and_authority(callback) == uri_scheme_and_authority(template) && callback.start_with?(template)
4 | end
5 |
6 | private
7 |
8 | def uri_scheme_and_authority(uri)
9 | URI(uri).tap { |u| u.path = u.query = u.fragment = nil }
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/delete_message/message_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskPermissionDenied
4 |
5 | Užívateľ nemá právo zmazať danú správu.
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/move_message/folder_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EDeskPermissionDenied
4 |
5 | Užívateľ nemá právo čítať cieľový priečinok.
6 |
7 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
7 | # Character.create(name: 'Luke', movie: movies.first)
8 |
--------------------------------------------------------------------------------
/spec/support/database_cleaner.rb:
--------------------------------------------------------------------------------
1 | require 'database_cleaner/active_record'
2 | require 'database_cleaner/redis'
3 |
4 | RSpec.configure do |config|
5 | config.before(:suite) do
6 | DatabaseCleaner.strategy = :deletion
7 | DatabaseCleaner.clean_with(:deletion)
8 | end
9 |
10 | config.around(:example) do |example|
11 | DatabaseCleaner.cleaning { example.run }
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/chart/test/testdata/full-spec-policy.yaml:
--------------------------------------------------------------------------------
1 | networkPolicy:
2 | enabled: true
3 | spec:
4 | podSelector:
5 | matchLabels: {}
6 | policyTypes:
7 | - Ingress
8 | - Egress
9 | ingress:
10 | - from:
11 | - podSelector:
12 | matchLabels: {}
13 | egress:
14 | - to:
15 | - namespaceSelector:
16 | matchLabels:
17 | name: gitlab-managed-apps
18 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/authorize_message/already_authorized_fault.xml:
--------------------------------------------------------------------------------
1 |
2 | MessageNotDeliverable
3 |
4 | Správu ste už prevzali cez elektronickú schránku alebo integrovaný systém, a preto ju nemôžete prevziať opakovane.
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/authorize_message/message_permission_denied_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | IncorrectConfirmRequest
4 |
5 | Nie ste adresátom správy a preto ju nemáte oprávnenie prevziať.
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_folders/no_folders_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_messages/no_messages_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/chart/templates/NOTES.txt:
--------------------------------------------------------------------------------
1 | {{- if and .Values.ingress.enabled .Values.service.enabled -}}
2 | Application should be accessible at
3 |
4 | {{ .Values.service.url }}
5 | {{- else -}}
6 | Application was deployed reusing the service at
7 |
8 | {{ .Values.service.url }}
9 |
10 | It will share a load balancer with the previous release (or be unavailable if
11 | no service or ingress was previously deployed).
12 | {{- end -}}
13 |
--------------------------------------------------------------------------------
/chart/test/testdata/modsecurity-ingress.yaml:
--------------------------------------------------------------------------------
1 | ingress:
2 | modSecurity:
3 | enabled: true
4 | secRules:
5 | - variable: "REQUEST_HEADERS:User-Agent"
6 | operator: "scanner"
7 | action: "log,deny,id:107,status:403,msg:'Scanner Identified'"
8 | - variable: "REQUEST_HEADERS:Content-Type"
9 | operator: "text/plain"
10 | action: "log,deny,id:'20010',status:403,msg:'Text plain not allowed'"
--------------------------------------------------------------------------------
/spec/support/java_object_proxies.rb:
--------------------------------------------------------------------------------
1 | # cache Java object proxy to support user-defined instance variables or singleton
2 | # object on arbitrary Java object, see https://github.com/jruby/jruby/wiki/Persistence
3 |
4 | module JavaObjectProxies
5 | def cache_java_object_proxy!(object)
6 | object.class.__persistent__ = true
7 | end
8 | end
9 |
10 | RSpec.configure do |config|
11 | config.include JavaObjectProxies
12 | end
13 |
--------------------------------------------------------------------------------
/config/clock.rb:
--------------------------------------------------------------------------------
1 | require_relative 'environment'
2 |
3 | Rails.application.load_tasks
4 |
5 | module Clockwork
6 | configure do |config|
7 | config[:thread] = true
8 | config[:tz] = Rails.application.config.time_zone
9 | end
10 |
11 | handler do |name|
12 | Rake::Task[name].reenable
13 | Rake::Task[name].invoke
14 | end
15 |
16 | every(1.day, 'eform:sync', at: '5:00') if ENV.key?('EFORM_SYNC_SUBJECT')
17 | end
18 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/authorize_message/non_delivery_notification_fault.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | IncorrectConfirmRequest
4 |
5 | Správa 4898662475 nemá Class ED_DELIVERY_NOTIFICATION, a teda nie je notifikačná doručenka.
6 |
7 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/forms/delivery_report_authorization.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | e411c801-8290-47c2-8250-801f3cf56e58
4 | ico://sk/6501012225
5 | ico://sk/6501012225
6 | 2016-10-18T16:35:44+02:00
7 |
8 |
--------------------------------------------------------------------------------
/chart/test/go.mod:
--------------------------------------------------------------------------------
1 | module gitlab.com/gitlab-org/charts/auto-deploy-app/test
2 |
3 | go 1.15
4 |
5 | require (
6 | github.com/cilium/cilium v1.8.1
7 | github.com/gruntwork-io/terratest v0.32.1
8 | github.com/stretchr/testify v1.6.1
9 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
10 | k8s.io/api v0.19.7
11 | k8s.io/apimachinery v0.19.7
12 | )
13 |
14 | replace github.com/optiopay/kafka => github.com/cilium/kafka v0.0.0-20180809090225-01ce283b732b
15 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/app/views/cep/signatures_info.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.is_signed @response.kod == 0
2 | json.description @response.popis.value
3 |
4 | if @response.kod == 0
5 | json.mime_type @response.mime_type.value
6 |
7 | json.signatures @response.podpisy.value.ztfp2_podpis.to_a.each do |signature|
8 | json.type signature.typ_podpisu.value
9 | json.format signature.format_podpisu.value
10 | json.with_timestamp signature.is_obsahuje_casovu_peciatku
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/chart/test/testdata/volume-mounts.yaml:
--------------------------------------------------------------------------------
1 | persistence:
2 | enabled: true
3 | volumes:
4 | - name: log-dir
5 | mount:
6 | path: "/log"
7 | claim:
8 | accessMode: ReadWriteOnce
9 | size: 20Gi
10 | storageClass: ""
11 | - name: config
12 | mount:
13 | path: "/app-config"
14 | subPath: "config.txt"
15 | claim:
16 | accessMode: ReadWriteOnce
17 | size: 8Gi
18 | storageClass: ""
--------------------------------------------------------------------------------
/config/initializers/json_encoding.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Disable HTML entities escaping in encoded values.
4 | ActiveSupport::JSON::Encoding.escape_html_entities_in_json = false
5 |
6 | # Use ISO 8601 format for encoded date and time values.
7 | ActiveSupport::JSON::Encoding.use_standard_json_time_format = true
8 |
9 | # Use millisecond precision of encoded time values.
10 | ActiveSupport::JSON::Encoding.time_precision = 3
11 |
--------------------------------------------------------------------------------
/chart/templates/postgres-instance.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.postgresql.managed -}}
2 | apiVersion: database.crossplane.io/v1alpha1
3 | kind: PostgreSQLInstance
4 | metadata:
5 | name: {{ template "appname" . }}
6 | spec:
7 | engineVersion: "9.6"
8 | writeConnectionSecretToRef:
9 | name: app-postgres
10 | {{- if .Values.postgresql.managedClassSelector }}
11 | classSelector:
12 | {{ toYaml .Values.postgresql.managedClassSelector | indent 4 }}
13 | {{- end }}
14 | {{- end -}}
15 |
--------------------------------------------------------------------------------
/spec/support/request_errors.rb:
--------------------------------------------------------------------------------
1 | RSpec.configure do |config|
2 | config.before(:example, type: :request) do |example|
3 | if example.description.start_with?('responds with 404', 'responds with 500')
4 | allow(Rails.application).to receive(:env_config).and_wrap_original do |m|
5 | m.call.merge(
6 | 'action_dispatch.show_exceptions' => true,
7 | 'action_dispatch.show_detailed_exceptions' => false,
8 | )
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | default: &default
2 | adapter: postgresql
3 | encoding: unicode
4 | pool: 50
5 |
6 | development:
7 | <<: *default
8 | database: podaas_development
9 | username: postgres
10 | password: password
11 |
12 | test:
13 | <<: *default
14 | database: podaas_test
15 | username: postgres
16 | password: password
17 |
18 | staging:
19 | url: <%= ENV['DATABASE_URL'] %>
20 | pool: 30
21 |
22 | production:
23 | url: <%= ENV['DATABASE_URL'] %>
24 | pool: 50
25 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which is enabled by default.
4 |
5 | # Disable parameter wrapping for JSON.
6 | ActiveSupport.on_load(:action_controller) do
7 | wrap_parameters format: []
8 | end
9 |
10 | # Disable root element in JSON for ActiveRecord objects.
11 | ActiveSupport.on_load(:active_record) do
12 | self.include_root_in_json = false
13 | end
14 |
--------------------------------------------------------------------------------
/spec/support/fixture_names.rb:
--------------------------------------------------------------------------------
1 | module FixtureNames
2 | def fixture_names(pattern)
3 | Dir[File.join(file_fixture_path, pattern)].sort.map { |name| name.remove(file_fixture_path) }
4 | end
5 |
6 | def fixture_name_to_human(name)
7 | fixes = { 'ed' => 'ED', 'edesk' => 'eDesk', 'egov' => 'eGov' }
8 | File.basename(name, '.*').remove('_response').split('_').map { |p| fixes[p] || p }.join(' ')
9 | end
10 | end
11 |
12 | RSpec.configure do |config|
13 | config.extend FixtureNames
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20181210113900_create_form_templates.rb:
--------------------------------------------------------------------------------
1 | class CreateFormTemplates < ActiveRecord::Migration[5.2]
2 | def change
3 | create_table :form_templates do |t|
4 | t.string :identifier, null: false
5 | t.integer :version_major, null: false
6 | t.integer :version_minor, null: false
7 |
8 | t.timestamps
9 | end
10 |
11 | add_index :form_templates, [:identifier, :version_major, :version_minor], unique: true, name: 'index_form_templates_on_identifier_and_version'
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/spec/fixtures/api/edesk/folders.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 20378640,
4 | "parent_id": null,
5 | "name": "Inbox",
6 | "system": true
7 | },
8 | {
9 | "id": 20378641,
10 | "parent_id": null,
11 | "name": "SentItems",
12 | "system": true
13 | },
14 | {
15 | "id": 20378642,
16 | "parent_id": null,
17 | "name": "Drafts",
18 | "system": true
19 | },
20 | {
21 | "id": 25616503,
22 | "parent_id": null,
23 | "name": "Bin",
24 | "system": true
25 | }
26 | ]
27 |
--------------------------------------------------------------------------------
/chart/templates/cilium-network-policy.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.ciliumNetworkPolicy.enabled -}}
2 | apiVersion: cilium.io/v2
3 | kind: CiliumNetworkPolicy
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | {{- if .Values.ciliumNetworkPolicy.alerts.enabled }}
7 | annotations:
8 | "app.gitlab.com/alert": "true"
9 | {{- end }}
10 | labels:
11 | app.gitlab.com/proj: {{ .Values.gitlab.projectID | quote }}
12 | {{ include "sharedlabels" . | indent 4}}
13 | spec:
14 | {{ toYaml .Values.ciliumNetworkPolicy.spec | indent 2 }}
15 | {{- end -}}
16 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/egov_application_empty_general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3.0
4 |
5 |
6 | EGOV_APPLICATION
7 | App.GeneralAgenda
8 | 1.9
9 | 00000000-0000-0000-0000-000000000000
10 | 00000000-0000-0000-0000-000000000000
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/find_form_templates_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_FINDFORMTEMPLATES_SOAP_V_1_0
4 |
5 |
6 |
--------------------------------------------------------------------------------
/db/migrate/20181210164801_create_form_template_related_documents.rb:
--------------------------------------------------------------------------------
1 | class CreateFormTemplateRelatedDocuments < ActiveRecord::Migration[5.2]
2 | def change
3 | create_table :form_template_related_documents do |t|
4 | t.references :form_template, null: false, foreign_key: true
5 | t.string :data, null: false
6 | t.string :language, null: false
7 | t.string :document_type, null: false
8 |
9 | t.timestamps
10 | end
11 |
12 | add_index :form_template_related_documents, [:form_template_id, :language, :document_type], unique: true, name: 'index_related_documents_on_template_id_and_language_and_type'
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM jruby:9.3.15.0-jdk17
2 |
3 | # Install packages
4 | RUN apt-get update
5 | RUN apt-get install -y build-essential libpq-dev
6 |
7 | # Set working directory
8 | RUN mkdir /app
9 | WORKDIR /app
10 |
11 | # Bundle and cache Ruby gems
12 | COPY Gemfile* ./
13 | RUN bundle config set deployment true
14 | RUN bundle config set without development:test
15 | RUN bundle install
16 |
17 | # Package and cache UPVS library
18 | COPY lib/upvs lib/upvs
19 | RUN gem install ruby-maven
20 | RUN rmvn -f lib/upvs package
21 |
22 | # Cache everything
23 | COPY . .
24 |
25 | # Run application by default
26 | CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
27 |
--------------------------------------------------------------------------------
/chart/templates/pdb.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.podDisruptionBudget.enabled }}
2 | apiVersion: policy/v1beta1
3 | kind: PodDisruptionBudget
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | labels:
7 | {{ include "sharedlabels" . | indent 4 }}
8 | spec:
9 | {{- if .Values.podDisruptionBudget.minAvailable }}
10 | minAvailable: {{ .Values.podDisruptionBudget.minAvailable }}
11 | {{- end }}
12 | {{- if .Values.podDisruptionBudget.maxUnavailable }}
13 | maxUnavailable: {{ .Values.podDisruptionBudget.maxUnavailable }}
14 | {{- end }}
15 | selector:
16 | matchLabels:
17 | app: {{ template "appname" . }}
18 | release: {{ .Release.Name }}
19 | {{- end }}
20 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/cep/zisti_typ_a_formu_podpisu/response_unsigned.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 2123249
4 | Vstupné dáta neobsahujú podpis alebo obsahujú nepodporovaný typ podpisu
5 |
6 | 9f696c01-b6c8-4bc7-81da-5ddf9b7f88df
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status/input_parameter_type_mismatch_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status/unset_object_reference_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
4 |
5 |
6 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Publikovaný
5 |
6 | App.GeneralAgenda
7 |
8 | 1
9 | 9
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/services/upvs_proxy.rb:
--------------------------------------------------------------------------------
1 | class UpvsProxy < SimpleDelegator
2 | def initialize(properties)
3 | super digital.slovensko.upvs.UpvsProxy.new(properties)
4 | end
5 |
6 | # TODO methods may have misleading names consider this change:
7 | # sktalk (Štandard pre komunikáciu prostredníctvom ÚPVS) -> urp (Univerzálne integračné rozhranie s asynchrónne rozhranie na príjem správ do ÚPVS)
8 | # ez (Externá zbernica) -> usr (Univerzálne synchrónne rozhranie pre sprístupnenie ostatných synchrónnych služieb modulov ÚPVS – z pohľadu SP ide o rozhranie externej zbernice)
9 | # eks (?) -> ekr (Externé komunikačné rozhranie)
10 | # iam / sts -> seems ok
11 | # TODO search for file names / directories / paths etc.
12 | end
13 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status/no_form_template_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | ActiveSupport::Inflector.inflections(:en) do |inflect|
14 | inflect.acronym 'ID'
15 | inflect.acronym 'URI'
16 |
17 | inflect.human /_id$/i, '\1 identifier'
18 | end
19 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | upvs.log.level
8 | INFO
9 |
10 |
11 |
12 |
13 | %d{HH:mm:ss.SSS} [%thread] %level: %logger{42} - %msg%n
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/config/initializers/upvs_authentication.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | return unless UpvsEnvironment.sso_support?
4 |
5 | Rails.application.config.middleware.use OmniAuth::Builder do
6 | configure do |config|
7 | # Raise errors in every environment instead of redirecting to the default error page.
8 | config.failure_raise_out_environments = ['development', 'production', 'staging', 'test']
9 |
10 | # Respond to saml, saml/callback, saml/metadata, saml/slo, and saml/spslo under path prefix.
11 | config.path_prefix = '/auth'
12 |
13 | # Use default application logger.
14 | config.logger = Rails.logger
15 | end
16 |
17 | provider :saml, UpvsEnvironment.sso_settings
18 | end
19 |
--------------------------------------------------------------------------------
/app/jobs/download_form_templates_job.rb:
--------------------------------------------------------------------------------
1 | class DownloadFormTemplatesJob < ApplicationJob
2 | def perform(force: false)
3 | Heartbeat.find_or_create_by(name: self.class.name).touch
4 |
5 | eform_service = UpvsEnvironment.eform_service(sub: ENV.fetch('EFORM_SYNC_SUBJECT'))
6 | eform_service.fetch_all_form_template_ids.each do |template_id|
7 | identifier, version_major, version_minor = template_id.identifier.value, template_id.version.value.major, template_id.version.value.minor
8 | next if FormTemplate.exists?(identifier: identifier, version_major: version_major, version_minor: version_minor) && !force
9 | DownloadFormTemplateJob.perform_later(identifier, version_major, version_minor)
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20181211152434_create_delayed_jobs.rb:
--------------------------------------------------------------------------------
1 | class CreateDelayedJobs < ActiveRecord::Migration[5.2]
2 | def self.up
3 | create_table :delayed_jobs, force: true do |table|
4 | table.integer :priority, default: 0, null: false
5 | table.integer :attempts, default: 0, null: false
6 | table.text :handler, null: false
7 | table.text :last_error
8 | table.datetime :run_at
9 | table.datetime :locked_at
10 | table.datetime :failed_at
11 | table.string :locked_by
12 | table.string :queue
13 | table.timestamps null: true
14 | end
15 |
16 | add_index :delayed_jobs, [:priority, :run_at], name: 'delayed_jobs_priority'
17 | end
18 |
19 | def self.down
20 | drop_table :delayed_jobs
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/app/controllers/administration/certificates_controller.rb:
--------------------------------------------------------------------------------
1 | class Administration::CertificatesController < ApiController
2 | before_action { authenticate(allow_plain: true) }
3 |
4 | before_action(only: :create) { head :conflict if UpvsEnvironment.subject?(params[:id]) }
5 | before_action(only: [:show, :destroy]) { head :not_found unless UpvsEnvironment.subject?(params[:id]) }
6 |
7 | def create
8 | UpvsEnvironment.create_subject(params[:id], **params.permit(:cin).to_options)
9 |
10 | head :created
11 | end
12 |
13 | def show
14 | subject = UpvsEnvironment.subject(params[:id])
15 |
16 | render json: subject
17 | end
18 |
19 | def destroy
20 | UpvsEnvironment.delete_subject(params[:id])
21 |
22 | head :no_content
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/fixtures/oam/slo_response_different_user.xml:
--------------------------------------------------------------------------------
1 |
2 | https://auth.vyvoj.upvs.globaltel.sk/oam/fed
3 |
4 |
5 | User authenticated at IdP different from User specified in the Request message
6 |
7 |
8 |
--------------------------------------------------------------------------------
/spec/helpers/upvs_objects_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe UpvsObjects do
4 | subject { described_class }
5 |
6 | describe '.to_structure' do
7 | it 'transforms Java collections to Ruby objects' do
8 | expect(subject.to_structure(java.util.ArrayList.new)).to be_an_instance_of(Array)
9 | expect(subject.to_structure(java.util.HashMap.new)).to be_an_instance_of(Hash)
10 | end
11 |
12 | it 'transforms Java structures to Ruby objects' do
13 | expect(subject.to_structure('folderIds' => java.util.Arrays.as_list(0, 1, 2))).to eq('folder_ids' => [0, 1, 2])
14 | expect(subject.to_structure('folders' => com.google.common.collect.ImmutableMap.of('folderId', 0))).to eq('folders' => { 'folder_id' => 0 })
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/views/iam/_natural_person_name.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.name natural_person.formatted_name
2 | json.given_names natural_person.given_name
3 | json.preferred_given_name natural_person.preferred_given_name
4 |
5 | json.given_family_names natural_person.given_family_name do |n|
6 | json.primary n.is_primary
7 | json.(n, :prefix, :value)
8 | end
9 |
10 | json.family_names natural_person.family_name do |n|
11 | json.primary n.is_primary
12 | json.(n, :prefix, :value)
13 | end
14 |
15 | json.legal_name natural_person.legal_name
16 | json.other_name natural_person.other_name
17 |
18 | json.prefixes natural_person.affix.select { |a| a.position.to_s == 'Prefix' }, partial: 'iam/affix'
19 | json.suffixes natural_person.affix.select { |a| a.position.to_s == 'Postfix' }, partial: 'iam/affix'
20 |
--------------------------------------------------------------------------------
/app/views/iam/identities/_natural_person_name.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.name natural_person.formatted_name
2 | json.given_names natural_person.given_name
3 | json.preferred_given_name natural_person.preferred_given_name
4 |
5 | json.given_family_names natural_person.given_family_name do |n|
6 | json.primary n.is_primary
7 | json.(n, :prefix, :value)
8 | end
9 |
10 | json.family_names natural_person.family_name do |n|
11 | json.primary n.is_primary
12 | json.(n, :prefix, :value)
13 | end
14 |
15 | json.legal_name natural_person.legal_name
16 | json.other_name natural_person.other_name
17 |
18 | json.prefixes natural_person.affix.select { |a| a.position.to_s == 'Prefix' }, partial: 'affix'
19 | json.suffixes natural_person.affix.select { |a| a.position.to_s == 'Postfix' }, partial: 'affix'
20 |
--------------------------------------------------------------------------------
/spec/support/redis_cache_stores.rb:
--------------------------------------------------------------------------------
1 | class ActiveSupport::Cache::RedisCacheStore
2 | def keys
3 | redis.keys([options[:namespace], '*'].compact * ':')
4 | end
5 | end
6 |
7 | class MockRedis
8 | alias_method :with, :yield_self
9 | end
10 |
11 | module RedisCacheStores
12 | def redis_cache_store_in_ruby_memory
13 | ActiveSupport::Cache::RedisCacheStore.new(namespace: SecureRandom.uuid, redis: MockRedis.new)
14 | end
15 |
16 | def redis_cache_store_without_connection
17 | error_handler = -> (method:, **) { Environment::REDIS_CONNECTION_ENFORCER.call if method != :clear }
18 | ActiveSupport::Cache::RedisCacheStore.new(url: 'redis://127.0.0.1:10', error_handler: error_handler)
19 | end
20 | end
21 |
22 | RSpec.configure do |config|
23 | config.include RedisCacheStores
24 | end
25 |
--------------------------------------------------------------------------------
/chart/templates/pvc.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.persistence.enabled -}}
2 | {{- $context := . }}
3 | {{- range $volume := .Values.persistence.volumes }}
4 | ---
5 | kind: PersistentVolumeClaim
6 | apiVersion: v1
7 | metadata:
8 | {{ $args := dict "context" $context "name" $volume.name }}
9 | name: {{ template "pvcName" $args }}
10 | labels:
11 | track: "{{ $.Values.application.track }}"
12 | tier: "{{ $.Values.application.tier }}"
13 | {{ include "sharedlabels" $context | indent 4 }}
14 | spec:
15 | accessModes:
16 | - {{ $volume.claim.accessMode | quote }}
17 | resources:
18 | requests:
19 | storage: {{ $volume.claim.size | quote }}
20 | {{- if $volume.claim.storageClass }}
21 | storageClassName: {{ $volume.claim.storageClass | quote }}
22 | {{- end }}
23 | {{- end }}
24 | {{- end -}}
25 |
--------------------------------------------------------------------------------
/chart/templates/hpa.yaml:
--------------------------------------------------------------------------------
1 | {{- if and .Values.hpa.enabled .Values.resources.requests -}}
2 | {{- if .Values.hpa.metrics }}
3 | apiVersion: autoscaling/v2beta2
4 | {{- else }}
5 | apiVersion: autoscaling/v1
6 | {{- end }}
7 | kind: HorizontalPodAutoscaler
8 | metadata:
9 | name: {{ template "fullname" . }}
10 | labels:
11 | {{ include "sharedlabels" . | indent 4 }}
12 | spec:
13 | scaleTargetRef:
14 | apiVersion: apps/v1
15 | kind: Deployment
16 | name: {{ template "appname" . }}
17 | minReplicas: {{ .Values.hpa.minReplicas }}
18 | maxReplicas: {{ .Values.hpa.maxReplicas }}
19 | {{- if .Values.hpa.metrics }}
20 | metrics:
21 | {{ toYaml .Values.hpa.metrics | indent 2 }}
22 | {{- else }}
23 | targetCPUUtilizationPercentage: {{ .Values.hpa.targetCPUUtilizationPercentage }}
24 | {{- end }}
25 | {{- end}}
26 |
--------------------------------------------------------------------------------
/app/helpers/upvs_objects.rb:
--------------------------------------------------------------------------------
1 | module UpvsObjects
2 | extend self
3 |
4 | mattr_reader :datatype_factory, default: javax.xml.datatype.DatatypeFactory.new_instance
5 |
6 | delegate :from_xml, :to_xml, to: digital.slovensko.upvs.UpvsObjects
7 |
8 | def to_structure(object)
9 | to_ruby_object(digital.slovensko.upvs.UpvsObjects.to_structure(object))
10 | end
11 |
12 | alias_method :to_struct, :to_structure
13 |
14 | private
15 |
16 | def to_ruby_object(object)
17 | return object.to_a.map { |e| to_ruby_object(e) } if object.is_a?(java.util.Collection)
18 | return object.to_h.map { |k, v| [to_ruby_key(k), to_ruby_object(v)] }.to_h if object.is_a?(java.util.Map)
19 | object
20 | end
21 |
22 | def to_ruby_key(key)
23 | key.is_a?(String) ? key.underscore : to_ruby_object(key)
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/app/models/form_template.rb:
--------------------------------------------------------------------------------
1 | # TODO add annotate gem
2 | # TODO replace version_major/version_minor with single version field
3 |
4 | class FormTemplate < ApplicationRecord
5 | # TODO remove class_name once FormTemplateRelatedDocument is renamed just to RelatedDocument
6 | has_many :related_documents, class_name: 'FormTemplateRelatedDocument'
7 |
8 | # TODO remove but consider moving #version_major and #version_minor here as #version string
9 | def version
10 | "#{version_major}.#{version_minor}"
11 | end
12 |
13 | # TODO rename to just schema: "xsd_schema" reads "XML schema definition schema" which is weird
14 | def xsd_schema
15 | related_document('CLS_F_XSD_EDOC')
16 | end
17 |
18 | def related_document(type)
19 | related_documents.where(document_type: type).where("lower(language) = 'sk'")&.first&.data
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/upvs/src/digital/slovensko/upvs/internals/StringToElementConverter.java:
--------------------------------------------------------------------------------
1 | // TODO remove this after removing appropriate configuration files
2 |
3 | package digital.slovensko.upvs.internals;
4 |
5 | import java.io.StringReader;
6 |
7 | import javax.xml.stream.XMLStreamException;
8 |
9 | import org.apache.cxf.staxutils.StaxUtils;
10 | import org.springframework.core.convert.converter.Converter;
11 | import org.springframework.stereotype.Component;
12 | import org.w3c.dom.Element;
13 |
14 | @Component
15 | public class StringToElementConverter implements Converter {
16 | @Override
17 | public Element convert(final String value) {
18 | try {
19 | return StaxUtils.read(new StringReader(value)).getDocumentElement();
20 | } catch (XMLStreamException e) {
21 | throw new RuntimeException(e);
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/doc/templates/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | postgres:
5 | image: postgres:12-alpine
6 | volumes:
7 | - postgres:/var/lib/postgresql/data
8 | ports:
9 | - 5432:5432
10 | environment:
11 | POSTGRES_PASSWORD: password
12 |
13 | redis:
14 | image: redis:5-alpine
15 | ports:
16 | - 6379:6379
17 | volumes:
18 | - redis:/data
19 |
20 | web:
21 | image: ghcr.io/slovensko-digital/slovensko-sk-api:latest
22 | volumes:
23 | - ./security:/app/security
24 | ports:
25 | - 3000:3000
26 | depends_on:
27 | - postgres
28 | - redis
29 | env_file:
30 | - .env
31 | environment:
32 | DATABASE_URL: postgres://postgres:postgres@postgres:5432/slovensko-sk-api
33 | REDIS_URL: redis://redis:6379
34 |
35 | volumes:
36 | postgres:
37 | redis:
38 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/cep/zisti_typ_a_formu_podpisu/response_signed.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0
4 | OK
5 | application/vnd.etsi.asic-e+zip
6 | 3fa9b5fd-4dc1-4d9d-aef9-3198f6c8c5ea
7 |
8 |
9 | XadesBPLevelT
10 | XAdES-BP
11 | true
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/controllers/concerns/pagination.rb:
--------------------------------------------------------------------------------
1 | module Pagination
2 | extend ActiveSupport::Concern
3 |
4 | included do
5 | attr_accessor :page, :per_page
6 |
7 | private
8 |
9 | # TODO consider translating parameters and resources: t(:page) -> 'Page number'
10 |
11 | def set_page(default: 1, maximum: nil)
12 | self.page = Integers.parse_positive(params.fetch(:page, default))
13 | render_bad_request(:out_of_range, :page_number) if maximum && page > maximum
14 | rescue ArgumentError
15 | render_bad_request(:invalid, :page_number)
16 | end
17 |
18 | def set_per_page(default: 50, range: 10..100)
19 | self.per_page = Integers.parse_positive(params.fetch(:per_page, default))
20 | render_bad_request(:out_of_range, :per_page_number) unless per_page.in?(range)
21 | rescue ArgumentError
22 | render_bad_request(:invalid, :per_page_number)
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
4 |
5 |
6 | App.GeneralAgenda
7 |
8 | 1
9 | 9
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_form_template_status/invalid_form_template_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
4 |
5 |
6 | App.GeneralAgenda
7 |
8 | A
9 | B
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/spec/support/upvs_support.rb:
--------------------------------------------------------------------------------
1 | module UpvsSupport
2 | delegate :sso_support?, to: UpvsEnvironment
3 | delegate :obo_support?, to: UpvsEnvironment
4 | end
5 |
6 | RSpec.configure do |config|
7 | # enable UPVS helpers in examples
8 | config.include UpvsSupport
9 |
10 | # enable UPVS helpers in example groups
11 | config.extend UpvsSupport
12 |
13 | def config.inclusion_or_exclusion_filter?(tag)
14 | inclusion_filter.rules.key?(tag) || exclusion_filter.rules.key?(tag)
15 | end
16 |
17 | # skip all examples related to UPVS STS by default
18 | config.filter_run_excluding(sts: true) unless config.inclusion_or_exclusion_filter?(:sts)
19 |
20 | # skip all examples related to NASES UAT by default
21 | config.filter_run_excluding(uat: true) unless config.inclusion_or_exclusion_filter?(:uat)
22 |
23 | warn 'WARNING: Please consider running examples in UPVS FIX environment' unless Upvs.env.fix?
24 | abort 'ERROR: Unable to run examples in UPVS PROD environment' if Upvs.env.prod?
25 | end
26 |
--------------------------------------------------------------------------------
/app/services/cep_signer.rb:
--------------------------------------------------------------------------------
1 | class CepSigner
2 | def initialize(proxy)
3 | @upvs = proxy
4 | end
5 |
6 | def signatures_info(content)
7 | request = factory.create_zisti_typ_aformu_podpisu2_req
8 |
9 | request.data_b64 = factory.create_zisti_typ_aformu_podpisu_req_data_b64(content)
10 |
11 | @upvs.ez.call_service(ServiceClassEnum::DITEC_CEP_ZISTI_TYP_A_FORMU_PODPISU_2, request)
12 | end
13 |
14 | private
15 |
16 | mattr_reader :factory, default: sk.gov.schemas.servicebusserviceprovider.ditec.cepprovider._1.ObjectFactory.new
17 |
18 | java_import sk.gov.schemas.servicebus.service._1.ServiceClassEnum
19 | java_import sk.gov.schemas.servicebusserviceprovider.ditec.cepprovider._1.Encoding
20 | java_import sk.gov.schemas.servicebusserviceprovider.ditec.cepprovider._1.ItemChoiceType
21 | java_import sk.gov.schemas.servicebusserviceprovider.ditec.cepprovider._1.TypVizualizacie
22 | java_import sk.gov.schemas.servicebusserviceprovider.ditec.cepprovider._1.VerziaFormatuPodpisu
23 | end
24 |
--------------------------------------------------------------------------------
/spec/fixtures/oam/slo_request.query:
--------------------------------------------------------------------------------
1 | ?SAMLRequest=nVNdc5pAFP0rzPYZWEDTsBPNaKwTWjSJmGjztsoiW5ddy11Q8%2Bu7GM2kmSad9vVyvu497MXlrhBWzUrgSnaQ52BkMblUKZerDrqfDu1zZIGmMqVCSdZBewbosnsBtBAbEquVqvSE%2FawYaMsoSSApcMPMtd4Q191ut842cFS5cn2MsYtD16AayCd0xBu3d%2BCei1sN3CBe0I1vB1WlJIoCByJpwYDoJUl6o5j4DiYUgJXabPOasvmYsymVVkslTpRdG%2BO%2FMjIuzJBqXfJFpRmZG9KLAPB3l5qP4mSZs4LaXDaXXTJkjZW%2BkTdlL9Os7CAfe%2Be259teOPUC0m6RdviIrGjQQTy1%2BSC9pv1RK%2B5NZlH8OLrrDezsW92fLvwkSq7DL9k9y%2Fz5GlkPp1b9ptUIoGLRwVG%2FtQiOFgNTI5dUH1jH%2BEItqcgVaBI0DYpD5ej5DyAH0dIaqrKg%2BuOLNRMTPztATeua6z3qNiZgXGilc6fe1%2BqHU21qcFZCLajQTDiwdhUt3IylF%2B4rz2OAsVGNBv8RQJdUAjcxzPHNh7uKCp7x5vr%2FEglZye0f6IadstrZqJRScEComklYKyflK66pQF2To23vP8to96D4KlzzUTzLcZ7tx5NJPg6erpmsz%2FtZImbecevnRU8PL2HQVBvJlO0aMUhYFpwld9%2FzAF8VObbbT4tg%2FBh%2BjbP5WWsWDsPp1a1nx89ib%2Fin4W%2BvufsL&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=kpAvTYt1Ba8jdIxYaAebStvYKqcudFQmuMedALrF8M6PiD7GLPvm02OBF28Oww8Pf1SxqZD7D8Dyu%2FPjg7J%2BqnpDuYPYBaZfKBqOONgowUOtaJnME%2Bb4o%2BR8GcPn%2BdhPZ1nePK%2BU5Yj40GU3S4JzWSqdxtjJQGzZ4rgRELCCJVM%3D
2 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_related_document_by_type_request.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | EFORM_GETRELATEDDOCUMENTBYTYPE_SOAP_V_1_0
4 |
5 |
6 | App.GeneralAgenda
7 |
8 | 1
9 | 9
10 |
11 |
12 | sk
13 | CLS_F_XSD_EDOC
14 |
15 |
16 |
--------------------------------------------------------------------------------
/chart/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright GitLab B.V.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/spec/services/upvs_proxy_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | # NOTE: requires any UPVS technical account
4 |
5 | RSpec.describe UpvsProxy, :sts do
6 | let(:properties) { UpvsEnvironment.properties(sub: corporate_body_subject) }
7 |
8 | subject { described_class.new(properties) }
9 |
10 | describe '.new' do
11 | it 'creates UPVS proxy' do
12 | expect(subject).to be_an UpvsProxy
13 | end
14 | end
15 |
16 | describe '#eks' do
17 | it 'returns EKS service' do
18 | expect(subject.eks).to be_a sk.gov.schemas.edesk.eksservice._1.IEKSService
19 | end
20 | end
21 |
22 | describe '#ez' do
23 | it 'returns EZ service' do
24 | expect(subject.ez).to be_a sk.gov.schemas.servicebus.service._1_0.IServiceBus
25 | end
26 | end
27 |
28 | describe '#iam' do
29 | it 'returns IAM service' do
30 | expect(subject.iam).to be_a sk.gov.schemas.identity.service._1_7.IdentityServices
31 | end
32 | end
33 |
34 | describe '#sktalk' do
35 | it 'returns SKTalk service' do
36 | expect(subject.sktalk).to be_a sk.gov.egov.iservice.IService
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/app/views/iam/_corporate_body.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.cin identity.id.find { |id| id.identifier_type.id == '7' }&.identifier_value
2 | json.tin identity.id.find { |id| id.identifier_type.id == '8' }&.identifier_value
3 |
4 | json.organization_id corporate_body.org_id
5 | json.organization_units corporate_body.organization_unit
6 |
7 | json.partial! 'iam/corporate_body_name', corporate_body: corporate_body
8 | json.alternative_names corporate_body.corporate_body_alternative_name
9 |
10 | json.legal_form { json.partial! 'iam/enumeration', value: corporate_body.legal_form }
11 | json.legal_facts corporate_body.other_legal_facts
12 |
13 | json.activities corporate_body.activities
14 |
15 | # TODO
16 | # json.bank_connections corporate_body.bank_connection do |c|
17 | # end
18 |
19 | # TODO
20 | # json.stakeholders corporate_body.stakeholder do |s|
21 | # end
22 |
23 | # TODO
24 | # corporate_body.sid
25 | # corporate_body.equity
26 | # corporate_body.suspension
27 |
28 | json.established_on corporate_body.establishment.to_s.to_date
29 | json.terminated_on corporate_body.termination.to_s.to_date
30 | json.updated_on corporate_body.date_of_status_change.to_s.to_date
31 |
--------------------------------------------------------------------------------
/app/views/iam/identities/_corporate_body.json.jbuilder:
--------------------------------------------------------------------------------
1 | json.cin identity.id.find { |id| id.identifier_type.id == '7' }&.identifier_value
2 | json.tin identity.id.find { |id| id.identifier_type.id == '8' }&.identifier_value
3 |
4 | json.organization_id corporate_body.org_id
5 | json.organization_units corporate_body.organization_unit
6 |
7 | json.partial! 'corporate_body_name', corporate_body: corporate_body
8 | json.alternative_names corporate_body.corporate_body_alternative_name
9 |
10 | json.legal_form { json.partial! 'enumeration', value: corporate_body.legal_form }
11 | json.legal_facts corporate_body.other_legal_facts
12 |
13 | json.activities corporate_body.activities
14 |
15 | # TODO
16 | # json.bank_connections corporate_body.bank_connection do |c|
17 | # end
18 |
19 | # TODO
20 | # json.stakeholders corporate_body.stakeholder do |s|
21 | # end
22 |
23 | # TODO
24 | # corporate_body.sid
25 | # corporate_body.equity
26 | # corporate_body.suspension
27 |
28 | json.established_on corporate_body.establishment.to_s.to_date
29 | json.terminated_on corporate_body.termination.to_s.to_date
30 | json.updated_on corporate_body.date_of_status_change.to_s.to_date
31 |
--------------------------------------------------------------------------------
/chart/templates/service.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.service.enabled -}}
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: {{ template "fullname" . }}
6 | annotations:
7 | {{- if .Values.service.annotations }}
8 | {{ toYaml .Values.service.annotations | indent 4 }}
9 | {{- end }}
10 | {{- if .Values.prometheus.metrics }}
11 | prometheus.io/scrape: "true"
12 | prometheus.io/port: "{{ .Values.service.internalPort }}"
13 | {{- end }}
14 | labels:
15 | track: "{{ .Values.application.track }}"
16 | {{ include "sharedlabels" . | indent 4 }}
17 | spec:
18 | type: {{ .Values.service.type }}
19 | ports:
20 | - port: {{ .Values.service.externalPort }}
21 | targetPort: {{ .Values.service.internalPort }}
22 | protocol: TCP
23 | name: {{ .Values.service.name }}
24 | {{- if eq .Values.service.type "NodePort" }}
25 | nodePort: {{ .Values.service.nodePort }}
26 | {{- end }}
27 | {{- if .Values.service.extraPorts }}
28 | {{ toYaml .Values.service.extraPorts | indent 2 }}
29 | {{- end }}
30 | selector:
31 | app: {{ template "appname" . }}
32 | tier: "{{ .Values.application.tier }}"
33 | track: "{{ .Values.application.track }}"
34 | {{- end -}}
35 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | ruby '2.6.8', engine: 'jruby', engine_version: '9.3.15.0'
4 |
5 | gem 'rails', '~> 5.2.6'
6 | gem 'tzinfo-data', platforms: [:jruby]
7 | gem 'puma', '~> 6.3.1'
8 |
9 | # Drivers
10 | gem 'activerecord-jdbcpostgresql-adapter'
11 | gem 'redis'
12 |
13 | # Security
14 | gem 'ruby-saml', '~> 1.17'
15 | gem 'omniauth-saml', '~> 1.10' # TODO unlock this once https://sluzbyslovenskodigital.atlassian.net/browse/API-103 is resolved
16 | gem 'jwt'
17 |
18 | # Workers
19 | gem 'clockwork'
20 | gem 'delayed_job_active_record'
21 |
22 | # Utilities
23 | gem 'htmlentities'
24 | gem 'jbuilder'
25 | gem 'nokogiri'
26 | gem 'rubyzip'
27 | gem 'xmldsig'
28 |
29 | gem 'i18n', '1.8.7' # TODO unlock this once https://github.com/jruby/jruby/issues/6547 and https://github.com/ruby-i18n/i18n/issues/555 are resolved
30 |
31 | group :development, :test do
32 | gem 'database_cleaner-active_record'
33 | gem 'database_cleaner-redis'
34 | gem 'dotenv-rails'
35 | gem 'factory_bot_rails'
36 | gem 'mock_redis'
37 | gem 'pry-rails'
38 | gem 'rspec-rails'
39 | gem 'super_diff'
40 | end
41 |
42 | group :development do
43 | gem 'annotate'
44 | gem 'listen'
45 | end
46 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | bad_request:
3 | invalid: 'Invalid %{param}'
4 | missing: 'No %{param}'
5 | out_of_range: '%{param} out of range'
6 | redundant: 'Redundant %{param}'
7 | unpermitted_params: 'Unpermitted parameters: %{value}'
8 | internal_server_error: 'Unknown error'
9 | not_acceptable: 'Unacceptable Content-Type requested'
10 | not_found: '%{resource} not found'
11 | payload_too_large: 'Request payload limit exceeded'
12 | request_timeout: 'Operation timeout exceeded'
13 | conflict:
14 | inactive_box: 'Box inactive'
15 | service_unavailable:
16 | connection_refused: 'ÚPVS connection refused'
17 | unknown_error: 'Unknown failure'
18 | ekr: 'EKR failure'
19 | sts: 'STS failure'
20 | too_many_requests: 'Request rate limit exceeded'
21 | unauthorized: 'Bad credentials'
22 | unprocessable_entity:
23 | notification_report_already_confirmed: 'The notification report has already been confirmed'
24 | authorize_non_notification_report: 'Cannot authorize non-notification report message'
25 | received_as_being_saved_to_folder: 'Message should not be received as being saved to folder'
26 | unsupported_media_type: 'Invalid Content-Type'
27 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/forms/delivery_report_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ico://sk/42156424_90000
5 | ico://sk/6501012225
6 |
7 |
8 | 2016-10-18T15:51:23.7860774+02:00
9 | 15
10 | 2016-11-03T00:00:00+01:00
11 |
12 |
13 | e411c801-8290-47c2-8250-801f3cf56e58
14 | Všeobecná agenda - rozhodnutie do vlastných rúk
15 | Doc.GeneralAgendaReport
16 | Po uplynutí dátumu doručenia sa doručovaná správa považuje za nedoručenú.
17 |
18 |
19 | 9db2f9cb-639b-45d9-8f03-24195e5615af
20 | Všeobecná agenda - rozhodnutie do vlastných rúk
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/lib/keystore.rb:
--------------------------------------------------------------------------------
1 | # TODO remove in favor of PKCS -> replace Java Keystores with PKCS in pure OpenSSL Ruby library
2 |
3 | class KeyStore
4 | Error = Class.new(StandardError)
5 |
6 | def initialize(file, password, type: 'JKS')
7 | @keystore = java.security.KeyStore.get_instance(type)
8 | @keystore.load(java.io.FileInputStream.new(file), password.chars.to_java(:char))
9 | # TODO is this a bug? file not closed!
10 | rescue
11 | raise Error
12 | end
13 |
14 | def certificate(entry)
15 | @keystore.get_certificate(entry)
16 | rescue
17 | raise Error
18 | end
19 |
20 | def certificate_in_base64(entry)
21 | encode_base64(certificate(entry))
22 | end
23 |
24 | def private_key(entry, private_password)
25 | @keystore.get_key(entry, private_password.chars.to_java(:char))
26 | rescue
27 | raise Error
28 | end
29 |
30 | def private_key_in_base64(entry, private_password)
31 | encode_base64(private_key(entry, private_password))
32 | end
33 |
34 | private
35 |
36 | def base64_encoder
37 | @base64_encoder ||= java.util.Base64.get_mime_encoder(76, "\n".bytes.to_java(:byte))
38 | end
39 |
40 | def encode_base64(object)
41 | base64_encoder.encode_to_string(object.get_encoded)
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/app/models/message.rb:
--------------------------------------------------------------------------------
1 | class Message
2 | # set from eDesk response
3 | attr_accessor :id, :klass, :message_id, :correlation_id, :subject, :original_html, :original_xml, :delivered_at
4 |
5 | # set from SKTalk message
6 | attr_accessor :posp_id, :posp_version, :reference_id
7 | attr_accessor :sender_uri, :recipient_uri, :type, :sender_business_reference, :recipient_business_reference, :objects
8 |
9 | # set specially
10 | attr_accessor :delivery_notification
11 |
12 | # set internally
13 | attr_accessor :parse_error
14 |
15 | def initialize
16 | @objects = []
17 | end
18 |
19 | class Object
20 | attr_accessor :id, :name, :description, :klass, :signed, :mime_type, :encoding, :content
21 | end
22 |
23 | class DeliveryNotification
24 | # set from consignment
25 | attr_accessor :consignment
26 |
27 | # set from delivery information
28 | attr_accessor :delivery_period, :delivery_period_end_at, :received_at
29 |
30 | class Consignment
31 | attr_accessor :message_id, :message_type, :message_subject, :attachments, :note
32 |
33 | def initialize
34 | @attachments = []
35 | end
36 |
37 | class Attachment
38 | attr_accessor :id, :name
39 | end
40 | end
41 | end
42 | end
43 |
--------------------------------------------------------------------------------
/app/controllers/concerns/sktalk_receiving.rb:
--------------------------------------------------------------------------------
1 | # TODO validate form version status
2 | # TODO validate resulting builder message against XSD
3 | # TODO test response against openapi.yml see https://github.com/apiaryio/dredd
4 |
5 | module SktalkReceiving
6 | extend ActiveSupport::Concern
7 |
8 | included do
9 | private
10 |
11 | def receive_sktalk_message(builder, with_objects:, &form)
12 | message = builder.new(**params.permit(:message_id, :correlation_id).to_options) { |m|
13 | m.message_container(**params.permit(:sender_uri, :recipient_uri).to_options) {
14 | m.form_object(&form)
15 | params.require(:objects).each { |object|
16 | m.object(**object.permit(:id, :name, :description, :class, :signed, :mime_type, :encoding).to_options) {
17 | m << object.require(:content)
18 | }
19 | } if with_objects
20 | }
21 | }
22 |
23 | # TODO get save_to_outbox from params
24 | render_sktalk_results sktalk_receiver(upvs_identity).receive!(message.to_xml, save_to_outbox: false)
25 | end
26 |
27 | def render_sktalk_results(results)
28 | render status: (results.receive_timeout || results.save_to_outbox_timeout) ? :request_timeout : :ok, json: results
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/spec/fixtures/eks/get_folders_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 4
5 |
6 |
7 | 20378640
8 |
9 | Inbox
10 | true
11 |
12 |
13 | 20378641
14 |
15 | SentItems
16 | true
17 |
18 |
19 | 20378642
20 |
21 | Drafts
22 | true
23 |
24 |
25 | 25616503
26 |
27 | Bin
28 | true
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/lib/upvs/src/digital/slovensko/upvs/internals/PasswordCallbackHandler.java:
--------------------------------------------------------------------------------
1 | // TODO remove this after removing appropriate configuration files
2 |
3 | package digital.slovensko.upvs.internals;
4 |
5 | import java.io.IOException;
6 |
7 | import javax.security.auth.callback.Callback;
8 | import javax.security.auth.callback.CallbackHandler;
9 | import javax.security.auth.callback.UnsupportedCallbackException;
10 |
11 | import org.apache.wss4j.common.ext.WSPasswordCallback;
12 |
13 | public final class PasswordCallbackHandler implements CallbackHandler {
14 | private final String username;
15 | private final String password;
16 |
17 | public PasswordCallbackHandler(final String username, final String password) {
18 | this.username = username;
19 | this.password = password;
20 | }
21 |
22 | public void handle(final Callback[] callbacks) throws IOException, UnsupportedCallbackException {
23 | for (WSPasswordCallback callback: (WSPasswordCallback[]) callbacks) {
24 | String identifier = callback.getIdentifier();
25 | int usage = callback.getUsage();
26 |
27 | if (usage == WSPasswordCallback.DECRYPT || usage == WSPasswordCallback.SIGNATURE) {
28 | if (this.username.equals(identifier)) {
29 | callback.setPassword(this.password);
30 | }
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/views/edesk/messages/show.json.jbuilder:
--------------------------------------------------------------------------------
1 | # set class two times because setting it the first time marks its position
2 | json.(@message, :id, :class, :message_id, :correlation_id, :reference_id, :posp_id, :posp_version, :sender_uri, :recipient_uri, :type, :subject, :sender_business_reference, :recipient_business_reference, :objects, :original_html, :original_xml)
3 | json.class @message.klass
4 | json.delivered_at @message.delivered_at
5 |
6 | json.objects @message.objects do |o|
7 | json.(o, :id, :name, :description, :class, :signed, :mime_type, :encoding, :content)
8 | json.class o.klass
9 | end
10 |
11 | if @message.delivery_notification
12 | json.delivery_notification do
13 | json.authorize_url authorize_edesk_message_url(@message.id)
14 |
15 | json.consignment do
16 | json.(@message.delivery_notification.consignment, :message_id, :message_type, :message_subject, :attachments, :note)
17 |
18 | json.attachments @message.delivery_notification.consignment.attachments do |a|
19 | json.(a, :id, :name)
20 | end
21 | end
22 |
23 | json.delivery_period @message.delivery_notification.delivery_period
24 | json.delivery_period_end_at @message.delivery_notification.delivery_period_end_at
25 | json.received_at @message.delivery_notification.received_at
26 | end
27 | end
28 |
29 | json.parse_error @message.parse_error.present?
30 |
--------------------------------------------------------------------------------
/spec/jobs/download_form_templates_job_spec.rb:
--------------------------------------------------------------------------------
1 | # TODO jobs should not be STS type specs -> eForm service is covered as STS spec in spec/services
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe DownloadFormTemplatesJob, :sts do
6 | before(:example) { stub_const('ENV', ENV.merge('EFORM_SYNC_SUBJECT' => corporate_body_subject)) }
7 |
8 | describe '#perform' do
9 | before(:context) do
10 | @response = UpvsEnvironment.eform_service(sub: corporate_body_subject).fetch_all_form_template_ids.first(3)
11 | end
12 |
13 | before(:example) do
14 | allow_any_instance_of(EformService).to receive(:fetch_all_form_template_ids).and_return(@response)
15 | end
16 |
17 | before(:example) do
18 | FormTemplate.create(
19 | identifier: @response.first.identifier.value,
20 | version_major: @response.first.version.value.major,
21 | version_minor: @response.first.version.value.minor
22 | )
23 | end
24 |
25 | it 'enqueues DownloadFormTemplateJob for new templates by default' do
26 | expect { subject.perform }.to have_enqueued_job(DownloadFormTemplateJob).exactly(2).times
27 | end
28 |
29 | it 'enqueues DownloadFormTemplateJob for all templates when forced' do
30 | expect { subject.perform(force: true) }.to have_enqueued_job(DownloadFormTemplateJob).exactly(3).times
31 | end
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/spec/support/eform_matchers.rb:
--------------------------------------------------------------------------------
1 | # TODO rm
2 |
3 | RSpec::Matchers.define :eform_find_form_templates_request do
4 | match do |request|
5 | request.is_a?(sk.gov.schemas.servicebusserviceprovider.ness.eformprovider._1.FindFormTemplatesReq)
6 | end
7 | end
8 |
9 | RSpec::Matchers.define :eform_get_form_template_status_request do |identifier, version|
10 | match do |request|
11 | request.is_a?(sk.gov.schemas.servicebusserviceprovider.ness.eformprovider._1.GetFormTemplateStatusReq) &&
12 | request.form_template.value.identifier.value == identifier &&
13 | request.form_template.value.version.value.major == version.split('.').first.to_i &&
14 | request.form_template.value.version.value.minor == version.split('.').last.to_i
15 | end
16 | end
17 |
18 | RSpec::Matchers.define :eform_get_related_document_by_type_request do |identifier, version, type, language|
19 | match do |request|
20 | request.is_a?(sk.gov.schemas.servicebusserviceprovider.ness.eformprovider._1.GetRelatedDocumentByTypeReq) &&
21 | request.form_template.value.identifier.value == identifier &&
22 | request.form_template.value.version.value.major == version.split('.').first.to_i &&
23 | request.form_template.value.version.value.minor == version.split('.').last.to_i &&
24 | request.related_document_type.value == type &&
25 | request.related_document_language.value == language
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/controllers/iam/identities_controller.rb:
--------------------------------------------------------------------------------
1 | class Iam::IdentitiesController < ApiController
2 | include Pagination
3 |
4 | before_action { authenticate(allow_sub: true) }
5 |
6 | before_action(only: :search) { set_page }
7 | before_action(only: :search) { set_per_page(default: 10, range: 10..100) }
8 |
9 | before_action(only: :search) { render_bad_request(:missing, :query) if request.request_parameters.blank? }
10 |
11 | rescue_from(sk.gov.schemas.identity.service._1_7.GetIdentityFault) { |error| render_bad_request(:invalid, :identity_id, upvs_fault(error)) }
12 | rescue_from(sk.gov.schemas.identity.service._1_7.GetEdeskInfo2Fault) { |error| render_bad_request(:invalid, :query, upvs_fault(error)) }
13 |
14 | CODE_LIST_ATTRIBUTES = [:id, :name]
15 |
16 | def show
17 | @identity = iam_repository(upvs_identity).identity(params[:id])
18 | end
19 |
20 | def search
21 | query = params.permit(
22 | :match, :page, :per_page,
23 | :en, :email, :phone,
24 | ids: [],
25 | uris: [],
26 | address: [:type, :street, :building_number, :registration_number, :municipality => CODE_LIST_ATTRIBUTES, :country => CODE_LIST_ATTRIBUTES, :district => CODE_LIST_ATTRIBUTES],
27 | corporate_body: [:cin, :tin, :name],
28 | natural_person: [:given_name, :family_name, :date_of_birth, :place_of_birth],
29 | )
30 |
31 | @identities = iam_repository(upvs_identity).search(query.to_options.merge(page: page, per_page: per_page))
32 | end
33 | end
34 |
--------------------------------------------------------------------------------
/config/puma.rb:
--------------------------------------------------------------------------------
1 | # Puma can serve each request in a thread from an internal thread pool.
2 | # The `threads` method setting takes two numbers: a minimum and maximum.
3 | # Any libraries that use thread pools should be configured to match
4 | # the maximum value specified for Puma. Default is set to 5 threads for minimum
5 | # and maximum; this matches the default thread size of Active Record.
6 |
7 | threads_count = ENV.fetch('RAILS_MAX_THREADS') { 5 }
8 | threads threads_count, threads_count
9 |
10 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
11 |
12 | port ENV.fetch('PORT') { 3000 }
13 |
14 | # Specifies the `environment` that Puma will run in.
15 |
16 | environment ENV.fetch('RAILS_ENV') { 'development' }
17 |
18 | # Specifies the number of `workers` to boot in clustered mode.
19 | # Workers are forked webserver processes. If using threads and workers together
20 | # the concurrency of the application would be max `threads` * `workers`.
21 | # Workers do not work on JRuby or Windows (both of which do not support
22 | # processes).
23 |
24 | # workers ENV.fetch('WEB_CONCURRENCY') { 2 }
25 |
26 | # Use the `preload_app!` method when specifying a `workers` number.
27 | # This directive tells Puma to first boot the application and load code
28 | # before forking the application. This takes advantage of Copy On Write
29 | # process behavior so workers use less memory.
30 |
31 | # preload_app!
32 |
33 | # Allow puma to be restarted by `rails restart` command.
34 |
35 | plugin :tmp_restart
36 |
--------------------------------------------------------------------------------
/app/jobs/download_form_template_job.rb:
--------------------------------------------------------------------------------
1 | class DownloadFormTemplateJob < ApplicationJob
2 | def perform(identifier, version_major, version_minor)
3 | eform_service = UpvsEnvironment.eform_service(sub: ENV.fetch('EFORM_SYNC_SUBJECT'))
4 |
5 | FormTemplate.transaction do
6 | template = FormTemplate.find_or_create_by(identifier: identifier, version_major: version_major, version_minor: version_minor)
7 |
8 | xsd_schema = eform_service.fetch_form_related_document(identifier, "#{version_major}.#{version_minor}", 'CLS_F_XSD_EDOC')
9 | create_form_template_related_document(xsd_schema, template)
10 |
11 | xslt_sign_transformation = eform_service.fetch_form_related_document(identifier, "#{version_major}.#{version_minor}", 'CLS_F_XSLT_TXT_SGN')
12 | create_form_template_related_document(xslt_sign_transformation, template)
13 |
14 | rescue javax.xml.ws.soap.SOAPFaultException => e
15 | raise e unless e.message == '06000796'
16 | end
17 | end
18 |
19 | def create_form_template_related_document(document, template)
20 | return unless document.present?
21 |
22 | FormTemplateRelatedDocument.create_with(data: fix_document_data(document.data.value.to_s)).find_or_create_by(
23 | form_template: template,
24 | language: document.meta_data.value.language.value,
25 | document_type: document.meta_data.value.type.value
26 | )
27 | end
28 |
29 | def fix_document_data(document)
30 | document.force_encoding('UTF-8').gsub(/>\s*/, ">").gsub(/\s*, "<")
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/chart/templates/db-initialize-job.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.application.initializeCommand -}}
2 | apiVersion: batch/v1
3 | kind: Job
4 | metadata:
5 | name: {{ template "trackableappname" . }}-db-initialize
6 | labels:
7 | {{ include "sharedlabels" . | indent 4 }}
8 | annotations:
9 | "helm.sh/hook": post-install
10 | "helm.sh/hook-delete-policy": before-hook-creation
11 | "helm.sh/hook-weight": "0"
12 | spec:
13 | template:
14 | metadata:
15 | labels:
16 | app: {{ template "appname" . }}
17 | release: {{ .Release.Name }}
18 | spec:
19 | restartPolicy: Never
20 | imagePullSecrets:
21 | {{ toYaml .Values.image.secrets | indent 10 }}
22 | containers:
23 | - name: {{ .Chart.Name }}
24 | image: {{ template "imagename" . }}
25 | command: ["/bin/sh"]
26 | args: ["-c", "{{ .Values.application.initializeCommand }}"]
27 | imagePullPolicy: {{ .Values.image.pullPolicy }}
28 | {{- if .Values.application.secretName }}
29 | envFrom:
30 | - secretRef:
31 | name: {{ .Values.application.secretName }}
32 | {{- end }}
33 | env:
34 | {{- if .Values.application.database_url }}
35 | - name: DATABASE_URL
36 | value: {{ .Values.application.database_url | quote }}
37 | {{- end }}
38 | - name: GITLAB_ENVIRONMENT_NAME
39 | value: {{ .Values.gitlab.envName | quote }}
40 | - name: GITLAB_ENVIRONMENT_URL
41 | value: {{ .Values.gitlab.envURL | quote }}
42 | {{- end -}}
43 |
--------------------------------------------------------------------------------
/spec/services/environment_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe Environment do
4 | subject { described_class }
5 |
6 | context 'with OBO support', if: obo_support? do
7 | describe '.obo_token_authenticator' do
8 | it 'returns OBO token authenticator' do
9 | expect(subject.obo_token_authenticator).to be_an(OboTokenAuthenticator)
10 | end
11 | end
12 |
13 | describe '.obo_token_assertion_store' do
14 | it 'returns Redis cache store' do
15 | expect(subject.obo_token_assertion_store).to be_a(ActiveSupport::Cache::RedisCacheStore)
16 | end
17 | end
18 | end
19 |
20 | context 'with UPVS SSO support', if: sso_support? do
21 | describe '.obo_token_authenticator' do
22 | it 'returns OBO token authenticator' do
23 | expect(subject.obo_token_authenticator).to be_an(OboTokenAuthenticator)
24 | end
25 | end
26 |
27 | describe '.obo_token_assertion_store' do
28 | it 'returns Redis cache store' do
29 | expect(subject.obo_token_assertion_store).to be_a(ActiveSupport::Cache::RedisCacheStore)
30 | end
31 | end
32 | end
33 |
34 | context 'without UPVS SSO support', unless: sso_support? do
35 | describe '.obo_token_authenticator' do
36 | it 'returns nil' do
37 | expect(subject.obo_token_authenticator).to be_nil
38 | end
39 | end
40 |
41 | describe '.obo_token_assertion_store' do
42 | it 'returns nil' do
43 | expect(subject.obo_token_assertion_store).to be_nil
44 | end
45 | end
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # slovensko.sk API od Slovensko.Digital
2 |
3 | [](https://github.com/slovensko-digital/slovensko-sk-api/actions/workflows/slovensko_digital_ci.yml)
4 |
5 | slovensko.sk API je proxy REST API komponent k službám www.slovensko.sk (Ústredný portál verejnej správy – ÚPVS). Distribuovaný je ako Docker [kontajner](https://ghcr.io/slovensko-digital/slovensko-sk-api). Pomocou neho viete urobiť prihlasovanie cez eID, získať informácie o prihlásenej osobe, zasielať podania v mene prihlásenej osoby alebo v mene právnickej osoby, ktorá si zriadi technický účet u prevádzkovateľa (NASES). Taktiež je možné pracovať s el. schránkou (eDesk), modulom dlhodobého uchovávania registratúrnych záznamov (MDURZ), centrálnou úradnou tabuľou (CUET), využívať služby el. pečatenia a informatívneho overovania el. podpisov (CEP).
6 |
7 | ## Dokumentácia
8 |
9 | - [Inštalačná príručka](INSTALL.md)
10 | - [Špecifikácia API](https://generator3.swagger.io/index.html?url=https://slovensko-sk-api.ekosystem.slovensko.digital/openapi.yaml)
11 |
12 | ## Ďalšie služby
13 |
14 | - [Komerčná podpora, platený vývoj a konzultačné služby](https://ekosystem.slovensko.digital/sluzby/slovensko-sk-api)
15 | - [Ostatné služby a produkty Slovensko.Digital](https://ekosystem.slovensko.digital)
16 |
17 | ## Licencia
18 |
19 | [European Union Public License v. 1.2](LICENSE)
20 |
21 | ## Autori projektu
22 |
23 | **Občianske združenie Slovensko.Digital** v spolupráci s CRYSTAL CONSULTING, s.r.o. a WEBY GROUP, s.r.o.
24 |
--------------------------------------------------------------------------------
/doc/templates/docker-compose.with_eform_sync.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | postgres:
5 | image: postgres:12-alpine
6 | volumes:
7 | - postgres:/var/lib/postgresql/data
8 |
9 | redis:
10 | image: redis:5-alpine
11 | volumes:
12 | - redis:/data
13 |
14 | web:
15 | image: ghcr.io/slovensko-digital/slovensko-sk-api:latest
16 | volumes:
17 | - ./security:/app/security
18 | ports:
19 | - 3000:3000
20 | depends_on:
21 | - postgres
22 | - redis
23 | env_file:
24 | - .env
25 | environment:
26 | DATABASE_URL: postgres://postgres:postgres@postgres:5432/slovensko-sk-api
27 | REDIS_URL: redis://redis:6379
28 |
29 | worker:
30 | image: ghcr.io/slovensko-digital/slovensko-sk-api:latest
31 | volumes:
32 | - ./security:/app/security
33 | depends_on:
34 | - postgres
35 | - redis
36 | env_file:
37 | - .env
38 | environment:
39 | DATABASE_URL: postgres://postgres:postgres@postgres:5432/slovensko-sk-api
40 | REDIS_URL: redis://redis:6379
41 | command: bundle exec rake jobs:work
42 |
43 | clock:
44 | image: ghcr.io/slovensko-digital/slovensko-sk-api:latest
45 | volumes:
46 | - ./security:/app/security
47 | depends_on:
48 | - postgres
49 | - redis
50 | env_file:
51 | - .env
52 | environment:
53 | DATABASE_URL: postgres://postgres:postgres@postgres:5432/slovensko-sk-api
54 | REDIS_URL: redis://redis:6379
55 | command: bundle exec clockwork config/clock.rb
56 |
57 | volumes:
58 | postgres:
59 | redis:
60 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/ws-techcert.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure public file server for tests with Cache-Control for performance.
16 | config.public_file_server.enabled = true
17 | config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{1.hour.to_i}" }
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Print deprecation notices to the stderr.
30 | config.active_support.deprecation = :stderr
31 |
32 | # Raises error for missing translations.
33 | config.action_view.raise_on_missing_translations = true
34 | end
35 |
--------------------------------------------------------------------------------
/spec/factories/form_templates.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :form_template do
3 | identifier { 'App.GeneralAgenda' }
4 | version_major { 1 }
5 | version_minor { 9 }
6 | end
7 |
8 | factory :form_template_related_document do
9 | form_template
10 | language { 'sk' }
11 | document_type { 'CLS_F_XSD_EDOC' }
12 | data { '' }
13 |
14 | trait :general_agenda_xsd_schema do
15 | association :form_template, identifier: 'App.GeneralAgenda', version_major: 1, version_minor: 9
16 | data do
17 | <<~HEREDOC
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | HEREDOC
36 | end
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/ws-onbehalf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/egov_application_general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3.0
4 |
5 |
6 | EGOV_APPLICATION
7 | App.GeneralAgenda
8 | 1.9
9 | af63e546-343c-4fd2-b6b2-04414da997b7
10 | 528014ec-1b83-4e86-ac2b-fbfd532cb55f
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | af63e546-343c-4fd2-b6b2-04414da997b7
19 | ico://sk/6501017042
20 | ico://sk/8311237188
21 | App.GeneralAgenda
22 | Všeobecná agenda
23 |
24 |
25 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/edesk_save_application_to_drafts_general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3.0
4 |
5 |
6 | EDESK_SAVE_APPLICATION_TO_DRAFTS
7 | App.GeneralAgenda
8 | 1.9
9 | af63e546-343c-4fd2-b6b2-04414da997b7
10 | 528014ec-1b83-4e86-ac2b-fbfd532cb55f
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | af63e546-343c-4fd2-b6b2-04414da997b7
19 | ico://sk/6501017042
20 | ico://sk/8311237188
21 | App.GeneralAgenda
22 | Všeobecná agenda
23 |
24 |
25 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/edesk_save_application_to_outbox_general_agenda.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3.0
4 |
5 |
6 | EDESK_SAVE_APPLICATION_TO_OUTBOX
7 | App.GeneralAgenda
8 | 1.9
9 | af63e546-343c-4fd2-b6b2-04414da997b7
10 | 528014ec-1b83-4e86-ac2b-fbfd532cb55f
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | af63e546-343c-4fd2-b6b2-04414da997b7
19 | ico://sk/6501017042
20 | ico://sk/8311237188
21 | App.GeneralAgenda
22 | Všeobecná agenda
23 |
24 |
25 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Do not eager load code on boot.
10 | config.eager_load = false
11 |
12 | # Show full error reports.
13 | config.consider_all_requests_local = true
14 |
15 | # Enable/disable caching. By default caching is disabled.
16 | # Run rails dev:cache to toggle caching.
17 | if Rails.root.join('tmp', 'caching-dev.txt').exist?
18 | config.action_controller.perform_caching = true
19 | config.cache_store = :memory_store
20 | config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{2.days.to_i}" }
21 | else
22 | config.action_controller.perform_caching = false
23 | config.cache_store = :null_store
24 | end
25 |
26 | # Print deprecation notices to the Rails logger.
27 | config.active_support.deprecation = :log
28 |
29 | # Raise an error on page load if there are pending migrations.
30 | config.active_record.migration_error = :page_load
31 |
32 | # Highlight code that triggered database queries in logs.
33 | config.active_record.verbose_query_logs = true
34 |
35 | # Raises error for missing translations
36 | config.action_view.raise_on_missing_translations = true
37 |
38 | # Use an evented file watcher to asynchronously detect changes in source code,
39 | # routes, locales, etc. This feature depends on the listen gem.
40 | config.file_watcher = ActiveSupport::EventedFileUpdateChecker
41 | end
42 |
--------------------------------------------------------------------------------
/spec/support/sktalk_matchers.rb:
--------------------------------------------------------------------------------
1 | # TODO wrap matchers in module?
2 | # TODO add proper #failure_message for all matchers
3 | # TODO consider chained setters https://relishapp.com/rspec/rspec-expectations/v/3-9/docs/custom-matchers/define-matcher-with-fluent-interface#chained-setter
4 |
5 | RSpec::Matchers.define :sktalk_message do
6 | match do |message|
7 | message.is_a?(sk.gov.sktalkmessage.SKTalkMessage) &&
8 | (@class ? message.header.message_info.clazz == @class : true)
9 | end
10 |
11 | chain :saving_to_outbox do
12 | @class = 'EDESK_SAVE_APPLICATION_TO_OUTBOX'
13 | end
14 |
15 | chain :with_class, :class
16 |
17 | # TODO add chains here and remove all matchers below
18 | end
19 |
20 | RSpec::Matchers.define :sktalk_message_of_class do |clazz|
21 | match { |message| message.header.message_info.clazz = clazz.to_s }
22 | end
23 |
24 | RSpec::Matchers.define :sktalk_message_in_correlation_with do |id|
25 | match { |message| message.header.message_info.correlation_id = id.to_s }
26 | end
27 |
28 | RSpec::Matchers.define :sktalk_message_referencing do |id|
29 | match { |message| message.header.message_info.reference_id = id.to_s }
30 | end
31 |
32 | RSpec::Matchers.define :sktalk_message_containing do |value, at:, **options|
33 | match { |message| Nokogiri::XML::Document.wrap(message.body.any.first.owner_document).at_xpath(at, options).content == value }
34 | end
35 |
36 | RSpec::Matchers.define :sktalk_message_matching do |content|
37 | match do |expected|
38 | actual = SktalkMessages.from_xml(content)
39 | actual.header.message_info.clazz = @class if @class
40 |
41 | SktalkMessages.to_xml(expected) == SktalkMessages.to_xml(actual)
42 | end
43 |
44 | chain :saving_to_outbox do
45 | @class = 'EDESK_SAVE_APPLICATION_TO_OUTBOX'
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/app/controllers/sktalk_controller.rb:
--------------------------------------------------------------------------------
1 | # TODO validate form version status in #before_action
2 | # TODO validate input message against XSD in #before_action
3 |
4 | class SktalkController < ApiController
5 | include SktalkReceiving
6 |
7 | before_action { authenticate(allow_sub: true, allow_obo_token: true, require_obo_token_scope: action_scope) }
8 |
9 | before_action(except: :prepare_for_later_receive) { params.require(:message) }
10 |
11 | rescue_from(SktalkReceiver::ReceiveMessageFormatError) { render_bad_request(:invalid, :message) }
12 | rescue_from(SktalkReceiver::ReceiveAsSaveToFolderError) { render_unprocessable_entity(:received_as_being_saved_to_folder) }
13 |
14 | PREPARE_FOR_LATER_RECEIVE_SCOPES = %w[sktalk/receive sktalk/receive_and_save_to_outbox sktalk/save_to_outbox]
15 |
16 | def receive
17 | render json: { receive_result: sktalk_receiver(upvs_identity).receive(params[:message]) }
18 | end
19 |
20 | def receive_and_save_to_outbox
21 | render_sktalk_results sktalk_receiver(upvs_identity).receive_and_save_to_outbox!(params[:message])
22 | end
23 |
24 | def save_to_outbox
25 | render json: { save_to_outbox_result: sktalk_receiver(upvs_identity).save_to_outbox(params[:message]) }
26 | end
27 |
28 | # allow sending invalid sktalk to cache token for SSO
29 | def prepare_for_later_receive(message_builder: SktalkMessageBuilder)
30 | message = message_builder.new(class: 'EGOV_APPLICATION', posp_id: 'App.GeneralAgenda', posp_version: '1.9')
31 |
32 | sktalk_receiver(upvs_identity).receive(message.to_xml)
33 |
34 | long_lasting_obo_token = Environment.api_token_authenticator.generate_long_lasting_token(authenticity_token, PREPARE_FOR_LATER_RECEIVE_SCOPES)
35 |
36 | render status: :ok, json: {"token": long_lasting_obo_token}
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/spec/fixtures/ez/eform/get_related_document_by_type_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48eHM6c2NoZW1hIGVsZW1lbnRGb3JtRGVmYXVsdD0icXVhbGlmaWVkIiBhdHRyaWJ1dGVGb3JtRGVmYXVsdD0idW5xdWFsaWZpZWQiIHhtbG5zOnhzPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYSIgdGFyZ2V0TmFtZXNwYWNlPSJodHRwOi8vc2NoZW1hcy5nb3Yuc2svZm9ybS9BcHAuR2VuZXJhbEFnZW5kYS8xLjkiIHhtbG5zPSJodHRwOi8vc2NoZW1hcy5nb3Yuc2svZm9ybS9BcHAuR2VuZXJhbEFnZW5kYS8xLjkiPg0KPHhzOnNpbXBsZVR5cGUgbmFtZT0idGV4dEFyZWEiPg0KPHhzOnJlc3RyaWN0aW9uIGJhc2U9InhzOnN0cmluZyI+DQo8L3hzOnJlc3RyaWN0aW9uPg0KPC94czpzaW1wbGVUeXBlPg0KPHhzOnNpbXBsZVR5cGUgbmFtZT0ibWVubyI+DQo8eHM6cmVzdHJpY3Rpb24gYmFzZT0ieHM6c3RyaW5nIj4NCjwveHM6cmVzdHJpY3Rpb24+DQo8L3hzOnNpbXBsZVR5cGU+DQoNCg0KPHhzOmVsZW1lbnQgbmFtZT0iR2VuZXJhbEFnZW5kYSI+DQo8eHM6Y29tcGxleFR5cGU+DQo8eHM6c2VxdWVuY2U+DQo8eHM6ZWxlbWVudCBuYW1lPSJzdWJqZWN0IiB0eXBlPSJtZW5vIiBtaW5PY2N1cnM9IjAiIG5pbGxhYmxlPSJ0cnVlIiAvPg0KPHhzOmVsZW1lbnQgbmFtZT0idGV4dCIgdHlwZT0idGV4dEFyZWEiIG1pbk9jY3Vycz0iMCIgbmlsbGFibGU9InRydWUiIC8+DQo8L3hzOnNlcXVlbmNlPg0KPC94czpjb21wbGV4VHlwZT4NCjwveHM6ZWxlbWVudD4NCjwveHM6c2NoZW1hPg0KDQo=
7 |
8 | Xsd výsledného eDoc (elektronický dokument) xml
9 | schema.xsd
10 | sk
11 | CLS_F_XSD_EDOC
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/spec/support/upvs_object_matchers.rb:
--------------------------------------------------------------------------------
1 | # TODO use #alias_matcher instead of #alias once RubyMine starts to recognize aliases on click-to-reference
2 |
3 | module UpvsObjectMatchers
4 | extend RSpec::Matchers::DSL
5 |
6 | matcher :be_upvs_object do |expected|
7 | match do |actual|
8 | expected_as_struct = UpvsObjects.to_structure(expected)
9 | actual_as_struct = UpvsObjects.to_structure(actual)
10 |
11 | warn 'WARNING: Comparing two blank UPVS objects is unsafe' if expected_as_struct.blank? && actual_as_struct.blank?
12 |
13 | result = expected.instance_of?(actual.class) && values_match?(expected_as_struct, actual_as_struct)
14 |
15 | unless result
16 | @expected_formatted = RSpec::Support::ObjectFormatter.format(expected)
17 | @actual_formatted = RSpec::Support::ObjectFormatter.format(actual)
18 |
19 | @expected_as_array = [expected_as_struct]
20 | @actual = actual_as_struct
21 | end
22 |
23 | result
24 | end
25 |
26 | def failure_message
27 | "\nexpected: #{@expected_formatted}\n got: #{@actual_formatted}\n\n(#{failure_message_note})\n"
28 | end
29 |
30 | def failure_message_when_negated
31 | "\nexpected: value != #{@expected_formatted}\n got: #{@actual_formatted}\n\n(#{failure_message_note})\n"
32 | end
33 |
34 | def failure_message_note
35 | 'compared using Upvs#to_struct(expected) == Upvs#to_struct(actual)'
36 | end
37 |
38 | diffable
39 | end
40 |
41 | def usr_service_call_args(file)
42 | object = upvs_object_from_xml(file)
43 | [object.service_class, be_upvs_object(object.service_parameter.value)]
44 | end
45 |
46 | alias usr_args usr_service_call_args
47 |
48 | def be_usr_service_result(file)
49 | be_upvs_object(usr_service_result(file))
50 | end
51 | end
52 |
53 | RSpec.configure do |config|
54 | config.include UpvsObjectMatchers
55 | end
56 |
--------------------------------------------------------------------------------
/app/controllers/eform_controller.rb:
--------------------------------------------------------------------------------
1 | class EformController < ApiController
2 | before_action { authenticate(allow_sub: true) }
3 |
4 | rescue_from(ActiveRecord::RecordNotFound) { render_not_found(:template) }
5 | rescue_from(Nokogiri::XML::SyntaxError) { render_bad_request(:invalid, :form) }
6 |
7 | rescue_from_soap_fault { |code| render_not_found(:template) if code == '06000798' }
8 |
9 | def status
10 | identifier, version = params.require(:identifier), params.require(:version)
11 |
12 | render json: { status: eform_service(upvs_identity).fetch_form_template_status(identifier, version) }
13 | end
14 |
15 | def validate
16 | identifier, version, form = params.require(:identifier), params.require(:version), params.require(:form)
17 |
18 | # TODO remove -> see notes in FormTemplate model
19 | version_major, version_minor = version.split('.', 2)
20 |
21 | template = FormTemplate.find_by!(identifier: identifier, version_major: version_major, version_minor: version_minor)
22 |
23 | if template.xsd_schema.present?
24 | schema = Nokogiri::XML::Schema(template.xsd_schema)
25 | document = Nokogiri::XML(form) { |config| config.strict }
26 |
27 | errors = schema.validate(document)
28 |
29 | render json: { valid: errors.none?, errors: errors.map(&:message).presence }.compact
30 | else
31 | render_not_found(:schema)
32 | end
33 | end
34 |
35 | def form_template_related_document
36 | identifier, version, type = params.require(:identifier), params.require(:version), params.require(:type)
37 |
38 | # TODO remove -> see notes in FormTemplate model
39 | version_major, version_minor = *version.split('.', 2)
40 |
41 | document = FormTemplate.find_by!(identifier: identifier, version_major: version_major, version_minor: version_minor).related_document(type)
42 |
43 | document.present? ? (render status: :ok, json: { "document": Base64.encode64(document) }) : render_not_found(:template_related_document)
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/app/views/iam/identities/_natural_person.json.jbuilder:
--------------------------------------------------------------------------------
1 | # TODO
2 | # natural_person.pco
3 |
4 | json.type { json.partial! 'enumeration', value: natural_person.identity_type_detail }
5 |
6 | json.partial! 'natural_person_name', natural_person: natural_person.person_name
7 | json.alternative_names natural_person.alternative_name
8 |
9 | json.gender { json.partial! 'enumeration', value: natural_person.sex }
10 |
11 | json.marital_status natural_person.marital_status
12 | json.vital_status { json.partial! 'enumeration', value: natural_person.death&.status }
13 |
14 | json.nationality { json.partial! 'enumeration', value: natural_person.nationality }
15 | json.occupation { json.partial! 'enumeration', value: natural_person.occupation }
16 |
17 | # TODO
18 | # json.bank_connections natural_person.bank_connection do |c|
19 | # end
20 |
21 | # TODO
22 | # json.related_persons natural_person.related_person do |c|
23 | # end
24 |
25 | json.birth do
26 | if natural_person.birth
27 | json.date natural_person.birth.date_of_birth.to_s.in_time_zone.to_date
28 | json.country { json.partial! 'enumeration', value: natural_person.birth.country }
29 | json.district { json.partial! 'enumeration', value: natural_person.birth.county }
30 | json.municipality { json.partial! 'enumeration', value: natural_person.birth.municipality }
31 | json.part natural_person.birth.district
32 | else
33 | json.nil!
34 | end
35 | end
36 |
37 | json.death do
38 | if natural_person.death
39 | json.date natural_person.death.date_of_death.to_s.in_time_zone.to_date
40 | json.country { json.partial! 'enumeration', value: natural_person.death.country }
41 | json.district { json.partial! 'enumeration', value: natural_person.death.county }
42 | json.municipality { json.partial! 'enumeration', value: natural_person.death.municipality }
43 | json.part natural_person.death.district
44 | else
45 | json.nil!
46 | end
47 | end
48 |
49 | json.updated_on natural_person.death&.date_of_status_change.to_s.to_date
50 |
--------------------------------------------------------------------------------
/app/views/iam/_natural_person.json.jbuilder:
--------------------------------------------------------------------------------
1 | # TODO
2 | # natural_person.pco
3 |
4 | json.type { json.partial! 'iam/enumeration', value: natural_person.identity_type_detail }
5 |
6 | json.partial! 'iam/natural_person_name', natural_person: natural_person.person_name
7 | json.alternative_names natural_person.alternative_name
8 |
9 | json.gender { json.partial! 'iam/enumeration', value: natural_person.sex }
10 |
11 | json.marital_status natural_person.marital_status
12 | json.vital_status { json.partial! 'iam/enumeration', value: natural_person.death&.status }
13 |
14 | json.nationality { json.partial! 'iam/enumeration', value: natural_person.nationality }
15 | json.occupation { json.partial! 'iam/enumeration', value: natural_person.occupation }
16 |
17 | # TODO
18 | # json.bank_connections natural_person.bank_connection do |c|
19 | # end
20 |
21 | # TODO
22 | # json.related_persons natural_person.related_person do |c|
23 | # end
24 |
25 | json.birth do
26 | if natural_person.birth
27 | json.date natural_person.birth.date_of_birth.to_s.in_time_zone.to_date
28 | json.country { json.partial! 'iam/enumeration', value: natural_person.birth.country }
29 | json.district { json.partial! 'iam/enumeration', value: natural_person.birth.county }
30 | json.municipality { json.partial! 'iam/enumeration', value: natural_person.birth.municipality }
31 | json.part natural_person.birth.district
32 | else
33 | json.nil!
34 | end
35 | end
36 |
37 | json.death do
38 | if natural_person.death
39 | json.date natural_person.death.date_of_death.to_s.in_time_zone.to_date
40 | json.country { json.partial! 'iam/enumeration', value: natural_person.death.country }
41 | json.district { json.partial! 'iam/enumeration', value: natural_person.death.county }
42 | json.municipality { json.partial! 'iam/enumeration', value: natural_person.death.municipality }
43 | json.part natural_person.death.district
44 | else
45 | json.nil!
46 | end
47 | end
48 |
49 | json.updated_on natural_person.death&.date_of_status_change.to_s.to_date
50 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | scope format: false do
3 | namespace :administration do
4 | resources :certificates, only: [:create, :show, :destroy]
5 |
6 | namespace :eform do
7 | get :synchronize
8 | end
9 | end
10 |
11 | get :health, to: 'health#index'
12 |
13 | if UpvsEnvironment.sso_support?
14 | get :login, to: 'upvs#login'
15 | get :logout, to: 'upvs#logout'
16 |
17 | scope 'auth/saml', as: :upvs, controller: :upvs do
18 | get :login
19 | get :logout
20 |
21 | post :callback
22 | end
23 | end
24 |
25 | if UpvsEnvironment.obo_support?
26 | post :login, to: 'upvs#login_with_saml_assertion'
27 | end
28 |
29 | scope :api do
30 | namespace :cep do
31 | post :signatures_info
32 | end
33 |
34 | namespace :edesk do
35 | resources :folders, only: [:index] do
36 | resources :messages, only: [:index]
37 | end
38 |
39 | resources :messages, only: [:show, :update, :destroy] do
40 | collection do
41 | get :search
42 | end
43 |
44 | member do
45 | post :authorize
46 | end
47 | end
48 | end
49 |
50 | namespace :eform do
51 | get :status
52 | post :validate
53 | get :form_template_related_document
54 | end
55 |
56 | namespace :iam do
57 | resources :identities, only: [:show] do
58 | collection do
59 | post :search
60 | end
61 | end
62 | end
63 |
64 | namespace :sktalk do
65 | post :receive
66 | post :receive_and_save_to_outbox
67 | post :save_to_outbox
68 | get :prepare_for_later_receive
69 | end
70 |
71 | if UpvsEnvironment.obo_support?
72 | namespace :upvs do
73 | get :assertion
74 | get :identity
75 | end
76 | end
77 | end
78 |
79 | match '500', to: 'errors#internal_server_error', via: :all
80 | end
81 | end
82 |
--------------------------------------------------------------------------------
/spec/services/upvs_environment_spec.rb:
--------------------------------------------------------------------------------
1 | require 'rails_helper'
2 |
3 | RSpec.describe UpvsEnvironment do
4 | subject { described_class }
5 |
6 | pending '.upvs_properties'
7 |
8 | describe '.upvs_proxy' do
9 | before(:example) { allow(UpvsProxy).to receive(:new).and_wrap_original { Object.new }}
10 |
11 | before(:example) { UpvsEnvironment.upvs_proxy_cache.invalidate_all }
12 |
13 | it 'returns same proxy object in the first 120 minutes' do
14 | travel_to Time.now
15 |
16 | u1 = subject.upvs_proxy(sub: 'test')
17 |
18 | travel_to 120.minutes.from_now - 0.1.seconds
19 |
20 | u2 = subject.upvs_proxy(sub: 'test')
21 |
22 | expect(u1).to equal(u2)
23 | end
24 |
25 | it 'returns new proxy object on or after 120 minutes' do
26 | travel_to Time.now
27 |
28 | u1 = subject.upvs_proxy(sub: 'test')
29 |
30 | travel_to 120.minutes.from_now
31 |
32 | u2 = subject.upvs_proxy(sub: 'test')
33 |
34 | expect(u1).not_to equal(u2)
35 | end
36 |
37 | pending 'with OBO identifier'
38 |
39 | context 'with OBO assertion' do
40 | let(:assertion) { file_fixture('oam/sso_response_success_assertion.xml').read.strip }
41 |
42 | it 'returns same proxy object in the first 120 minutes' do
43 | travel_to Time.now
44 |
45 | u1 = subject.upvs_proxy(sub: 'test', obo: assertion)
46 |
47 | travel_to 120.minutes.from_now - 0.1.seconds
48 |
49 | u2 = subject.upvs_proxy(sub: 'test', obo: assertion)
50 |
51 | expect(u1).to equal(u2)
52 | end
53 |
54 | it 'returns new proxy object on or after 120 minutes' do
55 | travel_to Time.now
56 |
57 | u1 = subject.upvs_proxy(sub: 'test', obo: assertion)
58 |
59 | travel_to 120.minutes.from_now
60 |
61 | u2 = subject.upvs_proxy(sub: 'test', obo: assertion)
62 |
63 | expect(u1).not_to equal(u2)
64 | end
65 | end
66 | end
67 |
68 | pending '.obo_support?'
69 |
70 | pending '.sso_support?'
71 |
72 | pending '.sso_settings'
73 |
74 | pending '.sso_proxy_subject'
75 | end
76 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: alpine:latest
2 |
3 | variables:
4 | DOCKER_DRIVER: overlay2
5 | DOCKER_BUILDKIT: 0
6 | AUTO_DEVOPS_BUILD_CACHE: registry
7 | AUTO_DEPLOY_IMAGE_VERSION: 'v2.47.0'
8 |
9 | stages:
10 | - build
11 | - deploy
12 |
13 | include:
14 | - template: Jobs/Build.gitlab-ci.yml
15 |
16 | staging:
17 | extends: .auto-deploy
18 | stage: deploy
19 | script:
20 | - auto-deploy check_kube_domain
21 | - auto-deploy download_chart
22 | - auto-deploy use_kube_context || true
23 | - auto-deploy ensure_namespace
24 | - auto-deploy create_secret
25 | - auto-deploy deploy
26 | environment:
27 | name: staging
28 | url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
29 | rules:
30 | - if: '($CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == "") && ($KUBECONFIG == null || $KUBECONFIG == "")'
31 | when: never
32 | - when: always
33 |
34 | production:
35 | extends: .auto-deploy
36 | stage: deploy
37 | script:
38 | - auto-deploy check_kube_domain
39 | - auto-deploy download_chart
40 | - auto-deploy use_kube_context || true
41 | - auto-deploy ensure_namespace
42 | - auto-deploy create_secret
43 | - auto-deploy deploy
44 | - auto-deploy persist_environment_url
45 | environment:
46 | name: production
47 | url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
48 | artifacts:
49 | paths: [environment_url.txt]
50 | when: always
51 | allow_failure: false
52 | rules:
53 | - if: '($CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == "") && ($KUBECONFIG == null || $KUBECONFIG == "")'
54 | when: never
55 | - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
56 | when: manual
57 |
58 | # The latest build job generates a dotenv report artifact with a CI_APPLICATION_TAG
59 | # that also includes the image digest. This configures Auto Deploy to receive
60 | # this artifact and use the updated CI_APPLICATION_TAG for deployments.
61 | .auto-deploy:
62 | image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${AUTO_DEPLOY_IMAGE_VERSION}"
63 | dependencies: [build]
64 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/ws-onbehalf-id.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/doc/templates/podaas_fix.metadata.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/chart/templates/db-migrate-hook.yaml:
--------------------------------------------------------------------------------
1 | {{- if .Values.application.migrateCommand -}}
2 | apiVersion: batch/v1
3 | kind: Job
4 | metadata:
5 | name: {{ template "trackableappname" . }}-db-migrate
6 | labels:
7 | {{ include "sharedlabels" . | indent 4 }}
8 | annotations:
9 | "helm.sh/hook": pre-upgrade
10 | "helm.sh/hook-delete-policy": before-hook-creation
11 | "helm.sh/hook-weight": "0"
12 | spec:
13 | template:
14 | metadata:
15 | labels:
16 | app: {{ template "appname" . }}
17 | release: {{ .Release.Name }}
18 | spec:
19 | restartPolicy: Never
20 | imagePullSecrets:
21 | {{ toYaml .Values.image.secrets | indent 10 }}
22 | containers:
23 | - name: {{ .Chart.Name }}
24 | image: {{ template "imagename" . }}
25 | command: ["/bin/sh"]
26 | args: ["-c", "{{ .Values.application.migrateCommand }}"]
27 | imagePullPolicy: {{ .Values.image.pullPolicy }}
28 | {{- if .Values.persistence.enabled }}
29 | volumeMounts:
30 | {{- range $volume := .Values.persistence.volumes }}
31 | - name: {{ $volume.name | quote }}
32 | mountPath: {{ $volume.mount.path | quote }}
33 | {{- if $volume.mount.subPath }}
34 | subPath: {{ $volume.mount.subPath | quote }}
35 | {{- end }}
36 | {{- end }}
37 | {{- end }}
38 | {{- if .Values.application.secretName }}
39 | envFrom:
40 | - secretRef:
41 | name: {{ .Values.application.secretName }}
42 | {{- end }}
43 | env:
44 | {{- if .Values.application.database_url }}
45 | - name: DATABASE_URL
46 | value: {{ .Values.application.database_url | quote }}
47 | {{- end }}
48 | - name: GITLAB_ENVIRONMENT_NAME
49 | value: {{ .Values.gitlab.envName | quote }}
50 | - name: GITLAB_ENVIRONMENT_URL
51 | value: {{ .Values.gitlab.envURL | quote }}
52 | {{- if .Values.persistence.enabled }}
53 | {{- $context := . }}
54 | volumes:
55 | {{- range $volume := .Values.persistence.volumes }}
56 | - name: {{ $volume.name | quote }}
57 | persistentVolumeClaim:
58 | {{ $args := dict "context" $context "name" $volume.name }}
59 | claimName: {{ template "pvcName" $args }}
60 | {{- end }}
61 | {{- end }}
62 | {{- end -}}
--------------------------------------------------------------------------------
/app/controllers/concerns/edesk_rescuable.rb:
--------------------------------------------------------------------------------
1 | module EdeskRescuable
2 | extend ActiveSupport::Concern
3 |
4 | included do
5 | faults = [
6 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceGetFoldersEDeskFaultFaultFaultMessage,
7 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceGetMessagesEDeskFaultFaultFaultMessage,
8 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceGetMessageEDeskFaultFaultFaultMessage,
9 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceDeleteMessageEDeskFaultFaultFaultMessage,
10 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceMoveMessageEDeskFaultFaultFaultMessage,
11 | sk.gov.schemas.edesk.eksservice._1.IEKSServiceConfirmNotificationReportEDeskFaultFaultFaultMessage
12 | ]
13 |
14 | rescue_from *faults do |error|
15 | logger.debug { error.full_message }
16 |
17 | java_import org.datacontract.schemas._2004._07.anasoft_edesk.FaultCodes
18 |
19 | case error.fault_info.code
20 | when FaultCodes::E_DESK_INACTIVE then render_conflict(:inactive_box)
21 | when FaultCodes::E_DESK_PERMISSION_DENIED
22 | case error.message
23 | when /schránk[ay]/i then render_not_found(:box)
24 | when /priečinok/i then render_not_found(:folder)
25 | when /správ[au]/i then render_not_found(:message)
26 | else
27 | internal_server_error
28 | end
29 | when FaultCodes::E_DESK_NOT_EXIST then render_not_found(:box)
30 | when FaultCodes::FOLDER_NOT_EXIST then render_not_found(:folder)
31 | when FaultCodes::MESSAGE_NOT_EXIST then render_not_found(:message)
32 | when FaultCodes::MESSAGE_NOT_DELIVERABLE then render_unprocessable_entity(:notification_report_already_confirmed)
33 | when FaultCodes::INCORRECT_CONFIRM_REQUEST
34 | case error.message
35 | when /Správa \d+ nemá Class ED_DELIVERY_NOTIFICATION, a teda nie je notifikačná doručenka./ then render_unprocessable_entity(:authorize_non_notification_report)
36 | when /Správa \d+ neexistuje./ then render_not_found(:message)
37 | when 'Nie ste adresátom správy a preto ju nemáte oprávnenie prevziať.' then render_not_found(:message)
38 | else
39 | internal_server_error
40 | end
41 | else
42 | render_service_unavailable_error(:ekr)
43 | end
44 | end
45 | end
46 | end
47 |
--------------------------------------------------------------------------------
/app/services/eform_service.rb:
--------------------------------------------------------------------------------
1 | class EformService
2 | def initialize(proxy)
3 | @upvs = proxy
4 | end
5 |
6 | def fetch_all_form_template_ids
7 | service = ServiceClassEnum::EFORM_FINDFORMTEMPLATES_SOAP_V_1_0
8 | request = factory.create_find_form_templates_req
9 |
10 | @upvs.ez.call_service(service, request).form_templates.value.form_template_id
11 | end
12 |
13 | def fetch_form_template_status(identifier, version)
14 | service = ServiceClassEnum::EFORM_GETFORMTEMPLATESTATUS_SOAP_V_1_0
15 | request = factory.create_get_form_template_status_req
16 |
17 | request.form_template = factory.create_get_form_template_status_req_form_template(form_template_id(identifier, version))
18 |
19 | @upvs.ez.call_service(service, request).form_status.value
20 | end
21 |
22 | # TODO rename - this reads as "fetch XML schema definition schema"
23 | def fetch_form_related_document(identifier, version, type)
24 | service = ServiceClassEnum::EFORM_GETRELATEDDOCUMENTBYTYPE_SOAP_V_1_0
25 | request = factory.create_get_related_document_by_type_req
26 |
27 | request.form_template = factory.create_get_related_document_by_type_req_form_template(form_template_id(identifier, version))
28 | request.related_document_type = factory.create_get_related_document_by_type_req_related_document_type(type)
29 | request.related_document_language = factory.create_get_related_document_by_type_req_related_document_language('sk')
30 |
31 | @upvs.ez.call_service(service, request).related_document.value
32 | end
33 |
34 | private
35 |
36 | mattr_reader :factory, default: sk.gov.schemas.servicebusserviceprovider.ness.eformprovider._1.ObjectFactory.new
37 |
38 | java_import sk.gov.schemas.servicebus.service._1.ServiceClassEnum
39 |
40 | def form_template_id(identifier, version)
41 | major, minor = version.split('.', 2).map { |n| Integer(n, 10) }
42 |
43 | form_template_id = factory.create_form_template_id
44 | form_template_id.identifier = factory.create_form_template_id_identifier(identifier)
45 |
46 | form_version = factory.create_eform_version
47 | form_version.major = major
48 | form_version.minor = minor
49 |
50 | form_template_id.version = factory.create_form_template_id_version(form_version)
51 | form_template_id
52 | end
53 |
54 | private_constant *constants(false)
55 | end
56 |
--------------------------------------------------------------------------------
/spec/jobs/download_form_template_job_spec.rb:
--------------------------------------------------------------------------------
1 | # TODO jobs should not be STS type specs -> eForm service is covered as STS spec in spec/services
2 |
3 | require 'rails_helper'
4 |
5 | RSpec.describe DownloadFormTemplateJob, :sts do
6 | before(:example) { stub_const('ENV', ENV.merge('EFORM_SYNC_SUBJECT' => corporate_body_subject)) }
7 |
8 | describe '#perform' do
9 | let(:identifier) { 'App.GeneralAgenda' }
10 |
11 | it 'downloads form template' do
12 | expect { subject.perform(identifier, 1, 9) }.to change { FormTemplate.count }.by(1)
13 |
14 | form_template = FormTemplate.first
15 |
16 | expect(form_template).to have_attributes(identifier: identifier, version_major: 1, version_minor: 9)
17 | end
18 |
19 | it 'downloads form schema' do
20 | expect { subject.perform(identifier, 1, 9) }.to change { FormTemplateRelatedDocument.count }.by(1)
21 |
22 | form_template = FormTemplate.first
23 | form_schema = FormTemplateRelatedDocument.first
24 |
25 | expect(form_schema).to have_attributes(form_template: form_template, document_type: 'CLS_F_XSD_EDOC', language: 'sk')
26 | end
27 |
28 | context 'with form template already present' do
29 | pending 'updates form template'
30 |
31 | pending 'updates form schema'
32 | end
33 |
34 | context 'with form template not found' do
35 | let(:identifier) { 'App.UnknownAgenda' }
36 |
37 | it 'does not download form template' do
38 | expect { suppress(javax.xml.ws.soap.SOAPFaultException) { subject.perform(identifier, 1, 0) }}.not_to change { FormTemplate.count }
39 | end
40 |
41 | it 'raises error' do
42 | expect { subject.perform(identifier, 1, 0) }.to raise_soap_fault_exception('06000798')
43 | end
44 | end
45 |
46 | context 'with form schema not found' do
47 | let(:identifier) { '36126624.Rozhodnutie.sk' }
48 |
49 | it 'downloads form template' do
50 | expect { subject.perform(identifier, 1, 8) }.to change { FormTemplate.count }.by(1)
51 | end
52 |
53 | it 'does not download form schema' do
54 | expect { subject.perform(identifier, 1, 8) }.not_to change { FormTemplateRelatedDocument.count }
55 | end
56 |
57 | it 'does not raise error' do
58 | expect { subject.perform(identifier, 1, 8) }.not_to raise_error
59 | end
60 | end
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/chart/test/templates/db_migrate_hook_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strings"
5 | "testing"
6 |
7 | "github.com/gruntwork-io/terratest/modules/helm"
8 | "github.com/gruntwork-io/terratest/modules/k8s"
9 | "github.com/gruntwork-io/terratest/modules/random"
10 | "github.com/stretchr/testify/require"
11 | appsV1 "k8s.io/api/apps/v1"
12 | coreV1 "k8s.io/api/core/v1"
13 | )
14 |
15 | func TestMigrateDatabaseUrlEnvironmentVariable(t *testing.T) {
16 | releaseName := "migrate-application-database-url-test"
17 |
18 | tcs := []struct {
19 | CaseName string
20 | Values map[string]string
21 | ExpectedDatabaseUrl string
22 | Template string
23 | }{
24 | {
25 | CaseName: "present-db-migrate",
26 | Values: map[string]string{
27 | "application.database_url": "PRESENT",
28 | "application.migrateCommand": "echo migrate",
29 | },
30 | ExpectedDatabaseUrl: "PRESENT",
31 | Template: "templates/db-migrate-hook.yaml",
32 | },
33 | {
34 | CaseName: "missing-db-migrate",
35 | Values: map[string]string{
36 | "application.migrateCommand": "echo migrate",
37 | },
38 | Template: "templates/db-migrate-hook.yaml",
39 | },
40 | }
41 |
42 | for _, tc := range tcs {
43 | t.Run(tc.CaseName, func(t *testing.T) {
44 |
45 | namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
46 |
47 | values := map[string]string{
48 | "gitlab.app": "auto-devops-examples/minimal-ruby-app",
49 | "gitlab.env": "prod",
50 | }
51 |
52 | mergeStringMap(values, tc.Values)
53 |
54 | options := &helm.Options{
55 | SetValues: values,
56 | KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
57 | }
58 |
59 | output, err := helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{tc.Template})
60 |
61 | if err != nil {
62 | t.Error(err)
63 | return
64 | }
65 |
66 | deployment := new(appsV1.Deployment)
67 | helm.UnmarshalK8SYaml(t, output, &deployment)
68 |
69 | if tc.ExpectedDatabaseUrl != "" {
70 | require.Contains(t, deployment.Spec.Template.Spec.Containers[0].Env, coreV1.EnvVar{Name: "DATABASE_URL", Value: tc.ExpectedDatabaseUrl})
71 | } else {
72 | for _, envVar := range deployment.Spec.Template.Spec.Containers[0].Env {
73 | require.NotEqual(t, "DATABASE_URL", envVar.Name)
74 | }
75 | }
76 | })
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/chart/test/templates/db_initialize_job_test.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "strings"
5 | "testing"
6 |
7 | "github.com/gruntwork-io/terratest/modules/helm"
8 | "github.com/gruntwork-io/terratest/modules/k8s"
9 | "github.com/gruntwork-io/terratest/modules/random"
10 | "github.com/stretchr/testify/require"
11 | appsV1 "k8s.io/api/apps/v1"
12 | coreV1 "k8s.io/api/core/v1"
13 | )
14 |
15 | func TestInitializeDatabaseUrlEnvironmentVariable(t *testing.T) {
16 | releaseName := "initialize-application-database-url-test"
17 |
18 | tcs := []struct {
19 | CaseName string
20 | Values map[string]string
21 | ExpectedDatabaseUrl string
22 | Template string
23 | }{
24 | {
25 | CaseName: "present-db-intialize",
26 | Values: map[string]string{
27 | "application.database_url": "PRESENT",
28 | "application.initializeCommand": "echo initialize",
29 | },
30 | ExpectedDatabaseUrl: "PRESENT",
31 | Template: "templates/db-initialize-job.yaml",
32 | },
33 | {
34 | CaseName: "missing-db-initialize",
35 | Values: map[string]string{
36 | "application.initializeCommand": "echo initialize",
37 | },
38 | Template: "templates/db-initialize-job.yaml",
39 | },
40 | }
41 |
42 | for _, tc := range tcs {
43 | t.Run(tc.CaseName, func(t *testing.T) {
44 |
45 | namespaceName := "minimal-ruby-app-" + strings.ToLower(random.UniqueId())
46 |
47 | values := map[string]string{
48 | "gitlab.app": "auto-devops-examples/minimal-ruby-app",
49 | "gitlab.env": "prod",
50 | }
51 |
52 | mergeStringMap(values, tc.Values)
53 |
54 | options := &helm.Options{
55 | SetValues: values,
56 | KubectlOptions: k8s.NewKubectlOptions("", "", namespaceName),
57 | }
58 |
59 | output, err := helm.RenderTemplateE(t, options, helmChartPath, releaseName, []string{tc.Template})
60 |
61 | if err != nil {
62 | t.Error(err)
63 | return
64 | }
65 |
66 | deployment := new(appsV1.Deployment)
67 | helm.UnmarshalK8SYaml(t, output, &deployment)
68 |
69 | if tc.ExpectedDatabaseUrl != "" {
70 | require.Contains(t, deployment.Spec.Template.Spec.Containers[0].Env, coreV1.EnvVar{Name: "DATABASE_URL", Value: tc.ExpectedDatabaseUrl})
71 | } else {
72 | for _, envVar := range deployment.Spec.Template.Spec.Containers[0].Env {
73 | require.NotEqual(t, "DATABASE_URL", envVar.Name)
74 | }
75 | }
76 | })
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/spec/support/authenticity_tokens.rb:
--------------------------------------------------------------------------------
1 | module AuthenticityTokens
2 | def self.fetch_key_pair(prefix, write_public_key: false)
3 | path = Rails.root.join('security', "#{prefix}_token_#{Rails.env}.private.pem")
4 | File.write(path, OpenSSL::PKey::RSA.new(2048).to_s) unless File.exist?(path)
5 | key_pair = OpenSSL::PKey::RSA.new(File.read(path))
6 |
7 | if write_public_key
8 | path = path.sub('private', 'public')
9 | File.write(path, key_pair.public_key.to_s) unless File.exist?(path)
10 | end
11 |
12 | key_pair
13 | end
14 |
15 | mattr_accessor :api_token_key_pair, default: fetch_key_pair(:api, write_public_key: true)
16 | mattr_accessor :obo_token_key_pair, default: fetch_key_pair(:obo)
17 |
18 | mattr_accessor :sso_response_file, default: 'oam/sso_response_success.xml'
19 | mattr_accessor :sso_response_issued_at, default: '2018-11-28T20:26:16Z'
20 |
21 | def api_token
22 | api_token_with_subject(nil)
23 | end
24 |
25 | def api_token_with_subject(subject = 'CIN-11190868', obo: nil, expires_in: 1.minute.from_now)
26 | payload = { sub: subject, exp: expires_in.to_i, jti: SecureRandom.uuid }
27 | payload[:obo] = obo if obo
28 | JWT.encode(payload, api_token_key_pair, 'RS256')
29 | end
30 |
31 | def api_obo_token(obo, expires_in: 1.minute.from_now)
32 | payload = { exp: expires_in.to_i, jti: SecureRandom.uuid, obo: obo }
33 | JWT.encode(payload, api_token_key_pair, 'RS256')
34 | end
35 |
36 | def api_token_with_obo_token(response = file_fixture(sso_response_file).read, scopes: [], expires_in: 1.minute.from_now)
37 | response = OneLogin::RubySaml::Response.new(response) unless response.is_a?(OneLogin::RubySaml::Response)
38 | payload = { exp: expires_in.to_i, jti: SecureRandom.uuid, obo: obo_token_from_response(response, scopes: scopes) }
39 | JWT.encode(payload, api_token_key_pair, 'RS256', { cty: 'JWT' })
40 | end
41 |
42 | def obo_token_from_response(response, scopes: [])
43 | response = OneLogin::RubySaml::Response.new(response) unless response.is_a?(OneLogin::RubySaml::Response)
44 | Environment.obo_token_authenticator.generate_token(response, scopes: scopes)
45 | end
46 |
47 | def obo_token_scope(method, path)
48 | Rails.application.routes.recognize_path(path, method: method).slice(:controller, :action).values.join('/')
49 | end
50 | end
51 |
52 | RSpec.configure do |config|
53 | config.include AuthenticityTokens
54 | end
55 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative 'boot'
2 |
3 | require 'rails'
4 |
5 | # Pick the frameworks you want:
6 | require 'active_model/railtie'
7 | require 'active_job/railtie'
8 | require 'active_record/railtie'
9 | # require 'active_storage/engine'
10 | require 'action_controller/railtie'
11 | # require 'action_mailer/railtie'
12 | require 'action_view/railtie'
13 | # require 'action_cable/engine'
14 | # require 'sprockets/railtie'
15 | # require 'rails/test_unit/railtie'
16 |
17 | # Require the gems listed in Gemfile, including any gems
18 | # you've limited to :test, :development, or :production.
19 | Bundler.require(*Rails.groups)
20 |
21 | module SlovenskoSkApi
22 | class Application < Rails::Application
23 | # Initialize configuration defaults for originally generated Rails version.
24 | config.load_defaults 5.2
25 |
26 | # Settings in config/environments/* take precedence over those specified here.
27 | # Application configuration can go into files in config/initializers
28 | # -- all .rb files in that directory are automatically loaded after loading
29 | # the framework and any gems in your application.
30 |
31 | # Only loads a smaller set of middleware suitable for API only apps.
32 | # Middleware like session, flash, cookies can be added back manually.
33 | # Skip views, helpers and assets when generating a new resource.
34 | config.api_only = true
35 |
36 | # Add cookies back
37 | config.middleware.use ActionDispatch::Cookies
38 | config.middleware.use ActionDispatch::Session::CookieStore
39 |
40 | # Set local time zone
41 | config.active_record.default_timezone = :utc
42 | config.time_zone = ENV['TIME_ZONE'] || 'Europe/Bratislava'
43 |
44 | # Set default locale
45 | config.i18n.default_locale = :en
46 |
47 | # Set job worker
48 | config.active_job.queue_adapter = :delayed_job
49 |
50 | # Set error handler
51 | config.exceptions_app = self.routes
52 |
53 | # Set static files server
54 | config.public_file_server.headers = {}
55 | config.public_file_server.headers['Access-Control-Allow-Origin'] = '*'
56 | config.public_file_server.headers['Content-Type'] = 'text/plain; charset=utf-8'
57 | end
58 | end
59 |
60 | # Require Java
61 | require 'java'
62 |
63 | Kernel.define_method(:digital) { Java::Digital }
64 | Kernel.define_method(:sk) { Java::Sk }
65 |
66 | # Require libraries
67 | require 'keystore'
68 | require 'open3'
69 | require 'parameters'
70 | require 'upvs'
71 |
--------------------------------------------------------------------------------
/app/services/sktalk_receiver.rb:
--------------------------------------------------------------------------------
1 | class SktalkReceiver
2 | def initialize(proxy)
3 | @upvs = proxy
4 | end
5 |
6 | ReceiveMessageFormatError = Class.new(ArgumentError)
7 | ReceiveAsSaveToFolderError = Class.new(ArgumentError)
8 |
9 | ReceiveAndSaveToOutboxResults = Struct.new(:receive_result, :receive_timeout, :save_to_outbox_result, :save_to_outbox_timeout, keyword_init: true)
10 |
11 | def receive(message)
12 | object = parse(message)
13 | @upvs.sktalk.receive(object)
14 | end
15 |
16 | def receive!(message, save_to_outbox: false)
17 | object = parse(message)
18 | results = ReceiveAndSaveToOutboxResults.new
19 |
20 | begin
21 | results.receive_result = @upvs.sktalk.receive(object)
22 | results.receive_timeout = false
23 | rescue => error
24 | raise error unless timeout?(error)
25 | results.receive_timeout = true
26 | end
27 |
28 | # reparse message object to prevent potential modification by previous receive invocation
29 |
30 | if save_to_outbox && results.receive_result&.zero?
31 | object = parse(message)
32 | object.header.message_info.clazz = SAVE_TO_OUTBOX_CLASS
33 |
34 | begin
35 | results.save_to_outbox_result = @upvs.sktalk.receive(object)
36 | results.save_to_outbox_timeout = false
37 | rescue => error
38 | raise error unless timeout?(error)
39 | results.save_to_outbox_timeout = true
40 | end
41 | end
42 |
43 | results
44 | end
45 |
46 | def receive_and_save_to_outbox!(message)
47 | receive!(message, save_to_outbox: true)
48 | end
49 |
50 | def save_to_outbox(message)
51 | object = parse(message)
52 | object.header.message_info.clazz = SAVE_TO_OUTBOX_CLASS
53 | @upvs.sktalk.receive(object)
54 | end
55 |
56 | private
57 |
58 | SAVE_TO_DRAFTS_CLASS = 'EDESK_SAVE_APPLICATION_TO_DRAFTS'
59 | SAVE_TO_OUTBOX_CLASS = 'EDESK_SAVE_APPLICATION_TO_OUTBOX'
60 |
61 | def parse(message)
62 | object = SktalkMessages.from_xml(message)
63 | raise ReceiveAsSaveToFolderError if object.header.message_info.clazz.in?([SAVE_TO_DRAFTS_CLASS, SAVE_TO_OUTBOX_CLASS])
64 | object
65 | rescue javax.xml.bind.UnmarshalException
66 | raise ReceiveMessageFormatError
67 | end
68 |
69 | def timeout?(error)
70 | com.google.common.base.Throwables.get_causal_chain(error).to_enum.any? { |e| e.message =~ /timed out/i }
71 | end
72 |
73 | private_constant :SAVE_TO_DRAFTS_CLASS, :SAVE_TO_OUTBOX_CLASS
74 | end
75 |
--------------------------------------------------------------------------------
/app/controllers/edesk/messages_controller.rb:
--------------------------------------------------------------------------------
1 | class Edesk::MessagesController < ApiController
2 | around_action :raise_on_unpermitted_parameters, only: :search
3 |
4 | include EdeskRescuable
5 | include Pagination
6 |
7 | mattr_reader :edesk_message_parser, default: EdeskMessageParser.new
8 |
9 | before_action { authenticate(allow_sub: true) }
10 |
11 | before_action(only: [:index, :search]) { set_page }
12 | before_action(only: [:index, :search]) { set_per_page(default: 50, range: 10..5000) }
13 |
14 | before_action(only: :index) { render_bad_request(:invalid, :folder_id) unless match_positive?(params[:folder_id]) }
15 | before_action(only: :update) { render_bad_request(:invalid, :folder_id) if params.require(:folder_id).to_i <= 0 }
16 | before_action(only: :search) { render_bad_request(:invalid, :correlation_id) unless UUID_PATTERN.match?(params.require(:correlation_id)) }
17 | before_action(except: [:index, :search]) { render_bad_request(:invalid, :message_id) unless match_positive?(params[:id]) }
18 |
19 | def index
20 | @messages = edesk_service(upvs_identity).messages(params[:folder_id].to_i, page: page, per_page: per_page)
21 | end
22 |
23 | def show
24 | @message = edesk_message_parser.parse(edesk_service(upvs_identity).message(params[:id].to_i))
25 | end
26 |
27 | def search
28 | @messages = edesk_service(upvs_identity).filter_messages(search_params, page: page, per_page: per_page)
29 | end
30 |
31 | def update
32 | edesk_service(upvs_identity).move_message(params[:id].to_i, params[:folder_id].to_i)
33 |
34 | head :no_content
35 | end
36 |
37 | def destroy
38 | edesk_service(upvs_identity).delete_message(params[:id].to_i)
39 |
40 | head :no_content
41 | end
42 |
43 | def authorize
44 | render json: { authorized_message_id: edesk_service(upvs_identity).authorize_message(params[:id].to_i) }
45 | end
46 |
47 | private
48 |
49 | UUID_PATTERN = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
50 |
51 | def require_request_body?
52 | super && action_name != 'authorize'
53 | end
54 |
55 | def search_params
56 | params.permit(:format, :token, :page, :per_page, :correlation_id).except(:format, :token, :page, :per_page)
57 | end
58 |
59 | def raise_on_unpermitted_parameters
60 | begin
61 | ActionController::Parameters.action_on_unpermitted_parameters = :raise
62 | yield
63 | ensure
64 | ActionController::Parameters.action_on_unpermitted_parameters = :log
65 | end
66 | end
67 |
68 | delegate :match_positive?, to: Integers
69 | end
70 |
--------------------------------------------------------------------------------
/app/services/environment.rb:
--------------------------------------------------------------------------------
1 | module Environment
2 | extend self
3 |
4 | # TODO move to UpvsEnvironment and rename to #sso_callback_urls, also rename env var to SSO_CALLBACK_URLS as this is only UPVS SSO related configuration
5 | def login_callback_url
6 | @login_callback_url ||= ENV.fetch('LOGIN_CALLBACK_URL')
7 | end
8 |
9 | # TODO move to UpvsEnvironment and rename to #slo_callback_urls, also rename env var to SLO_CALLBACK_URLS as this is only UPVS SSO related configuration
10 | def logout_callback_url
11 | @logout_callback_url ||= ENV.fetch('LOGOUT_CALLBACK_URL')
12 | end
13 |
14 | def api_token_authenticator
15 | @api_token_authenticator ||= ApiTokenAuthenticator.new(
16 | identifier_store: api_token_identifier_store,
17 | public_key: OpenSSL::PKey::RSA.new(File.read(Rails.root.join('security', "api_token_#{Rails.env}.public.pem"))),
18 | subject_verifier: -> (sub) { UpvsEnvironment.subject?(sub) },
19 | obo_token_authenticator: obo_token_authenticator,
20 | )
21 | end
22 |
23 | def api_token_identifier_store
24 | @api_token_identifier_store ||= ActiveSupport::Cache::RedisCacheStore.new(
25 | namespace: 'api-token-identifiers',
26 | error_handler: REDIS_CONNECTION_ENFORCER,
27 | compress: false,
28 | url: ENV['REDIS_URL'] || 'redis://localhost:6379/0'
29 | )
30 | end
31 |
32 | def obo_token_authenticator
33 | @obo_token_authenticator ||= OboTokenAuthenticator.new(
34 | assertion_store: obo_token_assertion_store,
35 | key_pair: OpenSSL::PKey::RSA.new(File.read(Rails.root.join('security', "obo_token_#{Rails.env}.private.pem"))),
36 | proxy_subject: UpvsEnvironment.sso_proxy_subject,
37 | ) if (UpvsEnvironment.obo_support? || UpvsEnvironment.sso_support?)
38 | end
39 |
40 | def obo_token_assertion_store
41 | @obo_token_assertion_store ||= ActiveSupport::Cache::RedisCacheStore.new(
42 | namespace: 'obo-token-assertions',
43 | error_handler: REDIS_CONNECTION_ENFORCER,
44 | compress: true,
45 | url: ENV['REDIS_URL'] || 'redis://localhost:6379/0'
46 | ) if (UpvsEnvironment.obo_support? || UpvsEnvironment.sso_support?)
47 | end
48 |
49 | def obo_token_scopes
50 | @obo_token_scopes ||= ['sktalk/receive', 'sktalk/receive_and_save_to_outbox', 'sktalk/save_to_outbox', 'sktalk/prepare_for_later_receive', 'upvs/assertion', 'upvs/identity']
51 | end
52 |
53 | # RedisCacheStore ignores standard errors
54 | RedisConnectionError = Class.new(Exception)
55 |
56 | REDIS_CONNECTION_ENFORCER = -> (*) { raise RedisConnectionError }
57 | end
58 |
--------------------------------------------------------------------------------
/lib/upvs/cfg/eks/EKSService_1.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/chart/templates/_helpers.tpl:
--------------------------------------------------------------------------------
1 | {{/* vim: set filetype=mustache: */}}
2 | {{/*
3 | Expand the name of the chart.
4 | */}}
5 | {{- define "name" -}}
6 | {{- default .Chart.Name .Values.nameOverride | trunc 24 | trimSuffix "-" -}}
7 | {{- end -}}
8 |
9 | {{/*
10 | Create a default fully qualified app name.
11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
12 | */}}
13 | {{- define "fullname" -}}
14 | {{- $name := default .Chart.Name .Values.nameOverride -}}
15 | {{- printf "%s-%s" .Release.Name $name | trimSuffix "-app" | trunc 63 | trimSuffix "-" -}}
16 | {{- end -}}
17 |
18 | {{- define "appname" -}}
19 | {{- $releaseName := default .Release.Name .Values.releaseOverride -}}
20 | {{- printf "%s" $releaseName | trunc 63 | trimSuffix "-" -}}
21 | {{- end -}}
22 |
23 | {{- define "imagename" -}}
24 | {{- if eq .Values.image.tag "" -}}
25 | {{- .Values.image.repository -}}
26 | {{- else -}}
27 | {{- printf "%s:%s" .Values.image.repository .Values.image.tag -}}
28 | {{- end -}}
29 | {{- end -}}
30 |
31 | {{- define "trackableappname" -}}
32 | {{- $trackableName := printf "%s-%s" (include "appname" .) .Values.application.track -}}
33 | {{- $trackableName | trimSuffix "-stable" | trunc 63 | trimSuffix "-" -}}
34 | {{- end -}}
35 |
36 | {{/*
37 | Get a hostname from URL
38 | */}}
39 | {{- define "hostname" -}}
40 | {{- . | trimPrefix "http://" | trimPrefix "https://" | trimSuffix "/" | trim | quote -}}
41 | {{- end -}}
42 |
43 | {{/*
44 | Get SecRule's arguments with unescaped single&double quotes
45 | */}}
46 | {{- define "secrule" -}}
47 | {{- $operator := .operator | quote | replace "\"" "\\\"" | replace "'" "\\'" -}}
48 | {{- $action := .action | quote | replace "\"" "\\\"" | replace "'" "\\'" -}}
49 | {{- printf "SecRule %s %s %s" .variable $operator $action -}}
50 | {{- end -}}
51 |
52 | {{/*
53 | Generate a name for a Persistent Volume Claim
54 | */}}
55 | {{- define "pvcName" -}}
56 | {{- printf "%s-%s" (include "fullname" .context) .name | trunc 63 | trimSuffix "-" -}}
57 | {{- end -}}
58 |
59 | {{- define "sharedlabels" -}}
60 | app: {{ template "appname" . }}
61 | chart: "{{ .Chart.Name }}-{{ .Chart.Version| replace "+" "_" }}"
62 | release: {{ .Release.Name }}
63 | heritage: {{ .Release.Service }}
64 | app.kubernetes.io/name: {{ template "appname" . }}
65 | helm.sh/chart: "{{ .Chart.Name }}-{{ .Chart.Version| replace "+" "_" }}"
66 | app.kubernetes.io/managed-by: {{ .Release.Service }}
67 | app.kubernetes.io/instance: {{ .Release.Name }}
68 | {{- if .Values.extraLabels }}
69 | {{ toYaml $.Values.extraLabels }}
70 | {{- end }}
71 | {{- end -}}
72 |
--------------------------------------------------------------------------------
/chart/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | ## Contributing
2 |
3 | Thank you for your interest in contributing to this GitLab project! We welcome
4 | all contributions. By participating in this project, you agree to abide by the
5 | [code of conduct](#code-of-conduct).
6 |
7 |
8 | ## Developer Certificate of Origin + License
9 |
10 | By contributing to GitLab B.V., You accept and agree to the following terms and
11 | conditions for Your present and future Contributions submitted to GitLab B.V.
12 | Except for the license granted herein to GitLab B.V. and recipients of software
13 | distributed by GitLab B.V., You reserve all right, title, and interest in and to
14 | Your Contributions. All Contributions are subject to the following DCO + License
15 | terms.
16 |
17 | [DCO + License](https://gitlab.com/gitlab-org/dco/blob/master/README.md)
18 |
19 | _This notice should stay as the first item in the CONTRIBUTING.md file._
20 |
21 | ## Code of conduct
22 |
23 | We want to create a welcoming environment for everyone who is interested
24 | in contributing. Please visit our [Code of Conduct
25 | page](https://about.gitlab.com/contributing/code-of-conduct) to learn
26 | more about our commitment to an open and welcoming environment.
27 |
28 | ## Merge request guidelines
29 |
30 | Below are some guidelines for merge requests:
31 |
32 | - Any new configuration option should be documented in
33 | the `Configuration` section in README.md.
34 | - For any template changes, we encourage a test case be added or
35 | updated in the
36 | [template tests](https://gitlab.com/gitlab-org/charts/auto-deploy-app/-/blob/master/test/template_test.go).
37 |
38 | ### Working with the tests
39 |
40 | The tests are written in [Go](https://golang.org) (version 1.13 or later,
41 | with [modules enabled](https://golang.org/cmd/go/#hdr-Module_support)) using
42 | the [Terratest](https://github.com/gruntwork-io/terratest) library. To work
43 | on the tests, you need to have [Helm 2](https://v2.helm.sh/docs/) and
44 | [Go](https://golang.org) installed.
45 |
46 | To run the tests, run the following commands from the root of your copy of `auto-deploy-app`:
47 |
48 | ```shell
49 | helm repo add stable https://charts.helm.sh/stable # required only once
50 | helm dependency build . # required any time the dependencies change
51 | cd test
52 | GO111MODULE=auto go test ./... # required for every change to the tests or the template
53 | ```
54 |
55 | ### Windows users
56 |
57 | Some of the dependencies might not be available on Windows (e.g., `github.com/sirupsen/logrus/hooks/syslog`). Therefore we recommend running tests on docker, vagrant boxes or similar virtualization tools.
--------------------------------------------------------------------------------
/spec/fixtures/iam/get_identity_response.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UPVS
6 |
7 | 321
8 | Rozpočtová organizácia
9 |
10 | 2013-12-13+01:00
11 |
12 |
13 |
14 | 703
15 | Slovenská republika
16 |
17 |
18 | SK0101
19 | Okres Bratislava I
20 |
21 |
22 | SK0101528595
23 | Bratislava - mestská časť Staré Mesto
24 |
25 | Pribinova
26 |
27 | 81272
28 |
29 |
30 |
31 |
32 | 1
33 | Pevná sieť
34 |
35 |
36 | +42121234111
37 |
38 |
39 |
40 | mailto:test@slovensko.sk
41 |
42 |
43 |
44 | 7
45 | IČO (Identifikačné číslo organizácie)
46 |
47 | 42156424
48 |
49 |
50 | UPVS
51 | INSTITUTION_OF_PUBLIC_ADMINISTRATION
52 |
53 | SECTOR_UPVS
54 | 6D9DC77B-70ED-432F-ABAA-5DE8753C967C
55 |
56 | ico://sk/42156424_10001
57 | 10001
58 |
59 |
60 | false
61 | DELIVERABLE
62 | false
63 | false
64 | E0000012800
65 | ACTIVATED
66 | SK
67 | 217275
68 | true
69 |
70 |
71 |
72 |
--------------------------------------------------------------------------------
/spec/fixtures/sktalk/ed_delivery_notification.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3.0
4 |
5 |
6 | ED_DELIVERY_NOTIFICATION
7 | 6d65268e-495e-45f4-a3cb-3e8fca85b40a
8 | ac64292e-e06a-4147-8b8c-d56275a9f625
9 | e411c801-8290-47c2-8250-801f3cf56e58
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | 6d65268e-495e-45f4-a3cb-3e8fca85b40a
18 | ico://sk/42156424_90000
19 | ico://sk/6501012225
20 | ED.DeliveryReportNotification
21 | Doručenka
22 | e411c801-8290-47c2-8250-801f3cf56e58
23 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/lib/upvs/src/digital/slovensko/upvs/internals/LoggerPropertyDefiner.java:
--------------------------------------------------------------------------------
1 | // TODO remove this after removing appropriate configuration files
2 |
3 | package digital.slovensko.upvs.internals;
4 |
5 | import java.net.URL;
6 | import java.util.Map;
7 | import java.util.logging.ConsoleHandler;
8 | import java.util.logging.Handler;
9 | import java.util.logging.Level;
10 | import java.util.logging.LogManager;
11 | import java.util.logging.Logger;
12 |
13 | import ch.qos.logback.classic.LoggerContext;
14 | import ch.qos.logback.classic.joran.JoranConfigurator;
15 | import ch.qos.logback.classic.util.ContextInitializer;
16 | import ch.qos.logback.core.PropertyDefinerBase;
17 | import ch.qos.logback.core.joran.spi.JoranException;
18 | import org.slf4j.LoggerFactory;
19 |
20 | import static java.util.Collections.emptyMap;
21 |
22 | import static com.google.common.collect.ImmutableMap.copyOf;
23 |
24 | public final class LoggerPropertyDefiner extends PropertyDefinerBase {
25 | private static Map properties = emptyMap();
26 |
27 | private String propertyKey;
28 |
29 | private String propertyDefault;
30 |
31 | public LoggerPropertyDefiner() {}
32 |
33 | public static void load(final Map properties) {
34 | synchronized (LoggerPropertyDefiner.class) {
35 | LoggerPropertyDefiner.properties = copyOf(properties);
36 |
37 | reconfigureLogbackLoggerContext();
38 | reconfigureJavaLoggingLevelOnConsoleHandlers();
39 | }
40 | }
41 |
42 | private static void reconfigureLogbackLoggerContext() {
43 | LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
44 | ContextInitializer initializer = new ContextInitializer(context);
45 | URL url = initializer.findURLOfDefaultConfigurationFile(true);
46 |
47 | context.reset();
48 |
49 | try {
50 | JoranConfigurator configurator = new JoranConfigurator();
51 |
52 | configurator.setContext(context);
53 | configurator.doConfigure(url);
54 | } catch (JoranException e) {
55 | throw new RuntimeException(e);
56 | }
57 | }
58 |
59 | private static void reconfigureJavaLoggingLevelOnConsoleHandlers() {
60 | Level level = Level.parse(properties.getOrDefault("upvs.log.java.console.level", "OFF").toString());
61 | Logger logger = LogManager.getLogManager().getLogger("");
62 |
63 | for (Handler handler: logger.getHandlers()) {
64 | if (handler instanceof ConsoleHandler) {
65 | handler.setLevel(level);
66 | }
67 | }
68 | }
69 |
70 | public void setPropertyKey(final String key) {
71 | this.propertyKey = key;
72 | }
73 |
74 | public void setPropertyDefault(final String value) {
75 | this.propertyDefault = value;
76 | }
77 |
78 | public String getPropertyValue() {
79 | return properties.getOrDefault(this.propertyKey, this.propertyDefault).toString();
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # Note that this schema.rb definition is the authoritative source for your
6 | # database schema. If you need to create the application database on another
7 | # system, you should be using db:schema:load, not running all the migrations
8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 | # you'll amass, the slower it'll run and the greater likelihood for issues).
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema.define(version: 2018_12_19_193446) do
14 |
15 | # These are extensions that must be enabled in order to support this database
16 | enable_extension "plpgsql"
17 |
18 | create_table "delayed_jobs", force: :cascade do |t|
19 | t.integer "priority", default: 0, null: false
20 | t.integer "attempts", default: 0, null: false
21 | t.text "handler", null: false
22 | t.text "last_error"
23 | t.datetime "run_at"
24 | t.datetime "locked_at"
25 | t.datetime "failed_at"
26 | t.string "locked_by"
27 | t.string "queue"
28 | t.datetime "created_at"
29 | t.datetime "updated_at"
30 | t.index ["priority", "run_at"], name: "delayed_jobs_priority"
31 | end
32 |
33 | create_table "form_template_related_documents", force: :cascade do |t|
34 | t.bigint "form_template_id", null: false
35 | t.string "data", null: false
36 | t.string "language", null: false
37 | t.string "document_type", null: false
38 | t.datetime "created_at", null: false
39 | t.datetime "updated_at", null: false
40 | t.index ["form_template_id", "language", "document_type"], name: "index_related_documents_on_template_id_and_language_and_type", unique: true
41 | t.index ["form_template_id"], name: "index_form_template_related_documents_on_form_template_id"
42 | end
43 |
44 | create_table "form_templates", force: :cascade do |t|
45 | t.string "identifier", null: false
46 | t.integer "version_major", null: false
47 | t.integer "version_minor", null: false
48 | t.datetime "created_at", null: false
49 | t.datetime "updated_at", null: false
50 | t.index ["identifier", "version_major", "version_minor"], name: "index_form_templates_on_identifier_and_version", unique: true
51 | end
52 |
53 | create_table "heartbeats", force: :cascade do |t|
54 | t.string "name", null: false
55 | t.datetime "created_at", null: false
56 | t.datetime "updated_at", null: false
57 | t.index ["name"], name: "index_heartbeats_on_name", unique: true
58 | end
59 |
60 | add_foreign_key "form_template_related_documents", "form_templates"
61 | end
62 |
--------------------------------------------------------------------------------
/lib/upvs/src/digital/slovensko/upvs/UpvsProxy.java:
--------------------------------------------------------------------------------
1 | package digital.slovensko.upvs;
2 |
3 | import java.util.LinkedHashMap;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | import org.springframework.context.ApplicationContext;
8 | import org.springframework.context.support.ClassPathXmlApplicationContext;
9 | import org.springframework.core.env.MapPropertySource;
10 | import org.springframework.core.env.PropertySource;
11 | import org.springframework.core.io.FileSystemResource;
12 | import org.springframework.core.io.Resource;
13 |
14 | import sk.gov.egov.iservice.IService;
15 | import sk.gov.schemas.edesk.eksservice._1.IEKSService;
16 | import sk.gov.schemas.identity.service._1_7.IdentityServices;
17 | import sk.gov.schemas.servicebus.service._1_0.IServiceBus;
18 |
19 | import digital.slovensko.upvs.internals.LoggerPropertyDefiner;
20 |
21 | import static com.google.common.collect.Lists.newArrayList;
22 |
23 | public final class UpvsProxy {
24 | private final ApplicationContext context;
25 |
26 | private final IEKSService eks;
27 |
28 | private final IServiceBus ez;
29 |
30 | private final IdentityServices iam;
31 |
32 | private final IService sktalk;
33 |
34 | public UpvsProxy(final Map properties) {
35 | Map copy = new LinkedHashMap<>(properties);
36 |
37 | LoggerPropertyDefiner.load(copy);
38 |
39 | List configurations = newArrayList("context.xml", "ws.xml");
40 |
41 | if (copy.containsKey("upvs.sts.obo")) {
42 | boolean isSamlAssertion = copy.get("upvs.sts.obo").toString().stripLeading().startsWith("<");
43 | configurations.add(isSamlAssertion ? "ws-onbehalf.xml" : "ws-onbehalf-id.xml");
44 | } else {
45 | configurations.add("ws-techcert.xml");
46 | }
47 |
48 | this.context = new Context(configurations, new MapPropertySource("args", copy));
49 |
50 | this.eks = this.context.getBean(IEKSService.class);
51 | this.ez = this.context.getBean(IServiceBus.class);
52 | this.iam = this.context.getBean(IdentityServices.class);
53 | this.sktalk = this.context.getBean(IService.class);
54 | }
55 |
56 | private static final class Context extends ClassPathXmlApplicationContext {
57 | Context(final List configurations, final PropertySource> properties) {
58 | super(configurations.toArray(new String[configurations.size()]), false);
59 |
60 | this.getEnvironment().getPropertySources().addFirst(properties);
61 | this.refresh();
62 | }
63 |
64 | @Override
65 | protected Resource getResourceByPath(final String path) {
66 | Resource resource = super.getResourceByPath(path);
67 |
68 | return resource.exists() ? resource : new FileSystemResource(path);
69 | }
70 | }
71 |
72 | public IEKSService getEks() {
73 | return this.eks;
74 | }
75 |
76 | public IServiceBus getEz() {
77 | return this.ez;
78 | }
79 |
80 | public IdentityServices getIam() {
81 | return this.iam;
82 | }
83 |
84 | public IService getSktalk() {
85 | return this.sktalk;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/.github/workflows/slovensko_digital_ci.yml:
--------------------------------------------------------------------------------
1 | name: Slovensko.Digital CI
2 |
3 | on:
4 | push:
5 | branches: '**'
6 | tags: '*'
7 |
8 | jobs:
9 | test:
10 | runs-on: ubuntu-latest
11 |
12 | env:
13 | PGHOST: localhost
14 | RAILS_ENV: test
15 |
16 | services:
17 | postgres:
18 | image: postgres:12-alpine
19 | env:
20 | POSTGRES_USER: postgres
21 | POSTGRES_HOST_AUTH_METHOD: trust
22 | ports:
23 | - 5432:5432
24 | options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
25 | redis:
26 | image: redis:5-alpine
27 | ports:
28 | - 6379:6379
29 | options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
30 |
31 | steps:
32 | - uses: actions/checkout@v2
33 | - uses: actions/setup-java@v2
34 | with:
35 | java-version: 17
36 | distribution: 'adopt'
37 | - uses: actions/cache@v3
38 | with:
39 | path: ~/.m2
40 | key: ${{hashFiles('lib/upvs/pom.xml')}}
41 | - uses: ruby/setup-ruby@v1
42 | with:
43 | bundler-cache: true
44 |
45 | - run: mvn -f lib/upvs package
46 | - run: bundle exec rails db:create db:schema:load --trace
47 | - run: bundle exec dotenv -f .env.test rspec
48 | - run: bundle exec dotenv -f .env.test.with_upvs_sso rspec
49 |
50 | build:
51 | needs: test
52 | if: startsWith(github.ref, 'refs/tags/')
53 |
54 | runs-on: ubuntu-latest
55 |
56 | permissions: write-all
57 |
58 | steps:
59 | - uses: actions/checkout@v2
60 | with:
61 | fetch-depth: 0
62 | - name: Run slovensko-digital/docker-image-tags@v1
63 | run: |
64 | head=$(git describe --tags --exact-match ${{github.event.head_commit.id}})
65 | latest=$(git tag --sort=-v:refname | grep -Fv - | head -n 1)
66 | base=ghcr.io/${{github.repository}}
67 | tags=$base:${head:1}$(if [[ $head == $latest ]]; then echo ",$base:latest"; fi)
68 | echo "tags=$tags" >> $GITHUB_ENV
69 | - uses: docker/setup-buildx-action@v2
70 | - uses: docker/login-action@v2
71 | with:
72 | registry: ghcr.io
73 | username: ${{github.actor}}
74 | password: ${{secrets.GITHUB_TOKEN}}
75 | - uses: docker/build-push-action@v4
76 | with:
77 | push: true
78 | platforms: linux/amd64
79 | tags: ${{env.tags}}
80 |
81 | gitlab-push:
82 | needs: test
83 | if: startsWith(github.ref, 'refs/tags/')
84 |
85 | runs-on: ubuntu-latest
86 |
87 | steps:
88 | - uses: actions/checkout@v2
89 | with:
90 | fetch-depth: 0
91 |
92 | - uses: dokku/github-action@master
93 | with:
94 | git_push_flags: '--force'
95 | git_remote_url: ssh://git@${{secrets.GITLAB_DEPLOY_HOST}}/${{github.event.repository.name}}.git
96 | ssh_private_key: ${{secrets.GITLAB_DEPLOY_KEY}}
97 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # Code is not reloaded between requests.
5 | config.cache_classes = true
6 |
7 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both threaded web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
18 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
19 | # config.require_master_key = true
20 |
21 | # Disable serving static files from the `/public` folder by default since
22 | # Apache or NGINX already handles this.
23 | config.public_file_server.enabled = true
24 |
25 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
26 | # config.action_controller.asset_host = 'http://assets.example.com'
27 |
28 | # Specifies the header that your server uses for sending files.
29 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
30 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
31 |
32 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
33 | # config.force_ssl = true
34 |
35 | # Use the lowest log level to ensure availability of diagnostic information
36 | # when problems arise.
37 | config.log_level = ENV['LOG_LEVEL'] || :debug
38 |
39 | # Prepend all log lines with the following tags.
40 | config.log_tags = [:request_id]
41 |
42 | # Use a different cache store in production.
43 | # config.cache_store = :mem_cache_store
44 |
45 | # Use a real queuing backend for Active Job (and separate queues per environment)
46 | # config.active_job.queue_adapter = :resque
47 | # config.active_job.queue_name_prefix = "slovensko-sk-api-#{Rails.env}"
48 |
49 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
50 | # the I18n.default_locale when a translation cannot be found).
51 | config.i18n.fallbacks = true
52 |
53 | # Send deprecation notices to registered listeners.
54 | config.active_support.deprecation = :notify
55 |
56 | # Use default logging formatter so that PID and timestamp are not suppressed.
57 | config.log_formatter = ::Logger::Formatter.new
58 |
59 | # Use standard output logger.
60 | config.logger = ActiveSupport::Logger.new(STDOUT)
61 |
62 | # Use a different logger for distributed setups.
63 | # require 'syslog/logger'
64 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
65 |
66 | # Do not dump schema after migrations.
67 | config.active_record.dump_schema_after_migration = false
68 | end
69 |
--------------------------------------------------------------------------------
/config/environments/staging.rb:
--------------------------------------------------------------------------------
1 | Rails.application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # Code is not reloaded between requests.
5 | config.cache_classes = true
6 |
7 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both threaded web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"]
18 | # or in config/master.key. This key is used to decrypt credentials (and other encrypted files).
19 | # config.require_master_key = true
20 |
21 | # Disable serving static files from the `/public` folder by default since
22 | # Apache or NGINX already handles this.
23 | config.public_file_server.enabled = true
24 |
25 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
26 | # config.action_controller.asset_host = 'http://assets.example.com'
27 |
28 | # Specifies the header that your server uses for sending files.
29 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
30 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
31 |
32 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
33 | # config.force_ssl = true
34 |
35 | # Use the lowest log level to ensure availability of diagnostic information
36 | # when problems arise.
37 | config.log_level = ENV['LOG_LEVEL'] || :debug
38 |
39 | # Prepend all log lines with the following tags.
40 | config.log_tags = [:request_id]
41 |
42 | # Use a different cache store in production.
43 | # config.cache_store = :mem_cache_store
44 |
45 | # Use a real queuing backend for Active Job (and separate queues per environment)
46 | # config.active_job.queue_adapter = :resque
47 | # config.active_job.queue_name_prefix = "slovensko-sk-api-#{Rails.env}"
48 |
49 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
50 | # the I18n.default_locale when a translation cannot be found).
51 | config.i18n.fallbacks = true
52 |
53 | # Send deprecation notices to registered listeners.
54 | config.active_support.deprecation = :notify
55 |
56 | # Use default logging formatter so that PID and timestamp are not suppressed.
57 | config.log_formatter = ::Logger::Formatter.new
58 |
59 | # Use standard output logger.
60 | config.logger = ActiveSupport::Logger.new(STDOUT)
61 |
62 | # Use a different logger for distributed setups.
63 | # require 'syslog/logger'
64 | # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
65 |
66 | # Do not dump schema after migrations.
67 | config.active_record.dump_schema_after_migration = false
68 | end
69 |
--------------------------------------------------------------------------------
/spec/rails_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV['RAILS_ENV'] ||= 'test'
3 |
4 | require_relative '../config/environment'
5 |
6 | # Prevent database truncation if the environment is production
7 | abort('The Rails environment is running in production mode!') if Rails.env.production?
8 |
9 | require 'spec_helper'
10 | require 'rspec/rails'
11 |
12 | # Add additional requires below this line. Rails is not loaded until this point!
13 |
14 | require 'super_diff/rspec-rails'
15 |
16 | # Requires supporting ruby files with custom matchers and macros, etc, in
17 | # spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
18 | # run as spec files by default. This means that files in spec/support that end
19 | # in _spec.rb will both be required and run as specs, causing the specs to be
20 | # run twice. It is recommended that you do not name files matching this glob to
21 | # end with _spec.rb. You can configure this pattern with the --pattern
22 | # option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
23 | #
24 | # The following line is provided for convenience purposes. It has the downside
25 | # of increasing the boot-up time by auto-requiring all files in the support
26 | # directory. Alternatively, in the individual `*_spec.rb` files, manually
27 | # require only the support files necessary.
28 | #
29 | Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
30 |
31 | # Checks for pending migrations and applies them before tests are run.
32 | # If you are not using ActiveRecord, you can remove these lines.
33 | begin
34 | ActiveRecord::Migration.maintain_test_schema!
35 | rescue ActiveRecord::PendingMigrationError => e
36 | puts e.to_s.strip
37 | exit 1
38 | end
39 |
40 | RSpec.configure do |config|
41 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
42 | config.fixture_path = config.file_fixture_path = Rails.root.join('spec/fixtures').to_s
43 |
44 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
45 | # examples within a transaction, remove the following line or assign false
46 | # instead of true.
47 | config.use_transactional_fixtures = false
48 |
49 | # RSpec Rails can automatically mix in different behaviours to your tests
50 | # based on their file location, for example enabling you to call `get` and
51 | # `post` in specs under `spec/controllers`.
52 | #
53 | # You can disable this behaviour by removing the line below, and instead
54 | # explicitly tag your specs with their type, e.g.:
55 | #
56 | # RSpec.describe UsersController, :type => :controller do
57 | # # ...
58 | # end
59 | #
60 | # The different available types are documented in the features, such as in
61 | # https://relishapp.com/rspec/rspec-rails/docs
62 | config.infer_spec_type_from_file_location!
63 |
64 | # Filter lines from Rails gems in backtraces.
65 | config.filter_rails_from_backtrace!
66 | # arbitrary gems may also be filtered via:
67 | # config.filter_gems_from_backtrace("gem name")
68 | end
69 |
--------------------------------------------------------------------------------
/.gitlab/auto-deploy-values.yaml:
--------------------------------------------------------------------------------
1 | timeout: 120
2 | service:
3 | externalPort: 3000
4 | internalPort: 3000
5 | image:
6 | secrets:
7 | - name: skdigital-bonet-registry
8 | ingress:
9 | annotations:
10 | nginx.ingress.kubernetes.io/from-to-www-redirect: "true"
11 | hostAliases:
12 | - ip: "185.91.203.179"
13 | hostnames:
14 | - "eschranka1.slovensko.sk"
15 | - "eschranka.upvsfixnew.gov.sk"
16 | - "iamwse.slovensko.sk"
17 | - "iamwse.upvsfix.gov.sk"
18 | - "uir.slovensko.sk"
19 | - "uir.upvsfixnew.gov.sk"
20 | - "usr.slovensko.sk"
21 | - "usr.upvsfixnew.gov.sk"
22 | livenessProbe:
23 | initialDelaySeconds: 20
24 | probeType: "exec"
25 | command:
26 | - "true"
27 | readinessProbe:
28 | initialDelaySeconds: 20
29 | probeType: "exec"
30 | command:
31 | - "true"
32 | resources:
33 | requests:
34 | cpu: 5m
35 | memory: 650Mi
36 | limits:
37 | memory: 1Gi
38 | application:
39 | migrateCommand: ["bundle", "exec", "rails", "db:migrate"]
40 | persistence:
41 | enabled: true
42 | volumes:
43 | - name: security-volume
44 | mount:
45 | path: /app/security
46 | claim:
47 | accessMode: ReadWriteMany
48 | size: 16M
49 | storageClass: manual
50 | workers:
51 | clock:
52 | hostAliases:
53 | - ip: "185.91.203.179"
54 | hostnames:
55 | - "eschranka1.slovensko.sk"
56 | - "eschranka.upvsfixnew.gov.sk"
57 | - "iamwse.slovensko.sk"
58 | - "iamwse.upvsfix.gov.sk"
59 | - "uir.slovensko.sk"
60 | - "uir.upvsfixnew.gov.sk"
61 | - "usr.slovensko.sk"
62 | - "usr.upvsfixnew.gov.sk"
63 | replicaCount: "1"
64 | command: ["bundle", "exec", "clockwork", "config/clock.rb"]
65 | terminationGracePeriodSeconds: 60
66 | livenessProbe:
67 | initialDelaySeconds: 5
68 | timeoutSeconds: 10
69 | probeType: "exec"
70 | command:
71 | - "true"
72 | readinessProbe:
73 | probeType: "exec"
74 | command:
75 | - "true"
76 | resources:
77 | requests:
78 | cpu: 20m
79 | memory: 400Mi
80 | limits:
81 | memory: 600Mi
82 | worker:
83 | hostAliases:
84 | - ip: "185.91.203.179"
85 | hostnames:
86 | - "eschranka1.slovensko.sk"
87 | - "eschranka.upvsfixnew.gov.sk"
88 | - "iamwse.slovensko.sk"
89 | - "iamwse.upvsfix.gov.sk"
90 | - "uir.slovensko.sk"
91 | - "uir.upvsfixnew.gov.sk"
92 | - "usr.slovensko.sk"
93 | - "usr.upvsfixnew.gov.sk"
94 | replicaCount: "1"
95 | command: ["bundle", "exec", "rake", "jobs:work"]
96 | terminationGracePeriodSeconds: 60
97 | livenessProbe:
98 | initialDelaySeconds: 5
99 | timeoutSeconds: 10
100 | probeType: "exec"
101 | command:
102 | - "true"
103 | readinessProbe:
104 | probeType: "exec"
105 | command:
106 | - "true"
107 | resources:
108 | requests:
109 | cpu: 5m
110 | memory: 400Mi
111 | limits:
112 | memory: 600Mi
113 |
--------------------------------------------------------------------------------