Skip to content

Latest commit

 

History

History
296 lines (212 loc) · 14.2 KB

backend_audit.md

File metadata and controls

296 lines (212 loc) · 14.2 KB

Backend Audit

The purpose of a backend audit is to ensure that the backend of a software application is functioning properly and efficiently. It involves reviewing the code quality, performance, and security of the backend system.


Code Quality

This section of audit is related to code quality. CodeClimate is a tool that analyzes code and detects issues such as bugs, vulnerabilities, and code smells. It helps to maintain code quality and improve the overall health of the codebase. In order to pass the code quality check, the code must have 0 code smells.

Example of .codeclimate.yml for the project:

checks:
  argument-count:
    enabled: false
  file-lines:
    enabled: false
  method-complexity:
    config:
      threshold: 7
  method-count:
    enabled: false
  method-lines:
    enabled: false
plugins:
  brakeman:
    enabled: true
  bundler-audit:
    enabled: true
  fixme:
    enabled: true
  rubocop:
    enabled: true
    channel: rubocop-1-48-1
ratings:
  paths:
    - 'app/**'
    - 'lib/**'
exclude_paths:
  - 'config/'
  - 'db/'
  - 'public/'
  - 'spec/'
  - 'vendor/'

You need to specify version of rubocop in channel property from your Gemfile.lock, otherwise you will get an error. We disable some checks because they repeat the same checks from rubocop. Also we exclude some folders from checking because they are not related to our codebase. You can find more information about configuration in CodeClimate documentation.

We generate CodeClimate report in Gitlab CI. To do this, add the following lines to .gitlab-ci.yml:

include:
  - template: Code-Quality.gitlab-ci.yml

code_quality_html:
  extends: code_quality
  variables:
    REPORT_FORMAT: html
  artifacts:
    paths: [gl-code-quality-report.html]
  when: manual
  rules:
    - if: '$CI_COMMIT_REF_PROTECTED == "true"'

Then you can find CodeClimate report in code_quality_html pipeline artifacts and download it.

For Complexity score we use Cognitive complexity metric from codeclimate and Cyclomatic complexity metric from rubocop. We check by maximum value of these metrics. We also check that there are no methods with more than 5 arguments. You can find more information about these metrics in CodeClimate documentation and Rubocop documentation.

Code Quality


Performance

The section of audit is related to applicaiton performance. Datadog is a monitoring tool that helps to identify performance issues in real-time. It can be used to track metrics such as response time, throughput, and error rates. The requirement of requests not exceeding 1s in pt50 is a performance metric that ensures that the backend system is responding quickly to user requests.

You can find this information in APM tab in Datadog. You need to find rails or $APP_NAME-server in Services section and click on it. Choose operation:rack_request and env:production if you've enabled Datadog for several environments. Then you will see Requests section with pt50 and pt95 metrics. You can find more information about these metrics in Datadog documentation.

Datadog

The Bullet gem is used to detect slow database queries and improve performance in development and test environments.

Performance


Security

This section of audit is related to application security. We need to ensure that our users' data are properly protected. Brakeman is a security scanner that checks for security vulnerabilities in Ruby on Rails applications. It helps to identify potential security breaches and provides recommendations for fixing them. The requirement of having 0 critical issues and <5 low or medium issues ensures that the backend system is secure and protected from potential attacks.

Code Quality


Testing

This section of audit is related to testing. SimpleCov is a code coverage analysis tool that helps to identify untested code and improve test coverage. It can be used to track metrics such as lines of code, branches, and methods. The requirement of having at least 80% test coverage ensures that the backend system is well tested and all code paths are covered by tests. To display coverage report in Gitlab CI, add the following lines to .gitlab-ci.yml:

rspec:
  extends: .db
  stage: test
  coverage: '/\(\d+.\d+\%\) covered/'
  script:
    - bundle exec rake assets:precompile
    - bundle exec rspec --profile 10 --format progress --format RspecJunitFormatter --out rspec.xml
  artifacts:
    when: always
    paths:
      - rspec.xml
      - coverage/
    reports:
      coverage_report:
        coverage_format: cobertura
        path: coverage/coverage.xml
      junit: rspec.xml

Then you can find percentage of test coverage in Gitlab CI pipeline on Jobs tab.

Coverage

As you see above, we also use Cobertura format for Test coverage visualization . To generate Cobertura report, add the following lines to spec/spec_helper.rb:

require 'simplecov'
require 'simplecov-cobertura'

SimpleCov.start 'rails' do
  add_filter '/bin/'
  add_filter '/db/'
  add_filter '/spec/' # for rspec
  add_filter '/test/' # for minitest

  add_filter '/app/channels/'
  add_filter '/app/models/'
  add_filter '/app/helpers/'
  add_filter '/app/controllers/admin_panel' # it is optional to write tests for admin panel
  add_filter '/app/controllers/concerns/'
  add_filter '/lib/tasks/'

  add_filter do |source_file|
    source_file.lines.count < 20 # skip files with < 20 lines of code
  end

  add_group 'Forms', 'app/forms'
  add_group 'Policies', 'app/policies'
  add_group 'Services', 'app/services'

  formatter SimpleCov::Formatter::MultiFormatter.new([
                                                       SimpleCov::Formatter::HTMLFormatter,
                                                       SimpleCov::Formatter::CoberturaFormatter
                                                     ])
end

Testing


Documentation

This section is about business logic and API documentation. YARD is a documentation generation tool that helps to create documentation for Ruby on Rails applications. It can be used to generate HTML, PDF, and Markdown documentation from source code comments. The requirement of having all specific business logic documented ensures that the backend system is well documented and easy to understand.

For API documentation we use Postman. It is a tool that helps to create and share API documentation. You need to place all requests related to project in one collection, add examples for request when needed and provide description for request parameters that are not self-explanatory. It will help frontend developers to understand how to use API and what to expect from it.

You also need to provide proper Authorization if request requires one. In most cases it is Bearer token, but sometimes it can be Basic or Digest authentication. You can find more information about authentication in Postman documentation.

Postman authorization

Please provide token variable with valid user token in corresponding Postman environment. It will make faster for other developers to use your collection, because they will not need to create user in advance. You can find more information about environment variables in Postman documentation.

Documentation


Localization

This section is about localization of the project. i18n is a tool that helps to localize Ruby on Rails applications. It can be used to translate text, dates, and numbers into different languages. The requirement of having all specific business logic documented ensures that the backend system is well localized and easy to understand for users from different countries.

You need to check that all strings are translated and there are no untranslated strings. You can find all untranslated strings in config/locales folder. We are checking project for hardcoded strings inside templates with erb-lint and rubocop-i18n for detecting hardcoded strings in Ruby code. We are also using i18n-tasks gem to find missing and unused translations.

To enabled hardcoded strings check in erb-lint add the following lines to .erb-lint.yml:

HardCodedString:
  enabled: true

For rubocop-i18n add the following lines to .rubocop.yml:

require:
  - rubocop-i18n

# Added in version 2.14 of rubocop-rails
Rails/I18nLocaleTexts:
  Enabled: true

Rails/I18nLazyLookup:
  Enabled: true
  EnforcedStyle: explicit

I18n/GetText:
  Enabled: false

I18n/RailsI18n:
  Enabled: true

I18n/RailsI18n/DecorateStringFormattingUsingInterpolation:
  Enabled: false

To ensure that these checks are running in Gitlab CI, add the following lines to .gitlab-ci.yml:

lint_html:
  extends: .base
  stage: lint
  script:
    - bundle exec erblint --lint-all

lint_translations:
  extends: .base
  stage: lint
  script:
    - bundle exec i18n-tasks missing

Localization


CI/CD

This section is about CI/CD configured on project. Gitlab CI is a continuous integration and delivery tool that helps to automate the process of building, testing, and deploying software. It can be used to run tests, generate code coverage reports, and deploy applications to production environments. The requirement of having all tests passing and all code coverage metrics met ensures that the backend system is well tested and ready for deployment.

We need to ensure that all tests are passing and none preventing deployment to dev/staging/production environments. Also we check that commits meet Conventional Commits specification. To do this, add the following lines to .gitlab-ci.yml:

commitlint:
  extends: .base
  stage: lint
  variables:
    NODE_MAJOR: 16
  before_script:
    - curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR.x | bash -
    - apt-get update -qq && DEBIAN_FRONTEND=noninteractive apt-get install -yq --no-install-recommends nodejs
    - npm install -g @commitlint/cli @commitlint/config-conventional
  script:
    - echo "${CI_COMMIT_MESSAGE}" | commitlint

Also you need to specify @commitlint/config-conventional in commitlint.config.js:

module.exports = {
  extends: ['@commitlint/config-conventional'],
};

The next thing we need to check is amount of comments in merge request. It is bad sign if merge request has a lot of comments, because it means that code is not clear enough and needs to be refactored.

Comments


Error monitoring

This section is about Error monitoring. Sentry is a tool that helps to monitor errors in Ruby on Rails applications. It can be used to track errors, exceptions, and crashes in real-time. The requirement of having Sentry added to project and alerts configured ensures that the backend system is well monitored and all errors are tracked.

You need to create project in Sentry and add SENTRY_DSN variable to project either in .env or credentials.yml. You can find more information about how to do it in Sentry documentation.

Then you need to create separate alerts for each environment. We recommend to create alerts for critical and warning levels. You should specify all responsible people for each alert (e.g. backend developers, frontend developers, DevOps engineers that are responsible for this project). You can also specify how often you want to receive notifications (e.g. every 5 minutes, every 30 minutes, every hour. You can find more information about how to do it in Sentry documentation.

Alerts

Also you need to check lifetime of erros on project and make sure that it is less than 7 days. Long lifetime of errors means that you have a lot of errors that are not fixed and it is bad sign. You can use filter firstSeen: with before and specify a datetime week ago to display list of errors that appeared more than 7 days ago.

Issues must not be regressed. It means that if you fixed an issue, it should not appear again.

All issues need to be tracked in JIRA. It should be done by QA engineer or developer that is responsible for this issue. It is important to add all necessary information to JIRA issue (e.g. steps to reproduce, screenshots, logs, etc.). It will help developers to understand the issue and fix it faster.

Error monitoring