├── 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* 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 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 | 22 | 23 | 24 | 25 | 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 | 26 | 27 | Všeobecná agenda 28 | Všeobecný text 29 | 30 | 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 | 26 | 27 | Všeobecná agenda 28 | Všeobecný text 29 | 30 | 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 | 26 | 27 | Všeobecná agenda 28 | Všeobecný text 29 | 30 | 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 | 30 | 31 | 32 | 33 | 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 | 24 | 25 | 26 | ico://sk/42156424_90000 27 | ico://sk/6501012225 28 | 29 | 30 | 2016-10-18T15:51:23.7860774+02:00 31 | 15 32 | 2016-11-03T00:00:00+01:00 33 | 34 | 35 | e411c801-8290-47c2-8250-801f3cf56e58 36 | Všeobecná agenda - rozhodnutie do vlastných rúk 37 | Doc.GeneralAgendaReport 38 | Po uplynutí dátumu doručenia sa doručovaná správa považuje za nedoručenú. 39 | 40 | 41 | 9db2f9cb-639b-45d9-8f03-24195e5615af 42 | Všeobecná agenda - rozhodnutie do vlastných rúk 43 | 44 | 45 | 46 | 47 | 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 | --------------------------------------------------------------------------------