Commit 2a46ef4d authored by Robert Speicher's avatar Robert Speicher

Merge branch 'ce-to-ee-2018-10-22' into 'master'

CE upstream - 2018-10-22 13:22 UTC

Closes gitlab-ce#52690, #7996, gitlab-ce#52559, gitlab-ce#52728, and gitlab-qa#142

See merge request gitlab-org/gitlab-ee!8029
parents 59834c30 75c5ab57
......@@ -19,6 +19,7 @@ Closes
- [ ] [Apply the correct labels and milestone](https://docs.gitlab.com/ee/development/documentation/workflow.html#2-developer-s-role-in-the-documentation-process)
- [ ] Crosslink the document from the higher-level index
- [ ] Crosslink the document from other subject-related docs
- [ ] Feature moving tiers? Make sure the change is also reflected in [`features.yml`](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/features.yml)
- [ ] Correctly apply the product [badges](https://docs.gitlab.com/ee/development/documentation/styleguide.html#product-badges) and [tiers](https://docs.gitlab.com/ee/development/documentation/styleguide.html#gitlab-versions-and-tiers)
- [ ] [Port the MR to EE (or backport from CE)](https://docs.gitlab.com/ee/development/documentation/index.html#cherry-picking-from-ce-to-ee): _always recommended, required when the `ee-compat-check` job fails_
......
......@@ -72,7 +72,7 @@ This [documentation](doc/development/contributing/index.md#security-vulnerabilit
## Code of Conduct
This [documentation](doc/development/contributing/index.md#code-of-conduct) has been moved.
This [documentation](https://about.gitlab.com/contributing/code-of-conduct/) has been moved.
## Closing policy for issues and merge requests
......
......@@ -40,7 +40,7 @@ export default function initCompareAutocomplete(limitTo = null, clickHandler = (
},
selectable: true,
filterable: true,
filterRemote: true,
filterRemote: !!$dropdown.data('refsUrl'),
fieldName: $dropdown.data('fieldName'),
filterInput: 'input[type="search"]',
renderRow: function(ref) {
......
......@@ -25,14 +25,32 @@ export default {
},
},
methods: {
createFile(target, file, isText) {
isText(content, fileType) {
const knownBinaryFileTypes = ['image/'];
const knownTextFileTypes = ['text/'];
const isKnownBinaryFileType = knownBinaryFileTypes.find(type => fileType.includes(type));
const isKnownTextFileType = knownTextFileTypes.find(type => fileType.includes(type));
const asciiRegex = /^[ -~\t\n\r]+$/; // tests whether a string contains ascii characters only (ranges from space to tilde, tabs and new lines)
if (isKnownBinaryFileType) {
return false;
}
if (isKnownTextFileType) {
return true;
}
// if it's not a known file type, determine the type by evaluating the file contents
return asciiRegex.test(content);
},
createFile(target, file) {
const { name } = file;
let { result } = target;
const encodedContent = result.split('base64,')[1];
const rawContent = encodedContent ? atob(encodedContent) : '';
const isText = this.isText(rawContent, file.type);
if (!isText) {
// eslint-disable-next-line prefer-destructuring
result = result.split('base64,')[1];
}
result = isText ? rawContent : encodedContent;
this.$emit('create', {
name: `${this.path ? `${this.path}/` : ''}${name}`,
......@@ -43,15 +61,9 @@ export default {
},
readFile(file) {
const reader = new FileReader();
const isText = file.type.match(/text.*/) !== null;
reader.addEventListener('load', e => this.createFile(e.target, file, isText), { once: true });
if (isText) {
reader.readAsText(file);
} else {
reader.addEventListener('load', e => this.createFile(e.target, file), { once: true });
reader.readAsDataURL(file);
}
},
openFile() {
Array.from(this.$refs.fileUpload.files).forEach(file => this.readFile(file));
......
......@@ -6,11 +6,9 @@ class Admin::ApplicationsController < Admin::ApplicationController
before_action :set_application, only: [:show, :edit, :update, :destroy]
before_action :load_scopes, only: [:new, :create, :edit, :update]
# rubocop: disable CodeReuse/ActiveRecord
def index
@applications = Doorkeeper::Application.where("owner_id IS NULL")
@applications = ApplicationsFinder.new.execute
end
# rubocop: enable CodeReuse/ActiveRecord
def show
end
......@@ -49,11 +47,9 @@ class Admin::ApplicationsController < Admin::ApplicationController
private
# rubocop: disable CodeReuse/ActiveRecord
def set_application
@application = Doorkeeper::Application.where("owner_id IS NULL").find(params[:id])
@application = ApplicationsFinder.new(id: params[:id]).execute
end
# rubocop: enable CodeReuse/ActiveRecord
# Only allow a trusted parameter "white list" through.
def application_params
......
......@@ -9,7 +9,7 @@ class Projects::BlobController < Projects::ApplicationController
include ActionView::Helpers::SanitizeHelper
prepend_before_action :authenticate_user!, only: [:edit]
before_action :set_request_format, only: [:edit, :show, :update]
before_action :set_request_format, only: [:edit, :show, :update, :destroy]
before_action :require_non_empty_project, except: [:new, :create]
before_action :authorize_download_code!
......
# frozen_string_literal: true
class ApplicationsFinder
attr_reader :params
def initialize(params = {})
@params = params
end
def execute
applications = Doorkeeper::Application.where(owner_id: nil) # rubocop: disable CodeReuse/ActiveRecord
by_id(applications)
end
private
def by_id(applications)
return applications unless params[:id]
Doorkeeper::Application.find_by(id: params[:id]) # rubocop: disable CodeReuse/ActiveRecord
end
end
......@@ -21,17 +21,15 @@ module TimeHelper
"#{from.to_s(:short)} - #{to.to_s(:short)}"
end
def duration_in_numbers(duration_in_seconds, allow_overflow = false)
if allow_overflow
def duration_in_numbers(duration_in_seconds)
seconds = duration_in_seconds % 1.minute
minutes = (duration_in_seconds / 1.minute) % (1.hour / 1.minute)
hours = duration_in_seconds / 1.hour
"%02d:%02d:%02d" % [hours, minutes, seconds]
if hours == 0
"%02d:%02d" % [minutes, seconds]
else
time_format = duration_in_seconds < 1.hour ? "%M:%S" : "%H:%M:%S"
Time.at(duration_in_seconds).utc.strftime(time_format)
"%02d:%02d:%02d" % [hours, minutes, seconds]
end
end
end
......@@ -29,11 +29,15 @@ module Ci
metadata: :gzip,
trace: :raw,
junit: :gzip,
codequality: :gzip,
sast: :gzip,
dependency_scanning: :gzip,
container_scanning: :gzip,
dast: :gzip
# All these file formats use `raw` as we need to store them uncompressed
# for Frontend to fetch the files and do analysis
# When they will be only used by backend, they can be `gzipped`.
codequality: :raw,
sast: :raw,
dependency_scanning: :raw,
container_scanning: :raw,
dast: :raw
}.freeze
belongs_to :project
......@@ -103,7 +107,8 @@ module Ci
}
FILE_FORMAT_ADAPTERS = {
gzip: Gitlab::Ci::Build::Artifacts::GzipFileAdapter
gzip: Gitlab::Ci::Build::Artifacts::Adapters::GzipStream,
raw: Gitlab::Ci::Build::Artifacts::Adapters::RawStream
}.freeze
def valid_file_format?
......
......@@ -17,7 +17,7 @@ class MicrosoftTeamsService < ChatNotificationService
'This service sends notifications about projects events to Microsoft Teams channels.<br />
To set up this service:
<ol>
<li><a href="https://msdn.microsoft.com/en-us/microsoft-teams/connectors">Getting started with 365 Office Connectors For Microsoft Teams</a>.</li>
<li><a href="https://docs.microsoft.com/en-us/microsoftteams/platform/concepts/connectors/connectors-using#setting-up-a-custom-incoming-webhook">Setup a custom Incoming Webhook using Office 365 Connectors For Microsoft Teams</a>.</li>
<li>Paste the <strong>Webhook URL</strong> into the field below.</li>
<li>Select events below to enable notifications.</li>
</ol>'
......
......@@ -30,12 +30,12 @@ module Ci
def create_reports(reports, expire_in:)
return unless reports&.any?
reports.map do |k, v|
reports.map do |report_type, report_paths|
{
artifact_type: k.to_sym,
artifact_format: :gzip,
name: ::Ci::JobArtifact::DEFAULT_FILE_NAMES[k.to_sym],
paths: v,
artifact_type: report_type.to_sym,
artifact_format: ::Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.fetch(report_type.to_sym),
name: ::Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(report_type.to_sym),
paths: report_paths,
when: 'always',
expire_in: expire_in
}
......
......@@ -108,7 +108,7 @@
.btn.btn-default.has-tooltip{ disabled: true,
title: job.scheduled_at }
= sprite_icon('planning')
= duration_in_numbers(job.execute_in, true)
= duration_in_numbers(job.execute_in)
- confirmation_message = s_("DelayedJobs|Are you sure you want to run %{job_name} immediately? This job will run automatically after it's timer finishes.") % { job_name: job.name }
= link_to play_project_job_path(job.project, job, return_to: request.original_url),
method: :post,
......
---
title: Add Applications API endpoints for listing and deleting entries.
merge_request: 22296
author: Jean-Baptiste Vasseur
type: added
---
title: Drop `allow_overflow` option in `TimeHelper.duration_in_numbers`
merge_request: 52284
author:
type: changed
---
title: Remove base64 encoding from files that contain plain text
merge_request: 22425
author:
type: fixed
---
title: Enable frozen string for lib/gitlab/*.rb
merge_request:
author: gfyoung
type: performance
---
title: Fixed source project not filtering in merge request creation compare form
merge_request:
author:
type: fixed
---
title: 'Rails5: fix delete blob'
merge_request: 22456
author: Jasper Maes
type: other
---
title: Make all legacy security reports to use raw format
merge_request:
author:
type: changed
......@@ -7,8 +7,8 @@ Sidekiq::Testing.inline! do
'https://gitlab.com/gitlab-org/gitlab-shell.git',
'https://gitlab.com/gnuwget/wget2.git',
'https://gitlab.com/Commit451/LabCoat.git',
'https://github.com/documentcloud/underscore.git',
'https://github.com/twitter/flight.git',
'https://github.com/jashkenas/underscore.git',
'https://github.com/flightjs/flight.git',
'https://github.com/twitter/typeahead.js.git',
'https://github.com/h5bp/html5-boilerplate.git',
'https://github.com/google/material-design-lite.git',
......@@ -20,18 +20,18 @@ Sidekiq::Testing.inline! do
'https://github.com/airbnb/javascript.git',
'https://github.com/tessalt/echo-chamber-js.git',
'https://github.com/atom/atom.git',
'https://github.com/mattermost/platform.git',
'https://github.com/mattermost/mattermost-server.git',
'https://github.com/purifycss/purifycss.git',
'https://github.com/facebook/nuclide.git',
'https://github.com/wbkd/awesome-d3.git',
'https://github.com/kilimchoi/engineering-blogs.git',
'https://github.com/gilbarbara/logos.git',
'https://github.com/gaearon/redux.git',
'https://github.com/reduxjs/redux.git',
'https://github.com/awslabs/s2n.git',
'https://github.com/arkency/reactjs_koans.git',
'https://github.com/twbs/bootstrap.git',
'https://github.com/chjj/ttystudio.git',
'https://github.com/DrBoolean/mostly-adequate-guide.git',
'https://github.com/MostlyAdequate/mostly-adequate-guide.git',
'https://github.com/octocat/Spoon-Knife.git',
'https://github.com/opencontainers/runc.git',
'https://github.com/googlesamples/android-topeka.git'
......
require './spec/support/sidekiq'
class Gitlab::Seeder::Pipelines
STAGES = %w[build test deploy notify]
STAGES = %w[build test security deploy notify]
BUILDS = [
# build stage
{ name: 'build:linux', stage: 'build', status: :success,
......@@ -31,6 +31,16 @@ class Gitlab::Seeder::Pipelines
{ name: 'spinach:osx', stage: 'test', status: :failed, allow_failure: true,
queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago },
# security stage
{ name: 'dast', stage: 'security', status: :success,
queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago },
{ name: 'sast', stage: 'security', status: :success,
queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago },
{ name: 'dependency_scanning', stage: 'security', status: :success,
queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago },
{ name: 'container_scanning', stage: 'security', status: :success,
queued_at: 8.hour.ago, started_at: 8.hour.ago, finished_at: 7.hour.ago },
# deploy stage
{ name: 'staging', stage: 'deploy', environment: 'staging', status_event: :success,
options: { environment: { action: 'start', on_stop: 'stop staging' } },
......@@ -115,6 +125,11 @@ class Gitlab::Seeder::Pipelines
setup_artifacts(build)
setup_test_reports(build)
if build.ref == build.project.default_branch
setup_security_reports_file(build)
else
setup_security_reports_legacy_archive(build)
end
setup_build_log(build)
build.project.environments.
......@@ -150,6 +165,55 @@ class Gitlab::Seeder::Pipelines
end
end
def setup_security_reports_file(build)
return unless build.stage == "security"
# we have two sources: master and feature-branch
branch_name = build.ref == build.project.default_branch ?
'master' : 'feature-branch'
artifacts_cache_file(security_reports_path(branch_name, build.name)) do |file|
build.job_artifacts.build(
project: build.project,
file_type: build.name,
file_format: :raw,
file: file)
end
end
def setup_security_reports_legacy_archive(build)
return unless build.stage == "security"
# we have two sources: master and feature-branch
branch_name = build.ref == build.project.default_branch ?
'master' : 'feature-branch'
artifacts_cache_file(security_reports_archive_path(branch_name)) do |file|
build.job_artifacts.build(
project: build.project,
file_type: :archive,
file_format: :zip,
file: file)
end
# assign dummy metadata
artifacts_cache_file(artifacts_metadata_path) do |file|
build.job_artifacts.build(
project: build.project,
file_type: :metadata,
file_format: :gzip,
file: file)
end
build.options = {
artifacts: {
paths: [
Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(build.name.to_sym)
]
}
}
end
def setup_build_log(build)
if %w(running success failed).include?(build.status)
build.trace.set(FFaker::Lorem.paragraphs(6).join("\n\n"))
......@@ -201,6 +265,15 @@ class Gitlab::Seeder::Pipelines
Rails.root + 'spec/fixtures/junit/junit.xml.gz'
end
def security_reports_archive_path(branch)
Rails.root.join('spec', 'fixtures', 'security-reports', branch + '.zip')
end
def security_reports_path(branch, name)
file_name = Ci::JobArtifact::DEFAULT_FILE_NAMES.fetch(name.to_sym)
Rails.root.join('spec', 'fixtures', 'security-reports', branch, file_name)
end
def artifacts_cache_file(file_path)
file = Tempfile.new("artifacts")
file.close
......
......@@ -4,12 +4,12 @@
[ce-8160]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8160
Only admin user can use the Applications API.
## Create a application
Create a application by posting a JSON payload.
User must be admin to do that.
Returns `200` if the request succeeds.
```
......@@ -30,8 +30,55 @@ Example response:
```json
{
"id":1,
"application_id": "5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737",
"application_name": "MyApplication",
"secret": "ee1dd64b6adc89cf7e2c23099301ccc2c61b441064e9324d963c46902a85ec34",
"callback_url": "http://redirect.uri"
}
```
## List all applications
List all registered applications.
```
GET /applications
```
```bash
curl --request GET --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/applications
```
Example response:
```json
[
{
"id":1,
"application_id": "5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737",
"application_name": "MyApplication",
"callback_url": "http://redirect.uri"
}
]
```
> Note: the `secret` value will not be exposed by this API.
## Delete an application
Delete a specific application.
Returns `204` if the request succeeds.
```
DELETE /applications/:id
```
Parameters:
- `id` (required) - The id of the application (not the application_id)
```bash
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/applications/:id
```
......@@ -14,7 +14,7 @@ GET /projects/:id/repository/tree
Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `path` (optional) - The path inside repository. Used to get contend of subdirectories
- `path` (optional) - The path inside repository. Used to get content of subdirectories
- `ref` (optional) - The name of a repository branch or tag or if not given the default branch
- `recursive` (optional) - Boolean value used to get a recursive tree (false by default)
......
......@@ -25,7 +25,7 @@ before_script:
- apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823
- apt-get update -y
- apt-get install sbt -y
- sbt sbt-version
- sbt sbtVersion
test:
stage: test
......
......@@ -3,6 +3,8 @@
Thank you for your interest in contributing to GitLab. This guide details how
to contribute to GitLab in a way that is easy for everyone.
We want to create a welcoming environment for everyone who is interested in contributing. Please visit our [Code of Conduct page](https://about.gitlab.com/contributing/code-of-conduct) to learn more about our committment to an open and welcoming environment.
For a first-time step-by-step guide to the contribution process, please see
["Contributing to GitLab"](https://about.gitlab.com/contributing/).
......@@ -28,80 +30,6 @@ Please report suspected security vulnerabilities in private to
Please do **NOT** create publicly viewable issues for suspected security
vulnerabilities.
## Code of conduct
### Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
### Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
### Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
### Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
### Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at conduct@gitlab.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
### Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
## Closing policy for issues and merge requests
GitLab is a popular open source project and the capacity to deal with issues
......
......@@ -472,6 +472,37 @@ GitLab uses [factory_bot] as a test fixture replacement.
All fixtures should be be placed under `spec/fixtures/`.
### Repositories
Testing some functionality, e.g., merging a merge request, requires a git
repository with a certain state to be present in the test environment. GitLab
maintains the [gitlab-test](https://gitlab.com/gitlab-org/gitlab-test)
repository for certain common cases - you can ensure a copy of the repository is
used with the `:repository` trait for project factories:
```ruby
let(:project) { create(:project, :repository) }
```
Where you can, consider using the `:custom_repo` trait instead of `:repository`.
This allows you to specify exactly what files will appear in the `master` branch
of the project's repository. For example:
```ruby
let(:project) do
create(
:project, :custom_repo,
files: {
'README.md' => 'Content here',
'foo/bar/baz.txt' => 'More content here'
}
)
end
```
This will create a repository containing two files, with default permissions and
the specified content.
### Config
RSpec config files are files that change the RSpec config (i.e.
......
......@@ -24,6 +24,22 @@ module API
render_validation_error! application
end
end
desc 'Get applications' do
success Entities::Application
end
get do
applications = ApplicationsFinder.new.execute
present applications, with: Entities::Application
end
desc 'Delete an application'
delete ':id' do
application = ApplicationsFinder.new(params).execute
application.destroy
status 204
end
end
end
end
......@@ -1440,7 +1440,9 @@ module API
end
class Application < Grape::Entity
expose :id
expose :uid, as: :application_id
expose :name, as: :application_name
expose :redirect_uri, as: :callback_url
end
......
......@@ -164,7 +164,7 @@ module Backup
def tar_version
tar_version, _ = Gitlab::Popen.popen(%w(tar --version))
tar_version.force_encoding('locale').split("\n").first
tar_version.dup.force_encoding('locale').split("\n").first
end
def skipped?(item)
......
# frozen_string_literal: true
# Gitlab::Access module
#
# Define allowed roles that can be used
......
# frozen_string_literal: true
module Gitlab
# This class implements a simple rate limiter that can be used to throttle
# certain actions. Unlike Rack Attack and Rack::Throttle, which operate at
......
# frozen_string_literal: true
module Gitlab
module Allowable
def can?(*args)
......
# frozen_string_literal: true
module Gitlab
class AppLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
require 'asciidoctor'
require 'asciidoctor/converter/html5'
require "asciidoctor-plantuml"
......
# frozen_string_literal: true
module Gitlab
module Auth
MissingPersonalAccessTokenError = Class.new(StandardError)
......
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
def self.queue
......
# frozen_string_literal: true
# This is a base controller for doorkeeper.
# It adds the `can?` helper used in the views.
module Gitlab
......
# frozen_string_literal: true
module Gitlab
class Blame
attr_accessor :blob, :commit
......
# frozen_string_literal: true
# This has been extracted from https://github.com/github/linguist/blob/master/lib/linguist/blob_helper.rb
module Gitlab
module BlobHelper
......
# frozen_string_literal: true
module Gitlab
class BuildAccess < UserAccess
attr_accessor :user, :project
......
# frozen_string_literal: true
module Gitlab
class ChangesList
include Enumerable
......
# frozen_string_literal: true
require 'json'
module Gitlab
......
module Gitlab
module Ci
module Build
module Artifacts
module Adapters
class GzipStream
attr_reader :stream
InvalidStreamError = Class.new(StandardError)
def initialize(stream)
raise InvalidStreamError, "Stream is required" unless stream
@stream = stream
end
def each_blob
stream.seek(0)
until stream.eof?
gzip(stream) do |gz|
yield gz.read, gz.orig_name
unused = gz.unused&.length.to_i
# pos has already reached to EOF at the moment
# We rewind the pos to the top of unused files
# to read next gzip stream, to support multistream archives
# https://golang.org/src/compress/gzip/gunzip.go#L117
stream.seek(-unused, IO::SEEK_CUR)
end
end
end
private
def gzip(stream, &block)
gz = Zlib::GzipReader.new(stream)
yield(gz)
rescue Zlib::Error => e
raise InvalidStreamError, e.message
ensure
gz&.finish
end
end
end
end
end
end
end
module Gitlab
module Ci
module Build
module Artifacts
module Adapters
class RawStream
attr_reader :stream
InvalidStreamError = Class.new(StandardError)
def initialize(stream)
raise InvalidStreamError, "Stream is required" unless stream
@stream = stream
end
def each_blob
stream.seek(0)
yield(stream.read, 'raw') unless stream.eof?
end
end
end
end
end
end
end
module Gitlab
module Ci
module Build
module Artifacts
class GzipFileAdapter
attr_reader :stream
InvalidStreamError = Class.new(StandardError)
def initialize(stream)
raise InvalidStreamError, "Stream is required" unless stream
@stream = stream
end
def each_blob
stream.seek(0)
until stream.eof?
gzip(stream) do |gz|
yield gz.read, gz.orig_name
unused = gz.unused&.length.to_i
# pos has already reached to EOF at the moment
# We rewind the pos to the top of unused files
# to read next gzip stream, to support multistream archives
# https://golang.org/src/compress/gzip/gunzip.go#L117
stream.seek(-unused, IO::SEEK_CUR)
end
end
end
private
def gzip(stream, &block)
gz = Zlib::GzipReader.new(stream)
yield(gz)
rescue Zlib::Error => e
raise InvalidStreamError, e.message
ensure
gz&.finish
end
end
end
end
end
end
......@@ -29,7 +29,7 @@ module Gitlab
def execute_in
remaining_seconds = [0, subject.scheduled_at - Time.now].max
duration_in_numbers(remaining_seconds, true)
duration_in_numbers(remaining_seconds)
end
end
end
......
# frozen_string_literal: true
module Gitlab
# For backwards compatibility, generic CI (which is a build without a user) is
# allowed to :build_download_code without any other checks.
......
# frozen_string_literal: true
module Gitlab
class ClosingIssueExtractor
ISSUE_CLOSING_REGEX = begin
......
# frozen_string_literal: true
module Gitlab
# Module containing GitLab's syntax color scheme definitions and helper
# methods for accessing them.
......
# frozen_string_literal: true
module Gitlab::ConfigHelper
def gitlab_config_features
Gitlab.config.gitlab.default_projects_features
......
# frozen_string_literal: true
module Gitlab
class ContributionsCalendar
attr_reader :contributor
......
# frozen_string_literal: true
module Gitlab
class Contributor
attr_accessor :email, :name, :commits, :additions, :deletions
......
# frozen_string_literal: true
module Gitlab
class CrossProjectAccess
class << self
......
# frozen_string_literal: true
module Gitlab
module CurrentSettings
class << self
......
# frozen_string_literal: true
module Gitlab
class Daemon
def self.initialize_instance(*args)
......
# frozen_string_literal: true
module Gitlab
module Database
# The max value of INTEGER type is the same between MySQL and PostgreSQL:
......@@ -109,11 +111,11 @@ module Gitlab
order = "#{field} #{direction}"
if postgresql?
order << ' NULLS LAST'
order = "#{order} NULLS LAST"
else
# `field IS NULL` will be `0` for non-NULL columns and `1` for NULL
# columns. In the (default) ascending order, `0` comes first.
order.prepend("#{field} IS NULL, ") if direction == 'ASC'
order = "#{field} IS NULL, #{order}" if direction == 'ASC'
end
order
......@@ -123,11 +125,11 @@ module Gitlab
order = "#{field} #{direction}"
if postgresql?
order << ' NULLS FIRST'
order = "#{order} NULLS FIRST"
else
# `field IS NULL` will be `0` for non-NULL columns and `1` for NULL
# columns. In the (default) ascending order, `0` comes first.
order.prepend("#{field} IS NULL, ") if direction == 'DESC'
order = "#{field} IS NULL, #{order}" if direction == 'DESC'
end
order
......@@ -198,7 +200,7 @@ module Gitlab
EOF
if return_ids
sql << 'RETURNING id'
sql = "#{sql}RETURNING id"
end
result = connection.execute(sql)
......
# frozen_string_literal: true
module Gitlab
module DependencyLinker
LINKERS = [
......
# frozen_string_literal: true
module Gitlab
# Checks if a set of migrations requires downtime or not.
class DowntimeCheck
......
# frozen_string_literal: true
# rubocop: disable Rails/Output
module Gitlab
# Checks if a set of migrations requires downtime or not.
......
# frozen_string_literal: true
module Gitlab
module Emoji
extend self
......
# frozen_string_literal: true
module Gitlab
module EncodingHelper
extend self
......
# frozen_string_literal: true
module Gitlab
module Environment
def self.hostname
......
# frozen_string_literal: true
module Gitlab
class EnvironmentLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
require 'securerandom'
module Gitlab
......
# frozen_string_literal: true
module Gitlab
# This module provides helper methods which are intregrated with GitLab::ExclusiveLease
module ExclusiveLeaseHelpers
......
# frozen_string_literal: true
# This class extends an OpenStruct object by adding predicate methods to mimic
# ActiveRecord access. We rely on the initial values being true or false to
# determine whether to define a predicate method because for a newly-added
......
# frozen_string_literal: true
module Gitlab
class Favicon
class << self
......
# frozen_string_literal: true
require 'set'
module Gitlab
......
# frozen_string_literal: true
# This class finds files in a repository by name and content
# the result is joined and sorted by file name
module Gitlab
......
# frozen_string_literal: true
# Builds the markdown link of a file
# It needs the methods filename and secure_url (final destination url) to be defined.
module Gitlab
......@@ -8,7 +10,7 @@ module Gitlab
return unless name = markdown_name
markdown = "[#{name.gsub(']', '\\]')}](#{secure_url})"
markdown.prepend("!") if image_or_video? || dangerous?
markdown = "!#{markdown}" if image_or_video? || dangerous?
markdown
end
......
# frozen_string_literal: true
require_dependency 'gitlab/encoding_helper'
module Gitlab
......
# frozen_string_literal: true
# Check a user's access to perform a git action. All public methods in this
# class return an instance of `GitlabAccessStatus`
module Gitlab
......
# frozen_string_literal: true
module Gitlab
class GitAccessWiki < GitAccess
prepend EE::Gitlab::GitAccessWiki
......
# frozen_string_literal: true
module Gitlab
class GitLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
# Gitaly note: JV: does not need to be migrated, works without a repo.
module Gitlab
......
# frozen_string_literal: true
require 'base64'
require 'gitaly'
......@@ -23,7 +25,7 @@ module Gitlab
stacks = most_invoked_stack.join('\n') if most_invoked_stack
msg = "GitalyClient##{call_site} called #{invocation_count} times from single request. Potential n+1?"
msg << "\nThe following call site called into Gitaly #{max_call_stack} times:\n#{stacks}\n" if stacks
msg = "#{msg}\nThe following call site called into Gitaly #{max_call_stack} times:\n#{stacks}\n" if stacks
super(msg)
end
......
# frozen_string_literal: true
module Gitlab
module GithubImport
def self.refmap
......
# frozen_string_literal: true
module Gitlab
module GlId
def self.gl_id(user)
......
# frozen_string_literal: true
module Gitlab
module GlRepository
def self.gl_repository(project, is_wiki)
......
# frozen_string_literal: true
# rubocop:disable Metrics/AbcSize
module Gitlab
......
# frozen_string_literal: true
module Gitlab
module Gpg
extend self
......
# frozen_string_literal: true
module Gitlab
module Graphql
StandardGraphqlError = Class.new(StandardError)
......
# frozen_string_literal: true
module Gitlab
# Retrieving of parent or child groups based on a base ActiveRecord relation.
#
......
# frozen_string_literal: true
module Gitlab
class Highlight
TIMEOUT_BACKGROUND = 30.seconds
......
# frozen_string_literal: true
# This class is used as a proxy for all outbounding http connection
# coming from callbacks, services and hooks. The direct use of the HTTParty
# is discouraged because it can lead to several security problems, like SSRF
......
# frozen_string_literal: true
##
# This class is compatible with IO class (https://ruby-doc.org/core-2.3.1/IO.html)
# source: https://gitlab.com/snippets/1685610
......@@ -73,8 +75,8 @@ module Gitlab
end
end
def read(length = nil, outbuf = "")
out = ""
def read(length = nil, outbuf = nil)
out = []
length ||= size - tell
......@@ -90,17 +92,18 @@ module Gitlab
length -= chunk_data.bytesize
end
out = out.join
# If outbuf is passed, we put the output into the buffer. This supports IO.copy_stream functionality
if outbuf
outbuf.slice!(0, outbuf.bytesize)
outbuf << out
outbuf.replace(out)
end
out
end
def readline
out = ""
out = []
until eof?
data = get_chunk
......@@ -116,7 +119,7 @@ module Gitlab
end
end
out
out.join
end
def write(data)
......
# frozen_string_literal: true
module Gitlab
module I18n
extend self
......
# frozen_string_literal: true
# Detect user based on identifier like
# key-13 or user-36 or last commit
module Gitlab
......
# frozen_string_literal: true
module Gitlab
module ImportExport
extend self
......
# frozen_string_literal: true
module Gitlab
class ImportFormatter
def comment(author, date, body)
......
# frozen_string_literal: true
# Gitlab::ImportSources module
#
# Define import sources that can be used
......
# frozen_string_literal: true
module Gitlab
module IncomingEmail
UNSUBSCRIBE_SUFFIX = '+unsubscribe'.freeze
......
# frozen_string_literal: true
module Gitlab
#
# Calculates the fingerprint of a given key without using
......
# frozen_string_literal: true
module Gitlab
module IssuableMetadata
def issuable_meta_data(issuable_collection, collection_type)
......
# frozen_string_literal: true
module Gitlab
module IssuableSorter
class << self
......
# frozen_string_literal: true
module Gitlab
# Class for counting and caching the number of issuables per state.
class IssuablesCountForState
......
# frozen_string_literal: true
module Gitlab
class IssuesLabels
class << self
......
# frozen_string_literal: true
module Gitlab
# JobWaiter can be used to wait for a number of Sidekiq jobs to complete.
#
......
# frozen_string_literal: true
module Gitlab
class JsonLogger < ::Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
module Gitlab
# Helper methods to do with Kubernetes network services & resources
module Kubernetes
......
# frozen_string_literal: true
module Gitlab
class LanguageDetection
MAX_LANGUAGES = 5
......
# frozen_string_literal: true
module Gitlab
# A class that can be wrapped around an expensive method call so it's only
# executed when actually needed.
......
# frozen_string_literal: true
module Gitlab
class LfsToken
attr_accessor :actor
......
# frozen_string_literal: true
module Gitlab
class Logger < ::Logger
def self.file_name
......
# frozen_string_literal: true
require 'yaml'
require 'json'
require_relative 'redis/queues' unless defined?(Gitlab::Redis::Queues)
......
# frozen_string_literal: true
module Gitlab
module MarkupHelper
extend self
......
# frozen_string_literal: true
module Gitlab
module Metrics
include Gitlab::Metrics::InfluxDb
......
# frozen_string_literal: true
module Gitlab
class MultiCollectionPaginator
attr_reader :first_collection, :second_collection, :per_page
......
# frozen_string_literal: true
module Gitlab
class OmniauthInitializer
prepend ::EE::Gitlab::OmniauthInitializer
......
# frozen_string_literal: true
module Gitlab
module OptimisticLocking
module_function
......
# frozen_string_literal: true
module Gitlab
# Parser/renderer for markups without other special support code.
module OtherMarkup
......
# frozen_string_literal: true
module Gitlab
# The +otp_key_base+ param is used to encrypt the User#otp_secret attribute.
#
......
# frozen_string_literal: true
module Gitlab
module Pages
VERSION = File.read(Rails.root.join("GITLAB_PAGES_VERSION")).strip.freeze
......
# frozen_string_literal: true
module Gitlab
class PagesClient
class << self
......
# frozen_string_literal: true
module Gitlab
class PagesTransfer < ProjectTransfer
def root_dir
......
# frozen_string_literal: true
module Gitlab
module PathRegex
extend self
......
# frozen_string_literal: true
module Gitlab
module PerformanceBar
ALLOWED_USER_IDS_KEY = 'performance_bar_allowed_user_ids:v2'.freeze
......
# frozen_string_literal: true
module Gitlab
module Plugin
def self.files
......
# frozen_string_literal: true
module Gitlab
class PluginLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
module Gitlab
class PollingInterval
HEADER_NAME = 'Poll-Interval'.freeze
......
# frozen_string_literal: true
require 'fileutils'
require 'open3'
......@@ -11,7 +13,7 @@ module Gitlab
def popen(cmd, path = nil, vars = {}, &block)
result = popen_with_detail(cmd, path, vars, &block)
[result.stdout << result.stderr, result.status&.exitstatus]
["#{result.stdout}#{result.stderr}", result.status&.exitstatus]
end
# Returns Result
......
# coding: utf-8
# frozen_string_literal: true
module Gitlab
module Profiler
FILTERED_STRING = '[FILTERED]'.freeze
......
# frozen_string_literal: true
module Gitlab
class ProjectSearchResults < SearchResults
attr_reader :project, :repository_ref
......@@ -57,7 +59,8 @@ module Gitlab
ref = nil
filename = nil
basename = nil
data = ""
data = []
startline = 0
result.each_line.each_with_index do |line, index|
......@@ -78,7 +81,7 @@ module Gitlab
basename: basename,
ref: ref,
startline: startline,
data: data,
data: data.join,
project_id: project ? project.id : nil
)
end
......
# frozen_string_literal: true
module Gitlab
class ProjectServiceLogger < Gitlab::JsonLogger
def self.file_name_noext
......
# frozen_string_literal: true
module Gitlab
class ProjectTemplate
attr_reader :title, :name, :description, :preview
......
# frozen_string_literal: true
module Gitlab
# This class is used to move local, unhashed files owned by projects to their new location
class ProjectTransfer
......
# frozen_string_literal: true
module Gitlab
# Helper methods to interact with Prometheus network services & resources
class PrometheusClient
......
# frozen_string_literal: true
module Gitlab
module ProtocolAccess
def self.allowed?(protocol)
......
# frozen_string_literal: true
# This class is part of the Gitlab::HTTP wrapper. Depending on the value
# of the global setting allow_local_requests_from_hooks_and_services this adapter
# will allow/block connection to internal IPs and/or urls.
......
# frozen_string_literal: true
module Gitlab
module QueryLimiting
# Returns true if we should enable tracking of query counts.
......
# frozen_string_literal: true
module Gitlab
module Recaptcha
def self.load_configurations!
......
# frozen_string_literal: true
module Gitlab
class ReferenceCounter
REFERENCE_EXPIRE_TIME = 600
......
# frozen_string_literal: true
module Gitlab
# Extract possible GFM references from an arbitrary String for further processing.
class ReferenceExtractor < Banzai::ReferenceExtractor
......
# frozen_string_literal: true
module Gitlab
module Regex
extend self
......
# frozen_string_literal: true
module Gitlab
module RepoPath
NotFoundError = Class.new(StandardError)
......
# frozen_string_literal: true
# Interface to the Redis-backed cache store
module Gitlab
class RepositoryCache
......@@ -6,7 +8,7 @@ module Gitlab
def initialize(repository, extra_namespace: nil, backend: Rails.cache)
@repository = repository
@namespace = "#{repository.full_path}:#{repository.project.id}"
@namespace += ":#{extra_namespace}" if extra_namespace
@namespace = "#{@namespace}:#{extra_namespace}" if extra_namespace
@backend = backend
end
......
# frozen_string_literal: true
module Gitlab
module RepositoryCacheAdapter
extend ActiveSupport::Concern
......
# frozen_string_literal: true
module Gitlab
class RepositoryCheckLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
module Gitlab
class RequestContext
class << self
......
# frozen_string_literal: true
# A module to check CSRF tokens in requests.
# It's used in API helpers and OmniAuth.
# Usage: GitLab::RequestForgeryProtection.call(env)
......
# frozen_string_literal: true
require 'fileutils'
module Gitlab
......
# frozen_string_literal: true
module Gitlab
class RouteMap
FormatError = Class.new(StandardError)
......
# frozen_string_literal: true
module Gitlab
module Routing
extend ActiveSupport::Concern
......@@ -47,7 +49,7 @@ module Gitlab
#
# `request.fullpath` includes the querystring
new_path = request.path.sub(%r{/#{path}(/*)(?!.*#{path})}, "/-/#{path}\\1")
new_path << "?#{request.query_string}" if request.query_string.present?
new_path = "#{new_path}?#{request.query_string}" if request.query_string.present?
new_path
end
......
# frozen_string_literal: true
module Gitlab
class SearchResults
class FoundBlob
......
# frozen_string_literal: true
# :nocov:
module DeliverNever
def deliver_later
......
# frozen_string_literal: true
module Gitlab
module Sentry
def self.enabled?
......
# frozen_string_literal: true
require 'toml-rb'
module Gitlab
......
# frozen_string_literal: true
module Gitlab
class ShardHealthCache
HEALTHY_SHARDS_KEY = 'gitlab-healthy-shards'.freeze
......
# frozen_string_literal: true
# Gitaly note: SSH key operations are not part of Gitaly so will never be migrated.
require 'securerandom'
......
# frozen_string_literal: true
# == GitLab Shell mixin
#
# Provide a shortcut to Gitlab::Shell instance by gitlab_shell
......
# frozen_string_literal: true
require 'securerandom'
module Gitlab
......
# frozen_string_literal: true
require 'yaml'
require 'set'
......
# frozen_string_literal: true
module Gitlab
class SidekiqLogger < Gitlab::Logger
def self.file_name_noext
......
# frozen_string_literal: true
module Gitlab
# The SidekiqStatus module and its child classes can be used for checking if a
# Sidekiq job has been processed or not.
......
# frozen_string_literal: true
module Gitlab
module SidekiqVersioning
def self.install!
......
# frozen_string_literal: true
module Gitlab
class SnippetSearchResults < SearchResults
include SnippetsHelper
......
# frozen_string_literal: true
module Gitlab
class SSHPublicKey
Technology = Struct.new(:name, :key_class, :supported_sizes)
......@@ -26,7 +28,7 @@ module Gitlab
return key_content if parts.empty?
parts.each_with_object("#{ssh_type} ").with_index do |(part, content), index|
parts.each_with_object(+"#{ssh_type} ").with_index do |(part, content), index|
content << part
if Gitlab::SSHPublicKey.new(content).valid?
......
# frozen_string_literal: true
module Gitlab
class StringPlaceholderReplacer
# This method accepts the following paras
......
# frozen_string_literal: true
module Gitlab
class StringRangeMarker
attr_accessor :raw_line, :rich_line, :html_escaped
......
# frozen_string_literal: true
module Gitlab
class StringRegexMarker < StringRangeMarker
# rubocop: disable CodeReuse/ActiveRecord
......
# frozen_string_literal: true
require 'rainbow/ext/string'
require 'gitlab/utils/strong_memoize'
......@@ -39,7 +41,7 @@ module Gitlab
File.read('/etc/os-release').match(/PRETTY_NAME=\"(.+)\"/)[1]
end
os_name.try(:squish!)
os_name.try(:squish)
end
# Prompt the user to input something
......
# frozen_string_literal: true
module Gitlab
class TcpChecker
attr_reader :remote_host, :remote_port, :local_host, :local_port, :error
......
# frozen_string_literal: true
module Gitlab
module TemplateHelper
def prepare_template_environment(file)
......
# frozen_string_literal: true
module Gitlab
module TemporarilyAllow
TEMPORARILY_ALLOW_MUTEX = Mutex.new
......
# frozen_string_literal: true
module Gitlab
# Module containing GitLab's application theme definitions and helper methods
# for accessing them.
......
# frozen_string_literal: true
module Gitlab
module TimeTrackingFormatter
extend self
......
# frozen_string_literal: true
module Gitlab
module Timeless
def self.timeless(model, &block)
......
# frozen_string_literal: true
module Gitlab
class TreeSummary
prepend ::EE::Gitlab::TreeSummary
......
# frozen_string_literal: true
module Gitlab
# An untrusted regular expression is any regexp containing patterns sourced
# from user input.
......
# frozen_string_literal: true
module Gitlab
UpdatePathError = Class.new(StandardError)
end
# frozen_string_literal: true
module Gitlab
class Upgrader
def execute
......
# frozen_string_literal: true
module Gitlab
class UploadsTransfer < ProjectTransfer
def root_dir
......
# frozen_string_literal: true
require 'resolv'
module Gitlab
......
# frozen_string_literal: true
module Gitlab
class UrlBuilder
include Gitlab::Routing
......
# frozen_string_literal: true
module Gitlab
class UrlSanitizer
ALLOWED_SCHEMES = %w[http https ssh git].freeze
......
# frozen_string_literal: true
module Gitlab
class UsageData
class << self
......
# frozen_string_literal: true
module Gitlab
class UserAccess
extend Gitlab::Cache::RequestCache
......
# frozen_string_literal: true
module Gitlab
module Utils
extend self
......
# frozen_string_literal: true
module Gitlab
class VersionInfo
include Comparable
......
# frozen_string_literal: true
# Gitlab::VisibilityLevel module
#
# Define allowed public modes that can be used for
......
# frozen_string_literal: true
module Gitlab
class WikiFileFinder < FileFinder
attr_reader :repository
......
# frozen_string_literal: true
require 'base64'
require 'json'
require 'securerandom'
......@@ -63,7 +65,7 @@ module Gitlab
def send_git_archive(repository, ref:, format:, append_sha:)
format ||= 'tar.gz'
format.downcase!
format = format.downcase
params = repository.archive_metadata(ref, Gitlab.config.gitlab.repository_downloads_path, format, append_sha: append_sha)
raise "Repository or ref not found" if params.empty?
......
......@@ -119,11 +119,11 @@ FactoryBot.define do
trait :codequality do
file_type :codequality
file_format :gzip
file_format :raw
after(:build) do |artifact, evaluator|
artifact.file = fixture_file_upload(
Rails.root.join('spec/fixtures/codequality/codequality.json.gz'), 'application/x-gzip')
Rails.root.join('spec/fixtures/codequality/codequality.json'), 'application/json')
end
end
......
......@@ -28,4 +28,29 @@ describe 'Merge request > User creates MR' do
it_behaves_like 'a creatable merge request'
end
end
context 'source project', :js do
let(:user) { create(:user) }
let(:target_project) { create(:project, :public, :repository) }
let(:source_project) { target_project }
before do
source_project.add_maintainer(user)
sign_in(user)
visit project_new_merge_request_path(
target_project,
merge_request: {
source_project_id: source_project.id,
target_project_id: target_project.id
})
end
it 'filters source project' do
find('.js-source-project').click
find('.dropdown-source-project input').set('source')
expect(find('.dropdown-source-project .dropdown-content')).not_to have_content(source_project.name)
end
end
end
......@@ -373,17 +373,15 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
context 'when job starts environment', :js do
let(:environment) { create(:environment, name: 'production', project: project) }
context 'job is successful and has deployment' do
let(:build) { create(:ci_build, :success, :trace_live, environment: environment.name, pipeline: pipeline) }
let!(:deployment) { create(:deployment, environment: environment, project: environment.project, deployable: build) }
before do
visit project_job_path(project, build)
wait_for_requests
# scroll to the top of the page first
execute_script "window.scrollTo(0,0)"
end
context 'job is successful and has deployment' do
let(:build) { create(:ci_build, :success, :trace_live, environment: environment.name, pipeline: pipeline) }
let!(:deployment) { create(:deployment, environment: environment, project: environment.project, deployable: build) }
it 'shows a link for the job' do
expect(page).to have_link environment.name
end
......@@ -398,11 +396,6 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
let(:build) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) }
it 'shows a link for the job' do
visit project_job_path(project, build)
wait_for_requests
# scroll to the top of the page first
execute_script "window.scrollTo(0,0)"
expect(page).to have_link environment.name
expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
end
......@@ -412,11 +405,6 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
it 'shows a link to latest deployment' do
visit project_job_path(project, build)
wait_for_all_requests
# scroll to the top of the page first
execute_script "window.scrollTo(0,0)"
expect(page).to have_link environment.name
expect(page).to have_content 'This job is creating a deployment'
expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
......@@ -453,8 +441,6 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
before do
visit project_job_path(project, job)
wait_for_requests
# scroll to the top of the page first
execute_script "window.scrollTo(0,0)"
end
context 'job with outdated deployment' do
......@@ -484,8 +470,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'shows deployment message' do
expected_text = 'The deployment of this job to staging did not succeed.'
expect(page).to have_css(
'.environment-information', text: expected_text)
expect(page).to have_css('.environment-information', text: expected_text)
end
end
......@@ -498,8 +483,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'shows deployment message' do
expected_text = 'This job is creating a deployment to staging'
expect(page).to have_css(
'.environment-information', text: expected_text)
expect(page).to have_css('.environment-information', text: expected_text)
expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
end
......@@ -509,10 +493,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
it 'shows that deployment will be overwritten' do
expected_text = 'This job is creating a deployment to staging'
expect(page).to have_css(
'.environment-information', text: expected_text)
expect(page).to have_css(
'.environment-information', text: 'latest deployment')
expect(page).to have_css('.environment-information', text: expected_text)
expect(page).to have_css('.environment-information', text: 'latest deployment')
expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
end
end
......
# frozen_string_literal: true
require 'spec_helper'
describe ApplicationsFinder do
let(:application1) { create(:application, name: 'some_application', owner: nil, redirect_uri: 'http://some_application.url', scopes: '') }
let(:application2) { create(:application, name: 'another_application', owner: nil, redirect_uri: 'http://other_application.url', scopes: '') }
describe '#execute' do
it 'returns an array of applications' do
found = described_class.new.execute
expect(found).to match_array([application1, application2])
end
it 'returns the application by id' do
params = { id: application1.id }
found = described_class.new(params).execute
expect(found).to match(application1)
end
end
end
{
"image": "registry.gitlab.com/bikebilly/auto-devops-10-6/feature-branch:e7315ba964febb11bac8f5cd6ec433db8a3a1583",
"unapproved": [
"CVE-2017-15650"
],
"vulnerabilities": [
{
"featurename": "musl",
"featureversion": "1.1.14-r15",
"vulnerability": "CVE-2017-15650",
"namespace": "alpine:v3.4",
"description": "",
"link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15650",
"severity": "Medium",
"fixedby": "1.1.14-r16"
}
]
}
{
"site": {
"alerts": [
{
"sourceid": "3",
"wascid": "15",
"cweid": "16",
"reference": "<p>http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx</p><p>https://www.owasp.org/index.php/List_of_useful_HTTP_headers</p>",
"otherinfo": "<p>This issue still applies to error type pages (401, 403, 500, etc) as those pages are often still affected by injection issues, in which case there is still concern for browsers sniffing pages away from their actual content type.</p><p>At \"High\" threshold this scanner will not alert on client or server error responses.</p>",
"solution": "<p>Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.</p><p>If possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.</p>",
"count": "2",
"pluginid": "10021",
"alert": "X-Content-Type-Options Header Missing",
"name": "X-Content-Type-Options Header Missing",
"riskcode": "1",
"confidence": "2",
"riskdesc": "Low (Medium)",
"desc": "<p>The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.</p>",
"instances": [
{
"param": "X-Content-Type-Options",
"method": "GET",
"uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io"
},
{
"param": "X-Content-Type-Options",
"method": "GET",
"uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io/"
}
]
}
],
"@ssl": "false",
"@port": "80",
"@host": "bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io",
"@name": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io"
},
"@generated": "Fri, 13 Apr 2018 09:22:01",
"@version": "2.7.0"
}
[
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2012-4387",
"url": "http://struts.apache.org/docs/s2-011.html",
"message": "Long parameter name DoS for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
},
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2013-1966",
"url": "http://struts.apache.org/docs/s2-014.html",
"message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
},
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2013-2115",
"url": "http://struts.apache.org/docs/s2-014.html",
"message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
},
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2013-2134",
"url": "http://struts.apache.org/docs/s2-015.html",
"message": "Arbitrary OGNL code execution via unsanitized wildcard matching for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
}
]
{
"licenses": [
{
"count": 13,
"name": "MIT"
},
{
"count": 2,
"name": "New BSD"
},
{
"count": 1,
"name": "LGPL"
}
],
"dependencies": [
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "bundler",
"url": "http://bundler.io",
"description": "The best way to manage your application's dependencies",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "concurrent-ruby",
"url": "http://www.concurrent-ruby.com",
"description": "Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "connection_pool",
"url": "https://github.com/mperham/connection_pool",
"description": "Generic connection pool for Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mini_portile2",
"url": "http://github.com/flavorjones/mini_portile",
"description": "Simplistic port-like solution for developers",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mustermann",
"url": "https://github.com/sinatra/mustermann",
"description": "Your personal string matching expert.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "nokogiri",
"url": "http://nokogiri.org",
"description": "Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser",
"pathes": [
"."
]
}
},
{
"license": {
"name": "New BSD",
"url": "http://opensource.org/licenses/BSD-3-Clause"
},
"dependency": {
"name": "pg",
"url": "https://bitbucket.org/ged/ruby-pg",
"description": "Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]",
"pathes": [
"."
]
}
},
{
"license": {
"name": "New BSD",
"url": "http://opensource.org/licenses/BSD-3-Clause"
},
"dependency": {
"name": "puma",
"url": "http://puma.io",
"description": "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack",
"url": "https://rack.github.io/",
"description": "a modular Ruby webserver interface",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack-protection",
"url": "http://github.com/sinatra/sinatra/tree/master/rack-protection",
"description": "Protect against typical web attacks, works with all Rack apps, including Rails.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "redis",
"url": "https://github.com/redis/redis-rb",
"description": "A Ruby client library for Redis",
"pathes": [
"."
]
}
},
{
"license": {
"name": "LGPL",
"url": "http://www.gnu.org/licenses/lgpl.txt"
},
"dependency": {
"name": "sidekiq",
"url": "http://sidekiq.org",
"description": "Simple, efficient background processing for Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "sinatra",
"url": "http://www.sinatrarb.com/",
"description": "Classy web-development dressed in a DSL",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "slim",
"url": "http://slim-lang.com/",
"description": "Slim is a template language.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "temple",
"url": "https://github.com/judofyr/temple",
"description": "Template compilation framework in Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "tilt",
"url": "http://github.com/rtomayko/tilt/",
"description": "Generic interface to multiple Ruby template engines",
"pathes": [
"."
]
}
}
]
}
[
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 1,
"end_line": 1
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 1,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:47:PREDICTABLE_RANDOM",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 47,
"end_line": 47,
"class": "com.gitlab.security_products.tests.App",
"method": "generateSecretToken2"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-PREDICTABLE_RANDOM",
"value": "PREDICTABLE_RANDOM",
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 47,
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:41:PREDICTABLE_RANDOM",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 41,
"end_line": 41,
"class": "com.gitlab.security_products.tests.App",
"method": "generateSecretToken1"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-PREDICTABLE_RANDOM",
"value": "PREDICTABLE_RANDOM",
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 41,
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 11,
"end_line": 11
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 11,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 12,
"end_line": 12
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 12,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 13,
"end_line": 13
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 13,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 14,
"end_line": 14
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 14,
"tool": "bandit"
},
{
"category": "sast",
"message": "Pickle library appears to be in use, possible security issue.",
"cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 15,
"end_line": 15
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B301",
"value": "B301"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 15,
"tool": "bandit"
},
{
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:ECB_MODE",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 29,
"end_line": 29,
"class": "com.gitlab.security_products.tests.App",
"method": "insecureCypher"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-ECB_MODE",
"value": "ECB_MODE",
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 29,
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:CIPHER_INTEGRITY",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 29,
"end_line": 29,
"class": "com.gitlab.security_products.tests.App",
"method": "insecureCypher"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-CIPHER_INTEGRITY",
"value": "CIPHER_INTEGRITY",
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 29,
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 14,
"end_line": 14
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 14,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 10,
"end_line": 10
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 10,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 1,
"end_line": 1
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 1,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports.py",
"start_line": 2,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports.py",
"line": 2,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports.py",
"start_line": 4,
"end_line": 4
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports.py",
"line": 4,
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 22,
"end_line": 22
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B106",
"value": "B106",
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 22,
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'root'",
"cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 5,
"end_line": 5
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 5,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: ''",
"cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 9,
"end_line": 9
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 9,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'",
"cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 13,
"end_line": 13
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 13,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 23,
"end_line": 23
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 23,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 24,
"end_line": 24
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 24,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-function.py",
"start_line": 4,
"end_line": 4
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-function.py",
"line": 4,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-function.py",
"start_line": 2,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-function.py",
"line": 2,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 7,
"end_line": 7
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 7,
"tool": "bandit"
},
{
"category": "sast",
"message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell",
"cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 9,
"end_line": 9
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B602",
"value": "B602",
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 9,
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 6,
"end_line": 6
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 6,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 1,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 1,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 7,
"end_line": 8
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 7,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with loads module.",
"cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 6,
"end_line": 6
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 6,
"tool": "bandit"
},
{
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120",
"confidence": "Low",
"solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "c/subdir/utils.c",
"start_line": 4
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-119",
"value": "119",
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "c/subdir/utils.c",
"line": 4,
"url": "https://cwe.mitre.org/data/definitions/119.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)",
"cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362",
"confidence": "Low",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "c/subdir/utils.c",
"start_line": 8
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-362",
"value": "362",
"url": "https://cwe.mitre.org/data/definitions/362.html"
}
],
"file": "c/subdir/utils.c",
"line": 8,
"url": "https://cwe.mitre.org/data/definitions/362.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120",
"confidence": "Low",
"solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "cplusplus/src/hello.cpp",
"start_line": 6
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-119",
"value": "119",
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "cplusplus/src/hello.cpp",
"line": 6,
"url": "https://cwe.mitre.org/data/definitions/119.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)",
"cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120",
"confidence": "Low",
"solution": "Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused)",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "cplusplus/src/hello.cpp",
"start_line": 7
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "cplusplus/src/hello.cpp",
"line": 7,
"url": "https://cwe.mitre.org/data/definitions/120.html",
"tool": "flawfinder"
}
]
{
"image": "registry.gitlab.com/bikebilly/auto-devops-10-6/feature-branch:e7315ba964febb11bac8f5cd6ec433db8a3a1583",
"unapproved": [
"CVE-2017-15651"
],
"vulnerabilities": [
{
"featurename": "musl",
"featureversion": "1.1.14-r15",
"vulnerability": "CVE-2017-15651",
"namespace": "alpine:v3.4",
"description": "",
"link": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-15651",
"severity": "Medium",
"fixedby": "1.1.14-r16"
}
]
}
{
"site": {
"alerts": [
{
"sourceid": "3",
"wascid": "15",
"cweid": "16",
"reference": "<p>http://msdn.microsoft.com/en-us/library/ie/gg622941%28v=vs.85%29.aspx</p><p>https://www.owasp.org/index.php/List_of_useful_HTTP_headers</p>",
"otherinfo": "<p>This issue still applies to error type pages (401, 403, 500, etc) as those pages are often still affected by injection issues, in which case there is still concern for browsers sniffing pages away from their actual content type.</p><p>At \"High\" threshold this scanner will not alert on client or server error responses.</p>",
"solution": "<p>Ensure that the application/web server sets the Content-Type header appropriately, and that it sets the X-Content-Type-Options header to 'nosniff' for all web pages.</p><p>If possible, ensure that the end user uses a standards-compliant and modern web browser that does not perform MIME-sniffing at all, or that can be directed by the web application/web server to not perform MIME-sniffing.</p>",
"count": "2",
"pluginid": "10021",
"alert": "X-Content-Type-Options Header Missing",
"name": "X-Content-Type-Options Header Missing",
"riskcode": "1",
"confidence": "2",
"riskdesc": "Low (Medium)",
"desc": "<p>The Anti-MIME-Sniffing header X-Content-Type-Options was not set to 'nosniff'. This allows older versions of Internet Explorer and Chrome to perform MIME-sniffing on the response body, potentially causing the response body to be interpreted and displayed as a content type other than the declared content type. Current (early 2014) and legacy versions of Firefox will use the declared content type (if one is set), rather than performing MIME-sniffing.</p>",
"instances": [
{
"param": "X-Content-Type-Options",
"method": "GET",
"uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io"
},
{
"param": "X-Content-Type-Options",
"method": "GET",
"uri": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io/"
}
]
}
],
"@ssl": "false",
"@port": "80",
"@host": "bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io",
"@name": "http://bikebilly-spring-auto-devops-review-feature-br-3y2gpb.35.192.176.43.xip.io"
},
"@generated": "Fri, 13 Apr 2018 09:22:01",
"@version": "2.7.0"
}
[
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2012-4386",
"url": "http://struts.apache.org/docs/s2-010.html",
"message": "CSRF protection bypass for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
},
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2012-4387",
"url": "http://struts.apache.org/docs/s2-011.html",
"message": "Long parameter name DoS for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
},
{
"priority": "Unknown",
"file": "pom.xml",
"cve": "CVE-2013-1966",
"url": "http://struts.apache.org/docs/s2-014.html",
"message": "Remote command execution due to flaw in the includeParams attribute of URL and Anchor tags for org.apache.struts/struts2-core",
"tools": [
"gemnasium"
],
"tool": "gemnasium"
}
]
{
"licenses": [
{
"count": 10,
"name": "MIT"
}
],
"dependencies": [
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mini_portile2",
"url": "http://github.com/flavorjones/mini_portile",
"description": "Simplistic port-like solution for developers",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "mustermann",
"url": "https://github.com/sinatra/mustermann",
"description": "Your personal string matching expert.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "nokogiri",
"url": "http://nokogiri.org",
"description": "Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack",
"url": "https://rack.github.io/",
"description": "a modular Ruby webserver interface",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "rack-protection",
"url": "http://github.com/sinatra/sinatra/tree/master/rack-protection",
"description": "Protect against typical web attacks, works with all Rack apps, including Rails.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "redis",
"url": "https://github.com/redis/redis-rb",
"description": "A Ruby client library for Redis",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "sinatra",
"url": "http://www.sinatrarb.com/",
"description": "Classy web-development dressed in a DSL",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "slim",
"url": "http://slim-lang.com/",
"description": "Slim is a template language.",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "temple",
"url": "https://github.com/judofyr/temple",
"description": "Template compilation framework in Ruby",
"pathes": [
"."
]
}
},
{
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/mit-license"
},
"dependency": {
"name": "tilt",
"url": "http://github.com/rtomayko/tilt/",
"description": "Generic interface to multiple Ruby template engines",
"pathes": [
"."
]
}
}
]
}
[
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:52865813c884a507be1f152d654245af34aba8a391626d01f1ab6d3f52ec8779:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 1,
"end_line": 1
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 1,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:47:PREDICTABLE_RANDOM",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 47,
"end_line": 47,
"class": "com.gitlab.security_products.tests.App",
"method": "generateSecretToken2"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-PREDICTABLE_RANDOM",
"value": "PREDICTABLE_RANDOM",
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 47,
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"name": "Predictable pseudorandom number generator",
"message": "Predictable pseudorandom number generator",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:41:PREDICTABLE_RANDOM",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 41,
"end_line": 41,
"class": "com.gitlab.security_products.tests.App",
"method": "generateSecretToken1"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-PREDICTABLE_RANDOM",
"value": "PREDICTABLE_RANDOM",
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 41,
"url": "https://find-sec-bugs.github.io/bugs.htm#PREDICTABLE_RANDOM",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:cb203b465dffb0cb3a8e8bd8910b84b93b0a5995a938e4b903dbb0cd6ffa1254:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 11,
"end_line": 11
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 11,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:a7173c43ae66bd07466632d819d450e0071e02dbf782763640d1092981f9631b:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 12,
"end_line": 12
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 12,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:017017b77deb0b8369b6065947833eeea752a92ec8a700db590fece3e934cf0d:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 13,
"end_line": 13
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 13,
"tool": "bandit"
},
{
"category": "sast",
"message": "Use of insecure MD2, MD4, or MD5 hash function.",
"cve": "python/imports/imports-aliases.py:45fc8c53aea7b84f06bc4e590cc667678d6073c4c8a1d471177ca2146fb22db2:B303",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 14,
"end_line": 14
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B303",
"value": "B303"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 14,
"tool": "bandit"
},
{
"category": "sast",
"message": "Pickle library appears to be in use, possible security issue.",
"cve": "python/imports/imports-aliases.py:5f200d47291e7bbd8352db23019b85453ca048dd98ea0c291260fa7d009963a4:B301",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 15,
"end_line": 15
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B301",
"value": "B301"
}
],
"priority": "Medium",
"file": "python/imports/imports-aliases.py",
"line": 15,
"tool": "bandit"
},
{
"category": "sast",
"name": "ECB mode is insecure",
"message": "ECB mode is insecure",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:ECB_MODE",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 29,
"end_line": 29,
"class": "com.gitlab.security_products.tests.App",
"method": "insecureCypher"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-ECB_MODE",
"value": "ECB_MODE",
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 29,
"url": "https://find-sec-bugs.github.io/bugs.htm#ECB_MODE",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"name": "Cipher with no integrity",
"message": "Cipher with no integrity",
"cve": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy:29:CIPHER_INTEGRITY",
"severity": "Medium",
"confidence": "High",
"scanner": {
"id": "find_sec_bugs",
"name": "Find Security Bugs"
},
"location": {
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"start_line": 29,
"end_line": 29,
"class": "com.gitlab.security_products.tests.App",
"method": "insecureCypher"
},
"identifiers": [
{
"type": "find_sec_bugs_type",
"name": "Find Security Bugs-CIPHER_INTEGRITY",
"value": "CIPHER_INTEGRITY",
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY"
}
],
"priority": "Medium",
"file": "groovy/src/main/java/com/gitlab/security_products/tests/App.groovy",
"line": 29,
"url": "https://find-sec-bugs.github.io/bugs.htm#CIPHER_INTEGRITY",
"tool": "find_sec_bugs"
},
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:63dd4d626855555b816985d82c4614a790462a0a3ada89dc58eb97f9c50f3077:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 14,
"end_line": 14
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 14,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Probable insecure usage of temp file/directory.",
"cve": "python/hardcoded/hardcoded-tmp.py:4ad6d4c40a8c263fc265f3384724014e0a4f8dd6200af83e51ff120420038031:B108",
"severity": "Medium",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-tmp.py",
"start_line": 10,
"end_line": 10
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B108",
"value": "B108",
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html"
}
],
"priority": "Medium",
"file": "python/hardcoded/hardcoded-tmp.py",
"line": 10,
"url": "https://docs.openstack.org/bandit/latest/plugins/b108_hardcoded_tmp_directory.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-aliases.py:2c3e1fa1e54c3c6646e8bcfaee2518153c6799b77587ff8d9a7b0631f6d34785:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 1,
"end_line": 1
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 1,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports.py:af58d07f6ad519ef5287fcae65bf1a6999448a1a3a8bc1ac2a11daa80d0b96bf:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports.py",
"start_line": 2,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports.py",
"line": 2,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports.py:8de9bc98029d212db530785a5f6780cfa663548746ff228ab8fa96c5bb82f089:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports.py",
"start_line": 4,
"end_line": 4
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports.py",
"line": 4,
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:97c30f1d76d2a88913e3ce9ae74087874d740f87de8af697a9c455f01119f633:B106",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 22,
"end_line": 22
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B106",
"value": "B106",
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 22,
"url": "https://docs.openstack.org/bandit/latest/plugins/b106_hardcoded_password_funcarg.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'root'",
"cve": "python/hardcoded/hardcoded-passwords.py:7431c73a0bc16d94ece2a2e75ef38f302574d42c37ac0c3c38ad0b3bf8a59f10:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 5,
"end_line": 5
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 5,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: ''",
"cve": "python/hardcoded/hardcoded-passwords.py:d2d1857c27caedd49c57bfbcdc23afcc92bd66a22701fcdc632869aab4ca73ee:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 9,
"end_line": 9
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 9,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'ajklawejrkl42348swfgkg'",
"cve": "python/hardcoded/hardcoded-passwords.py:fb3866215a61393a5c9c32a3b60e2058171a23219c353f722cbd3567acab21d2:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 13,
"end_line": 13
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 13,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:63c62a8b7e1e5224439bd26b28030585ac48741e28ca64561a6071080c560a5f:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 23,
"end_line": 23
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 23,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Possible hardcoded password: 'blerg'",
"cve": "python/hardcoded/hardcoded-passwords.py:4311b06d08df8fa58229b341c531da8e1a31ec4520597bdff920cd5c098d86f9:B105",
"severity": "Low",
"confidence": "Medium",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/hardcoded/hardcoded-passwords.py",
"start_line": 24,
"end_line": 24
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B105",
"value": "B105",
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html"
}
],
"priority": "Low",
"file": "python/hardcoded/hardcoded-passwords.py",
"line": 24,
"url": "https://docs.openstack.org/bandit/latest/plugins/b105_hardcoded_password_string.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-function.py:5858400c2f39047787702de44d03361ef8d954c9d14bd54ee1c2bef9e6a7df93:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-function.py",
"start_line": 4,
"end_line": 4
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-function.py",
"line": 4,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-function.py:dbda3cf4190279d30e0aad7dd137eca11272b0b225e8af4e8bf39682da67d956:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-function.py",
"start_line": 2,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-function.py",
"line": 2,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:eb8a0db9cd1a8c1ab39a77e6025021b1261cc2a0b026b2f4a11fca4e0636d8dd:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 7,
"end_line": 7
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 7,
"tool": "bandit"
},
{
"category": "sast",
"message": "subprocess call with shell=True seems safe, but may be changed in the future, consider rewriting without shell",
"cve": "python/imports/imports-aliases.py:f99f9721e27537fbcb6699a4cf39c6740d6234d2c6f06cfc2d9ea977313c483d:B602",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 9,
"end_line": 9
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B602",
"value": "B602",
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 9,
"url": "https://docs.openstack.org/bandit/latest/plugins/b602_subprocess_popen_with_shell_equals_true.html",
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with subprocess module.",
"cve": "python/imports/imports-from.py:332a12ab1146698f614a905ce6a6a5401497a12281aef200e80522711c69dcf4:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 6,
"end_line": 6
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 6,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with Popen module.",
"cve": "python/imports/imports-from.py:0a48de4a3d5348853a03666cb574697e3982998355e7a095a798bd02a5947276:B404",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-from.py",
"start_line": 1,
"end_line": 2
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B404",
"value": "B404"
}
],
"priority": "Low",
"file": "python/imports/imports-from.py",
"line": 1,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with pickle module.",
"cve": "python/imports/imports-aliases.py:51b71661dff994bde3529639a727a678c8f5c4c96f00d300913f6d5be1bbdf26:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 7,
"end_line": 8
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 7,
"tool": "bandit"
},
{
"category": "sast",
"message": "Consider possible security implications associated with loads module.",
"cve": "python/imports/imports-aliases.py:6ff02aeb3149c01ab68484d794a94f58d5d3e3bb0d58557ef4153644ea68ea54:B403",
"severity": "Low",
"confidence": "High",
"scanner": {
"id": "bandit",
"name": "Bandit"
},
"location": {
"file": "python/imports/imports-aliases.py",
"start_line": 6,
"end_line": 6
},
"identifiers": [
{
"type": "bandit_test_id",
"name": "Bandit Test ID B403",
"value": "B403"
}
],
"priority": "Low",
"file": "python/imports/imports-aliases.py",
"line": 6,
"tool": "bandit"
},
{
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "c/subdir/utils.c:b466873101951fe96e1332f6728eb7010acbbd5dfc3b65d7d53571d091a06d9e:CWE-119!/CWE-120",
"confidence": "Low",
"solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "c/subdir/utils.c",
"start_line": 4
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-119",
"value": "119",
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "c/subdir/utils.c",
"line": 4,
"url": "https://cwe.mitre.org/data/definitions/119.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362)",
"cve": "c/subdir/utils.c:bab681140fcc8fc3085b6bba74081b44ea145c1c98b5e70cf19ace2417d30770:CWE-362",
"confidence": "Low",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "c/subdir/utils.c",
"start_line": 8
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-362",
"value": "362",
"url": "https://cwe.mitre.org/data/definitions/362.html"
}
],
"file": "c/subdir/utils.c",
"line": 8,
"url": "https://cwe.mitre.org/data/definitions/362.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120)",
"cve": "cplusplus/src/hello.cpp:c8c6dd0afdae6814194cf0930b719f757ab7b379cf8f261e7f4f9f2f323a818a:CWE-119!/CWE-120",
"confidence": "Low",
"solution": "Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "cplusplus/src/hello.cpp",
"start_line": 6
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-119",
"value": "119",
"url": "https://cwe.mitre.org/data/definitions/119.html"
},
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "cplusplus/src/hello.cpp",
"line": 6,
"url": "https://cwe.mitre.org/data/definitions/119.html",
"tool": "flawfinder"
},
{
"category": "sast",
"message": "Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120)",
"cve": "cplusplus/src/hello.cpp:331c04062c4fe0c7c486f66f59e82ad146ab33cdd76ae757ca41f392d568cbd0:CWE-120",
"confidence": "Low",
"solution": "Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused)",
"scanner": {
"id": "flawfinder",
"name": "Flawfinder"
},
"location": {
"file": "cplusplus/src/hello.cpp",
"start_line": 7
},
"identifiers": [
{
"type": "cwe",
"name": "CWE-120",
"value": "120",
"url": "https://cwe.mitre.org/data/definitions/120.html"
}
],
"file": "cplusplus/src/hello.cpp",
"line": 7,
"url": "https://cwe.mitre.org/data/definitions/120.html",
"tool": "flawfinder"
}
]
......@@ -22,34 +22,17 @@ describe TimeHelper do
describe "#duration_in_numbers" do
using RSpec::Parameterized::TableSyntax
context "without passing allow_overflow" do
where(:duration, :formatted_string) do
0 | "00:00"
1.second | "00:01"
42.seconds | "00:42"
2.minutes + 1.second | "02:01"
3.hours + 2.minutes + 1.second | "03:02:01"
30.hours | "06:00:00"
end
with_them do
it { expect(duration_in_numbers(duration)).to eq formatted_string }
end
end
context "with allow_overflow = true" do
where(:duration, :formatted_string) do
0 | "00:00:00"
1.second | "00:00:01"
42.seconds | "00:00:42"
2.minutes + 1.second | "00:02:01"
3.hours + 2.minutes + 1.second | "03:02:01"
30.hours | "30:00:00"
end
with_them do
it { expect(duration_in_numbers(duration, true)).to eq formatted_string }
end
it { expect(duration_in_numbers(duration)).to eq formatted_string }
end
end
end
......@@ -40,21 +40,10 @@ describe('new dropdown upload', () => {
describe('readFile', () => {
beforeEach(() => {
spyOn(FileReader.prototype, 'readAsText');
spyOn(FileReader.prototype, 'readAsDataURL');
});
it('calls readAsText for text files', () => {
const file = {
type: 'text/html',
};
vm.readFile(file);
expect(FileReader.prototype.readAsText).toHaveBeenCalledWith(file);
});
it('calls readAsDataURL for non-text files', () => {
it('calls readAsDataURL for all files', () => {
const file = {
type: 'images/png',
};
......@@ -66,32 +55,37 @@ describe('new dropdown upload', () => {
});
describe('createFile', () => {
const target = {
result: 'content',
const textTarget = {
result: 'base64,cGxhaW4gdGV4dA==',
};
const binaryTarget = {
result: 'base64,base64content',
result: 'base64,w4I=',
};
const file = {
name: 'file',
const textFile = {
name: 'textFile',
type: 'text/plain',
};
const binaryFile = {
name: 'binaryFile',
type: 'image/png',
};
it('creates new file', () => {
vm.createFile(target, file, true);
it('creates file in plain text (without encoding) if the file content is plain text', () => {
vm.createFile(textTarget, textFile);
expect(vm.$emit).toHaveBeenCalledWith('create', {
name: file.name,
name: textFile.name,
type: 'blob',
content: target.result,
content: 'plain text',
base64: false,
});
});
it('splits content on base64 if binary', () => {
vm.createFile(binaryTarget, file, false);
vm.createFile(binaryTarget, binaryFile);
expect(vm.$emit).toHaveBeenCalledWith('create', {
name: file.name,
name: binaryFile.name,
type: 'blob',
content: binaryTarget.result.split('base64,')[1],
base64: true,
......
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::GzipFileAdapter do
describe Gitlab::Ci::Build::Artifacts::Adapters::GzipStream do
describe '#initialize' do
context 'when stream is passed' do
let(:stream) { File.open(expand_fixture_path('junit/junit.xml.gz'), 'rb') }
......
require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Adapters::RawStream do
describe '#initialize' do
context 'when stream is passed' do
let(:stream) { File.open(expand_fixture_path('junit/junit.xml'), 'rb') }
it 'initialized' do
expect { described_class.new(stream) }.not_to raise_error
end
end
context 'when stream is not passed' do
let(:stream) { nil }
it 'raises an error' do
expect { described_class.new(stream) }.to raise_error(described_class::InvalidStreamError)
end
end
end
describe '#each_blob' do
let(:adapter) { described_class.new(stream) }
context 'when file is not empty' do
let(:stream) { File.open(expand_fixture_path('junit/junit.xml'), 'rb') }
it 'iterates content' do
expect { |b| adapter.each_blob(&b) }
.to yield_with_args(fixture_file('junit/junit.xml'), 'raw')
end
end
context 'when file is empty' do
let(:stream) { Tempfile.new }
after do
stream.unlink
end
it 'does not iterate content' do
expect { |b| adapter.each_blob(&b) }
.not_to yield_control
end
end
end
end
......@@ -26,9 +26,9 @@ describe Gitlab::Ci::Status::Build::Scheduled do
context 'when scheduled_at is expired' do
let(:build) { create(:ci_build, :expired_scheduled, project: project) }
it 'shows 00:00:00' do
it 'shows 00:00' do
Timecop.freeze do
expect(subject.status_tooltip).to include('00:00:00')
expect(subject.status_tooltip).to include('00:00')
end
end
end
......
......@@ -194,6 +194,14 @@ describe Ci::JobArtifact do
end
end
context 'when file format is raw' do
let(:artifact) { build(:ci_job_artifact, :codequality, file_format: :raw) }
it 'iterates blob once' do
expect { |b| artifact.each_blob(&b) }.to yield_control.once
end
end
context 'when there are no adapters for the file format' do
let(:artifact) { build(:ci_job_artifact, :junit, file_format: :zip) }
......
......@@ -40,6 +40,7 @@ describe Ci::BuildRunnerPresenter do
context "with reports" do
Ci::JobArtifact::DEFAULT_FILE_NAMES.each do |file_type, filename|
context file_type.to_s do
let(:report) { { "#{file_type}": [filename] } }
let(:build) { create(:ci_build, options: { artifacts: { reports: report } } ) }
......@@ -47,7 +48,7 @@ describe Ci::BuildRunnerPresenter do
{
name: filename,
artifact_type: :"#{file_type}",
artifact_format: :gzip,
artifact_format: Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS.fetch(file_type),
paths: [filename],
when: 'always'
}
......@@ -58,6 +59,7 @@ describe Ci::BuildRunnerPresenter do
end
end
end
end
context "when option has both archive and reports specification" do
let(:report) { { junit: ['junit.xml'] } }
......
......@@ -5,6 +5,7 @@ describe API::Applications, :api do
let(:admin_user) { create(:user, admin: true) }
let(:user) { create(:user, admin: false) }
let!(:application) { create(:application, name: 'another_application', redirect_uri: 'http://other_application.url', scopes: '') }
describe 'POST /applications' do
context 'authenticated and authorized user' do
......@@ -15,7 +16,7 @@ describe API::Applications, :api do
application = Doorkeeper::Application.find_by(name: 'application_name', redirect_uri: 'http://application.url')
expect(response).to have_http_status 201
expect(response).to have_gitlab_http_status(201)
expect(json_response).to be_a Hash
expect(json_response['application_id']).to eq application.uid
expect(json_response['secret']).to eq application.secret
......@@ -27,7 +28,7 @@ describe API::Applications, :api do
post api('/applications', admin_user), name: 'application_name', redirect_uri: 'wrong_url_format', scopes: ''
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 400
expect(response).to have_gitlab_http_status(400)
expect(json_response).to be_a Hash
expect(json_response['message']['redirect_uri'][0]).to eq('must be an absolute URI.')
end
......@@ -37,7 +38,7 @@ describe API::Applications, :api do
post api('/applications', admin_user), redirect_uri: 'http://application.url', scopes: ''
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 400
expect(response).to have_gitlab_http_status(400)
expect(json_response).to be_a Hash
expect(json_response['error']).to eq('name is missing')
end
......@@ -47,7 +48,7 @@ describe API::Applications, :api do
post api('/applications', admin_user), name: 'application_name', scopes: ''
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 400
expect(response).to have_gitlab_http_status(400)
expect(json_response).to be_a Hash
expect(json_response['error']).to eq('redirect_uri is missing')
end
......@@ -57,7 +58,7 @@ describe API::Applications, :api do
post api('/applications', admin_user), name: 'application_name', redirect_uri: 'http://application.url'
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 400
expect(response).to have_gitlab_http_status(400)
expect(json_response).to be_a Hash
expect(json_response['error']).to eq('scopes is missing')
end
......@@ -69,7 +70,7 @@ describe API::Applications, :api do
post api('/applications', user), name: 'application_name', redirect_uri: 'http://application.url', scopes: ''
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 403
expect(response).to have_gitlab_http_status(403)
end
end
......@@ -79,7 +80,62 @@ describe API::Applications, :api do
post api('/applications'), name: 'application_name', redirect_uri: 'http://application.url'
end.not_to change { Doorkeeper::Application.count }
expect(response).to have_http_status 401
expect(response).to have_gitlab_http_status(401)
end
end
end
describe 'GET /applications' do
context 'authenticated and authorized user' do
it 'can list application' do
get api('/applications', admin_user)
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_a(Array)
end
end
context 'authorized user without authorization' do
it 'cannot list application' do
get api('/applications', user)
expect(response).to have_gitlab_http_status(403)
end
end
context 'non-authenticated user' do
it 'cannot list application' do
get api('/applications')
expect(response).to have_gitlab_http_status(401)
end
end
end
describe 'DELETE /applications/:id' do
context 'authenticated and authorized user' do
it 'can delete an application' do
expect do
delete api("/applications/#{application.id}", admin_user)
end.to change { Doorkeeper::Application.count }.by(-1)
expect(response).to have_gitlab_http_status(204)
end
end
context 'authorized user without authorization' do
it 'cannot delete an application' do
delete api("/applications/#{application.id}", user)
expect(response).to have_gitlab_http_status(403)
end
end
context 'non-authenticated user' do
it 'cannot delete an application' do
delete api("/applications/#{application.id}")
expect(response).to have_gitlab_http_status(401)
end
end
end
......
......@@ -11,213 +11,135 @@ describe Ci::ProcessBuildService, '#execute' do
project.add_maintainer(user)
end
shared_examples_for 'Enqueuing properly' do |valid_statuses_for_when|
valid_statuses_for_when.each do |status_for_prior_stages|
context "when status for prior stages is #{status_for_prior_stages}" do
let(:current_status) { status_for_prior_stages }
context 'when build has on_success option' do
let(:build) { create(:ci_build, :created, when: :on_success, user: user, project: project) }
%w[created skipped manual scheduled].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) }
context 'when current status is success' do
let(:current_status) { 'success' }
it 'enqueues the build' do
it 'changes the build status' do
expect { subject }.to change { build.status }.to('pending')
end
end
end
%w[pending running success failed canceled].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) }
context 'when current status is failed' do
let(:current_status) { 'failed' }
it 'does not change the build status' do
expect { subject }.not_to change { build.status }
end
end
expect { subject }.to change { build.status }.to('skipped')
end
end
end
(HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages|
let(:current_status) { status_for_prior_stages }
context 'when build has on_failure option' do
let(:build) { create(:ci_build, :created, when: :on_failure, user: user, project: project) }
context "when status for prior stages is #{status_for_prior_stages}" do
%w[created pending].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) }
context 'when current status is success' do
let(:current_status) { 'success' }
it 'skips the build' do
it 'changes the build status' do
expect { subject }.to change { build.status }.to('skipped')
end
end
end
(HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, when: when_option, user: user, project: project) }
context 'when current status is failed' do
let(:current_status) { 'failed' }
it 'does not change build status' do
expect { subject }.not_to change { build.status }
end
end
end
it 'does not change the build status' do
expect { subject }.to change { build.status }.to('pending')
end
end
end
shared_examples_for 'Actionizing properly' do |valid_statuses_for_when|
valid_statuses_for_when.each do |status_for_prior_stages|
context "when status for prior stages is #{status_for_prior_stages}" do
let(:current_status) { status_for_prior_stages }
context 'when build has always option' do
let(:build) { create(:ci_build, :created, when: :always, user: user, project: project) }
%w[created].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) }
context 'when current status is success' do
let(:current_status) { 'success' }
it 'enqueues the build' do
expect { subject }.to change { build.status }.to('manual')
end
it 'changes the build status' do
expect { subject }.to change { build.status }.to('pending')
end
end
%w[manual skipped pending running success failed canceled scheduled].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) }
context 'when current status is failed' do
let(:current_status) { 'failed' }
it 'does not change the build status' do
expect { subject }.not_to change { build.status }
end
end
expect { subject }.to change { build.status }.to('pending')
end
end
end
(HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages|
let(:current_status) { status_for_prior_stages }
context 'when build has manual option' do
let(:build) { create(:ci_build, :created, :actionable, user: user, project: project) }
context "when status for prior stages is #{status_for_prior_stages}" do
%w[created pending].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) }
context 'when current status is success' do
let(:current_status) { 'success' }
it 'skips the build' do
expect { subject }.to change { build.status }.to('skipped')
end
it 'changes the build status' do
expect { subject }.to change { build.status }.to('manual')
end
end
(HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :actionable, user: user, project: project) }
context 'when current status is failed' do
let(:current_status) { 'failed' }
it 'does not change build status' do
expect { subject }.not_to change { build.status }
end
end
end
it 'does not change the build status' do
expect { subject }.to change { build.status }.to('skipped')
end
end
end
shared_examples_for 'Scheduling properly' do |valid_statuses_for_when|
valid_statuses_for_when.each do |status_for_prior_stages|
context "when status for prior stages is #{status_for_prior_stages}" do
let(:current_status) { status_for_prior_stages }
%w[created].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) }
it 'enqueues the build' do
expect { subject }.to change { build.status }.to('scheduled')
end
end
context 'when build has delayed option' do
before do
allow(Ci::BuildScheduleWorker).to receive(:perform_at) { }
end
%w[manual skipped pending running success failed canceled scheduled].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) }
let(:build) { create(:ci_build, :created, :schedulable, user: user, project: project) }
it 'does not change the build status' do
expect { subject }.not_to change { build.status }
end
end
end
end
context 'when ci_enable_scheduled_build is enabled' do
before do
stub_feature_flags(ci_enable_scheduled_build: true)
end
(HasStatus::AVAILABLE_STATUSES - valid_statuses_for_when).each do |status_for_prior_stages|
let(:current_status) { status_for_prior_stages }
context "when status for prior stages is #{status_for_prior_stages}" do
%w[created pending].each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) }
context 'when current status is success' do
let(:current_status) { 'success' }
it 'skips the build' do
expect { subject }.to change { build.status }.to('skipped')
end
it 'changes the build status' do
expect { subject }.to change { build.status }.to('scheduled')
end
end
(HasStatus::AVAILABLE_STATUSES - %w[created pending]).each do |status|
context "when build status is #{status}" do
let(:build) { create(:ci_build, status.to_sym, :schedulable, user: user, project: project) }
context 'when current status is failed' do
let(:current_status) { 'failed' }
it 'does not change build status' do
expect { subject }.not_to change { build.status }
end
end
end
end
end
it 'does not change the build status' do
expect { subject }.to change { build.status }.to('skipped')
end
context 'when build has on_success option' do
let(:when_option) { :on_success }
it_behaves_like 'Enqueuing properly', %w[success skipped]
end
context 'when build has on_failure option' do
let(:when_option) { :on_failure }
it_behaves_like 'Enqueuing properly', %w[failed]
end
context 'when build has always option' do
let(:when_option) { :always }
it_behaves_like 'Enqueuing properly', %w[success failed skipped]
context 'when ci_enable_scheduled_build is disabled' do
before do
stub_feature_flags(ci_enable_scheduled_build: false)
end
context 'when build has manual option' do
let(:when_option) { :manual }
context 'when current status is success' do
let(:current_status) { 'success' }
it_behaves_like 'Actionizing properly', %w[success skipped]
it 'changes the build status' do
expect { subject }.to change { build.status }.to('manual')
end
context 'when build has delayed option' do
let(:when_option) { :delayed }
before do
allow(Ci::BuildScheduleWorker).to receive(:perform_at) { }
end
context 'when ci_enable_scheduled_build is enabled' do
before do
stub_feature_flags(ci_enable_scheduled_build: true)
end
context 'when current status is failed' do
let(:current_status) { 'failed' }
it_behaves_like 'Scheduling properly', %w[success skipped]
it 'does not change the build status' do
expect { subject }.to change { build.status }.to('skipped')
end
context 'when ci_enable_scheduled_build is enabled' do
before do
stub_feature_flags(ci_enable_scheduled_build: false)
end
it_behaves_like 'Actionizing properly', %w[success skipped]
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment