Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
59db98a0
Commit
59db98a0
authored
Mar 04, 2019
by
Yorick Peterse
Browse files
Options
Browse Files
Download
Plain Diff
Merge dev master into GitLab.com master
parents
5c80bbb3
02501504
Changes
131
Hide whitespace changes
Inline
Side-by-side
Showing
131 changed files
with
1577 additions
and
434 deletions
+1577
-434
CHANGELOG.md
CHANGELOG.md
+27
-0
app/assets/javascripts/behaviors/markdown/render_mermaid.js
app/assets/javascripts/behaviors/markdown/render_mermaid.js
+19
-0
app/controllers/concerns/milestone_actions.rb
app/controllers/concerns/milestone_actions.rb
+1
-1
app/controllers/google_api/authorizations_controller.rb
app/controllers/google_api/authorizations_controller.rb
+21
-11
app/controllers/profiles/active_sessions_controller.rb
app/controllers/profiles/active_sessions_controller.rb
+1
-10
app/controllers/projects/autocomplete_sources_controller.rb
app/controllers/projects/autocomplete_sources_controller.rb
+2
-0
app/controllers/projects/commit_controller.rb
app/controllers/projects/commit_controller.rb
+5
-1
app/controllers/projects/group_links_controller.rb
app/controllers/projects/group_links_controller.rb
+3
-2
app/finders/merge_requests_finder.rb
app/finders/merge_requests_finder.rb
+8
-1
app/graphql/types/project_type.rb
app/graphql/types/project_type.rb
+0
-2
app/mailers/emails/issues.rb
app/mailers/emails/issues.rb
+1
-0
app/models/active_session.rb
app/models/active_session.rb
+4
-2
app/models/clusters/platforms/kubernetes.rb
app/models/clusters/platforms/kubernetes.rb
+1
-1
app/models/concerns/issuable.rb
app/models/concerns/issuable.rb
+11
-0
app/models/concerns/milestoneish.rb
app/models/concerns/milestoneish.rb
+9
-2
app/models/merge_request.rb
app/models/merge_request.rb
+4
-5
app/models/merge_request_diff.rb
app/models/merge_request_diff.rb
+2
-0
app/models/project_services/prometheus_service.rb
app/models/project_services/prometheus_service.rb
+5
-1
app/policies/group_policy.rb
app/policies/group_policy.rb
+3
-0
app/policies/project_policy.rb
app/policies/project_policy.rb
+2
-0
app/services/issuable_base_service.rb
app/services/issuable_base_service.rb
+6
-0
app/services/issues/build_service.rb
app/services/issues/build_service.rb
+3
-1
app/services/merge_requests/build_service.rb
app/services/merge_requests/build_service.rb
+1
-0
app/services/projects/group_links/create_service.rb
app/services/projects/group_links/create_service.rb
+8
-2
app/uploaders/file_mover.rb
app/uploaders/file_mover.rb
+8
-0
app/validators/sha_validator.rb
app/validators/sha_validator.rb
+9
-0
app/views/notify/issue_moved_email.html.haml
app/views/notify/issue_moved_email.html.haml
+7
-4
app/views/notify/issue_moved_email.text.erb
app/views/notify/issue_moved_email.text.erb
+4
-0
app/views/profiles/active_sessions/_active_session.html.haml
app/views/profiles/active_sessions/_active_session.html.haml
+0
-6
app/views/projects/blob/viewers/_dependency_manager.html.haml
...views/projects/blob/viewers/_dependency_manager.html.haml
+0
-5
changelogs/unreleased/2802-security-add-public-internal-groups-as-members-to-your-project-idor.yml
...ublic-internal-groups-as-members-to-your-project-idor.yml
+6
-0
changelogs/unreleased/51971-milestones-visibility.yml
changelogs/unreleased/51971-milestones-visibility.yml
+5
-0
changelogs/unreleased/57534_filter_impersonated_sessions.yml
changelogs/unreleased/57534_filter_impersonated_sessions.yml
+6
-0
changelogs/unreleased/security-2797-milestone-mrs.yml
changelogs/unreleased/security-2797-milestone-mrs.yml
+5
-0
changelogs/unreleased/security-2798-fix-boards-policy.yml
changelogs/unreleased/security-2798-fix-boards-policy.yml
+5
-0
changelogs/unreleased/security-2799-emails.yml
changelogs/unreleased/security-2799-emails.yml
+5
-0
changelogs/unreleased/security-50334.yml
changelogs/unreleased/security-50334.yml
+5
-0
changelogs/unreleased/security-55468-check-validity-before-querying.yml
...eleased/security-55468-check-validity-before-querying.yml
+5
-0
changelogs/unreleased/security-56348.yml
changelogs/unreleased/security-56348.yml
+5
-0
changelogs/unreleased/security-commit-private-related-mr.yml
changelogs/unreleased/security-commit-private-related-mr.yml
+5
-0
changelogs/unreleased/security-fj-diff-import-file-read-fix.yml
...logs/unreleased/security-fj-diff-import-file-read-fix.yml
+5
-0
changelogs/unreleased/security-id-restricted-access-to-private-repo.yml
...eleased/security-id-restricted-access-to-private-repo.yml
+5
-0
changelogs/unreleased/security-issue_54789_2.yml
changelogs/unreleased/security-issue_54789_2.yml
+5
-0
changelogs/unreleased/security-kubernetes-google-login-csrf.yml
...logs/unreleased/security-kubernetes-google-login-csrf.yml
+5
-0
changelogs/unreleased/security-kubernetes-local-ssrf.yml
changelogs/unreleased/security-kubernetes-local-ssrf.yml
+5
-0
changelogs/unreleased/security-mermaid.yml
changelogs/unreleased/security-mermaid.yml
+5
-0
changelogs/unreleased/security-osw-stop-linking-to-packages.yml
...logs/unreleased/security-osw-stop-linking-to-packages.yml
+5
-0
changelogs/unreleased/security-protect-private-repo-information.yml
.../unreleased/security-protect-private-repo-information.yml
+5
-0
changelogs/unreleased/security-shared-project-private-group.yml
...logs/unreleased/security-shared-project-private-group.yml
+5
-0
changelogs/unreleased/security-tags-oracle.yml
changelogs/unreleased/security-tags-oracle.yml
+5
-0
config/routes/git_http.rb
config/routes/git_http.rb
+1
-1
doc/user/profile/active_sessions.md
doc/user/profile/active_sessions.md
+1
-7
doc/user/profile/img/active_sessions_list.png
doc/user/profile/img/active_sessions_list.png
+0
-0
lib/api/commits.rb
lib/api/commits.rb
+9
-1
lib/api/entities.rb
lib/api/entities.rb
+5
-4
lib/api/environments.rb
lib/api/environments.rb
+4
-4
lib/api/helpers/notes_helpers.rb
lib/api/helpers/notes_helpers.rb
+3
-11
lib/api/projects.rb
lib/api/projects.rb
+20
-19
lib/api/release/links.rb
lib/api/release/links.rb
+2
-0
lib/constraints/project_url_constrainer.rb
lib/constraints/project_url_constrainer.rb
+2
-1
lib/gitlab/auth/omniauth_identity_linker_base.rb
lib/gitlab/auth/omniauth_identity_linker_base.rb
+5
-1
lib/gitlab/dependency_linker/base_linker.rb
lib/gitlab/dependency_linker/base_linker.rb
+18
-0
lib/gitlab/dependency_linker/composer_json_linker.rb
lib/gitlab/dependency_linker/composer_json_linker.rb
+2
-2
lib/gitlab/dependency_linker/gemfile_linker.rb
lib/gitlab/dependency_linker/gemfile_linker.rb
+25
-5
lib/gitlab/dependency_linker/gemspec_linker.rb
lib/gitlab/dependency_linker/gemspec_linker.rb
+1
-1
lib/gitlab/dependency_linker/method_linker.rb
lib/gitlab/dependency_linker/method_linker.rb
+7
-3
lib/gitlab/dependency_linker/package.rb
lib/gitlab/dependency_linker/package.rb
+19
-0
lib/gitlab/dependency_linker/package_json_linker.rb
lib/gitlab/dependency_linker/package_json_linker.rb
+7
-14
lib/gitlab/dependency_linker/parser/gemfile.rb
lib/gitlab/dependency_linker/parser/gemfile.rb
+40
-0
lib/gitlab/dependency_linker/podfile_linker.rb
lib/gitlab/dependency_linker/podfile_linker.rb
+10
-1
lib/gitlab/dependency_linker/podspec_linker.rb
lib/gitlab/dependency_linker/podspec_linker.rb
+1
-1
lib/gitlab/import_export/merge_request_parser.rb
lib/gitlab/import_export/merge_request_parser.rb
+11
-0
lib/gitlab/kubernetes/kube_client.rb
lib/gitlab/kubernetes/kube_client.rb
+8
-0
locale/gitlab.pot
locale/gitlab.pot
+3
-0
spec/controllers/dashboard/milestones_controller_spec.rb
spec/controllers/dashboard/milestones_controller_spec.rb
+1
-1
spec/controllers/google_api/authorizations_controller_spec.rb
.../controllers/google_api/authorizations_controller_spec.rb
+41
-19
spec/controllers/groups/shared_projects_controller_spec.rb
spec/controllers/groups/shared_projects_controller_spec.rb
+2
-0
spec/controllers/omniauth_callbacks_controller_spec.rb
spec/controllers/omniauth_callbacks_controller_spec.rb
+1
-1
spec/controllers/projects/autocomplete_sources_controller_spec.rb
...trollers/projects/autocomplete_sources_controller_spec.rb
+31
-0
spec/controllers/projects/group_links_controller_spec.rb
spec/controllers/projects/group_links_controller_spec.rb
+37
-0
spec/controllers/snippets_controller_spec.rb
spec/controllers/snippets_controller_spec.rb
+4
-0
spec/features/issues_spec.rb
spec/features/issues_spec.rb
+2
-2
spec/features/merge_request/user_sees_versions_spec.rb
spec/features/merge_request/user_sees_versions_spec.rb
+5
-1
spec/features/merge_requests/user_lists_merge_requests_spec.rb
...features/merge_requests/user_lists_merge_requests_spec.rb
+2
-2
spec/features/profiles/active_sessions_spec.rb
spec/features/profiles/active_sessions_spec.rb
+22
-26
spec/features/projects/blobs/blob_show_spec.rb
spec/features/projects/blobs/blob_show_spec.rb
+1
-4
spec/features/projects/members/invite_group_spec.rb
spec/features/projects/members/invite_group_spec.rb
+2
-0
spec/features/projects/settings/user_manages_group_links_spec.rb
...atures/projects/settings/user_manages_group_links_spec.rb
+1
-0
spec/features/security/group/private_access_spec.rb
spec/features/security/group/private_access_spec.rb
+28
-4
spec/finders/merge_requests_finder_spec.rb
spec/finders/merge_requests_finder_spec.rb
+25
-1
spec/lib/constraints/project_url_constrainer_spec.rb
spec/lib/constraints/project_url_constrainer_spec.rb
+4
-0
spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb
...lib/gitlab/dependency_linker/composer_json_linker_spec.rb
+2
-2
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
+6
-3
spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
+2
-2
spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
.../lib/gitlab/dependency_linker/package_json_linker_spec.rb
+13
-5
spec/lib/gitlab/dependency_linker/parser/gemfile_spec.rb
spec/lib/gitlab/dependency_linker/parser/gemfile_spec.rb
+42
-0
spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
+4
-1
spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
+2
-2
spec/lib/gitlab/import_export/merge_request_parser_spec.rb
spec/lib/gitlab/import_export/merge_request_parser_spec.rb
+16
-0
spec/lib/gitlab/kubernetes/kube_client_spec.rb
spec/lib/gitlab/kubernetes/kube_client_spec.rb
+30
-0
spec/mailers/notify_spec.rb
spec/mailers/notify_spec.rb
+46
-8
spec/models/active_session_spec.rb
spec/models/active_session_spec.rb
+4
-1
spec/models/clusters/platforms/kubernetes_spec.rb
spec/models/clusters/platforms/kubernetes_spec.rb
+16
-0
spec/models/concerns/issuable_spec.rb
spec/models/concerns/issuable_spec.rb
+89
-8
spec/models/concerns/milestoneish_spec.rb
spec/models/concerns/milestoneish_spec.rb
+46
-1
spec/models/issue/metrics_spec.rb
spec/models/issue/metrics_spec.rb
+3
-3
spec/models/merge_request_diff_spec.rb
spec/models/merge_request_diff_spec.rb
+13
-1
spec/models/milestone_spec.rb
spec/models/milestone_spec.rb
+4
-4
spec/models/project_services/prometheus_service_spec.rb
spec/models/project_services/prometheus_service_spec.rb
+43
-18
spec/policies/commit_policy_spec.rb
spec/policies/commit_policy_spec.rb
+53
-0
spec/policies/group_policy_spec.rb
spec/policies/group_policy_spec.rb
+40
-0
spec/policies/note_policy_spec.rb
spec/policies/note_policy_spec.rb
+45
-49
spec/policies/project_policy_spec.rb
spec/policies/project_policy_spec.rb
+12
-8
spec/requests/api/commits_spec.rb
spec/requests/api/commits_spec.rb
+13
-2
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+1
-1
spec/requests/api/projects_spec.rb
spec/requests/api/projects_spec.rb
+69
-2
spec/requests/api/release/links_spec.rb
spec/requests/api/release/links_spec.rb
+16
-0
spec/requests/git_http_spec.rb
spec/requests/git_http_spec.rb
+70
-64
spec/services/issuable/common_system_notes_service_spec.rb
spec/services/issuable/common_system_notes_service_spec.rb
+2
-2
spec/services/issues/build_service_spec.rb
spec/services/issues/build_service_spec.rb
+38
-38
spec/services/issues/update_service_spec.rb
spec/services/issues/update_service_spec.rb
+3
-3
spec/services/merge_requests/build_service_spec.rb
spec/services/merge_requests/build_service_spec.rb
+9
-0
spec/services/merge_requests/update_service_spec.rb
spec/services/merge_requests/update_service_spec.rb
+3
-3
spec/services/projects/group_links/create_service_spec.rb
spec/services/projects/group_links/create_service_spec.rb
+8
-0
spec/support/helpers/file_mover_helpers.rb
spec/support/helpers/file_mover_helpers.rb
+12
-0
spec/support/helpers/login_helpers.rb
spec/support/helpers/login_helpers.rb
+8
-5
spec/support/shared_examples/issuable_shared_examples.rb
spec/support/shared_examples/issuable_shared_examples.rb
+1
-1
spec/support/shared_examples/requests/api/discussions.rb
spec/support/shared_examples/requests/api/discussions.rb
+31
-0
spec/uploaders/file_mover_spec.rb
spec/uploaders/file_mover_spec.rb
+31
-2
spec/validators/sha_validator_spec.rb
spec/validators/sha_validator_spec.rb
+40
-0
spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
...ers/update_head_pipeline_for_merge_request_worker_spec.rb
+1
-1
No files found.
CHANGELOG.md
View file @
59db98a0
...
@@ -486,6 +486,33 @@ entry.
...
@@ -486,6 +486,33 @@ entry.
-
Update url placeholder for the sentry configuration page. !24338
-
Update url placeholder for the sentry configuration page. !24338
## 11.6.10 (2019-02-28)
### Security (21 changes)
-
Stop linking to unrecognized package sources. !55518
-
Check snippet attached file to be moved is within designated directory.
-
Fix potential Addressable::URI::InvalidURIError.
-
Do not display impersonated sessions under active sessions and remove ability to revoke session.
-
Display only information visible to current user on the Milestone page.
-
Show only merge requests visible to user on milestone detail page.
-
Disable issue boards API when issues are disabled.
-
Don't show new issue link after move when a user does not have permissions.
-
Fix git clone revealing private repo's presence.
-
Fix blind SSRF in Prometheus integration by checking URL before querying.
-
Check if desired milestone for an issue is available.
-
Don't allow non-members to see private related MRs.
-
Fix arbitrary file read via diffs during import.
-
Display the correct number of MRs a user has access to.
-
Forbid creating discussions for users with restricted access.
-
Do not disclose milestone titles for unauthorized users.
-
Validate session key when authorizing with GCP to create a cluster.
-
Block local URLs for Kubernetes integration.
-
Limit mermaid rendering to 5K characters.
-
Remove the possibility to share a project with a group that a user is not a member of.
-
Fix leaking private repository information in API.
## 11.6.8 (2019-01-30)
## 11.6.8 (2019-01-30)
-
No changes.
-
No changes.
...
...
app/assets/javascripts/behaviors/markdown/render_mermaid.js
View file @
59db98a0
import
flash
from
'
~/flash
'
;
import
flash
from
'
~/flash
'
;
import
{
sprintf
,
__
}
from
'
../../locale
'
;
// Renders diagrams and flowcharts from text using Mermaid in any element with the
// Renders diagrams and flowcharts from text using Mermaid in any element with the
// `js-render-mermaid` class.
// `js-render-mermaid` class.
...
@@ -14,6 +15,9 @@ import flash from '~/flash';
...
@@ -14,6 +15,9 @@ import flash from '~/flash';
// </pre>
// </pre>
//
//
// This is an arbitary number; Can be iterated upon when suitable.
const
MAX_CHAR_LIMIT
=
5000
;
export
default
function
renderMermaid
(
$els
)
{
export
default
function
renderMermaid
(
$els
)
{
if
(
!
$els
.
length
)
return
;
if
(
!
$els
.
length
)
return
;
...
@@ -34,6 +38,21 @@ export default function renderMermaid($els) {
...
@@ -34,6 +38,21 @@ export default function renderMermaid($els) {
$els
.
each
((
i
,
el
)
=>
{
$els
.
each
((
i
,
el
)
=>
{
const
source
=
el
.
textContent
;
const
source
=
el
.
textContent
;
/**
* Restrict the rendering to a certain amount of character to
* prevent mermaidjs from hanging up the entire thread and
* causing a DoS.
*/
if
(
source
&&
source
.
length
>
MAX_CHAR_LIMIT
)
{
el
.
textContent
=
sprintf
(
__
(
'
Cannot render the image. Maximum character count (%{charLimit}) has been exceeded.
'
,
),
{
charLimit
:
MAX_CHAR_LIMIT
},
);
return
;
}
// Remove any extra spans added by the backend syntax highlighting.
// Remove any extra spans added by the backend syntax highlighting.
Object
.
assign
(
el
,
{
textContent
:
source
});
Object
.
assign
(
el
,
{
textContent
:
source
});
...
...
app/controllers/concerns/milestone_actions.rb
View file @
59db98a0
...
@@ -8,7 +8,7 @@ module MilestoneActions
...
@@ -8,7 +8,7 @@ module MilestoneActions
format
.
html
{
redirect_to
milestone_redirect_path
}
format
.
html
{
redirect_to
milestone_redirect_path
}
format
.
json
do
format
.
json
do
render
json:
tabs_json
(
"shared/milestones/_merge_requests_tab"
,
{
render
json:
tabs_json
(
"shared/milestones/_merge_requests_tab"
,
{
merge_requests:
@milestone
.
sorted_merge_requests
,
# rubocop:disable Gitlab/ModuleWithInstanceVariables
merge_requests:
@milestone
.
sorted_merge_requests
(
current_user
)
,
# rubocop:disable Gitlab/ModuleWithInstanceVariables
show_project_name:
true
show_project_name:
true
})
})
end
end
...
...
app/controllers/google_api/authorizations_controller.rb
View file @
59db98a0
...
@@ -2,6 +2,10 @@
...
@@ -2,6 +2,10 @@
module
GoogleApi
module
GoogleApi
class
AuthorizationsController
<
ApplicationController
class
AuthorizationsController
<
ApplicationController
include
Gitlab
::
Utils
::
StrongMemoize
before_action
:validate_session_key!
def
callback
def
callback
token
,
expires_at
=
GoogleApi
::
CloudPlatform
::
Client
token
,
expires_at
=
GoogleApi
::
CloudPlatform
::
Client
.
new
(
nil
,
callback_google_api_auth_url
)
.
new
(
nil
,
callback_google_api_auth_url
)
...
@@ -11,21 +15,27 @@ module GoogleApi
...
@@ -11,21 +15,27 @@ module GoogleApi
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
]
=
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
]
=
expires_at
.
to_s
expires_at
.
to_s
state_redirect_uri
=
redirect_uri_from_session_key
(
params
[
:state
])
redirect_to
redirect_uri_from_session
if
state_redirect_uri
redirect_to
state_redirect_uri
else
redirect_to
root_path
end
end
end
private
private
def
redirect_uri_from_session_key
(
state
)
def
validate_session_key!
key
=
GoogleApi
::
CloudPlatform
::
Client
access_denied!
unless
redirect_uri_from_session
.
present?
.
session_key_for_redirect_uri
(
params
[
:state
])
end
session
[
key
]
if
key
def
redirect_uri_from_session
strong_memoize
(
:redirect_uri_from_session
)
do
if
params
[
:state
].
present?
session
[
session_key_for_redirect_uri
(
params
[
:state
])]
else
nil
end
end
end
def
session_key_for_redirect_uri
(
state
)
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_redirect_uri
(
state
)
end
end
end
end
end
end
app/controllers/profiles/active_sessions_controller.rb
View file @
59db98a0
...
@@ -2,15 +2,6 @@
...
@@ -2,15 +2,6 @@
class
Profiles::ActiveSessionsController
<
Profiles
::
ApplicationController
class
Profiles::ActiveSessionsController
<
Profiles
::
ApplicationController
def
index
def
index
@sessions
=
ActiveSession
.
list
(
current_user
)
@sessions
=
ActiveSession
.
list
(
current_user
).
reject
(
&
:is_impersonated
)
end
def
destroy
ActiveSession
.
destroy
(
current_user
,
params
[
:id
])
respond_to
do
|
format
|
format
.
html
{
redirect_to
profile_active_sessions_url
,
status: :found
}
format
.
js
{
head
:ok
}
end
end
end
end
end
app/controllers/projects/autocomplete_sources_controller.rb
View file @
59db98a0
# frozen_string_literal: true
# frozen_string_literal: true
class
Projects::AutocompleteSourcesController
<
Projects
::
ApplicationController
class
Projects::AutocompleteSourcesController
<
Projects
::
ApplicationController
before_action
:authorize_read_milestone!
,
only: :milestones
def
members
def
members
render
json:
::
Projects
::
ParticipantsService
.
new
(
@project
,
current_user
).
execute
(
target
)
render
json:
::
Projects
::
ParticipantsService
.
new
(
@project
,
current_user
).
execute
(
target
)
end
end
...
...
app/controllers/projects/commit_controller.rb
View file @
59db98a0
...
@@ -65,7 +65,11 @@ class Projects::CommitController < Projects::ApplicationController
...
@@ -65,7 +65,11 @@ class Projects::CommitController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
def
merge_requests
def
merge_requests
@merge_requests
=
@commit
.
merge_requests
.
map
do
|
mr
|
@merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
project_id:
@project
.
id
,
commit_sha:
@commit
.
sha
).
execute
.
map
do
|
mr
|
{
iid:
mr
.
iid
,
path:
merge_request_path
(
mr
),
title:
mr
.
title
}
{
iid:
mr
.
iid
,
path:
merge_request_path
(
mr
),
title:
mr
.
title
}
end
end
...
...
app/controllers/projects/group_links_controller.rb
View file @
59db98a0
...
@@ -13,9 +13,10 @@ class Projects::GroupLinksController < Projects::ApplicationController
...
@@ -13,9 +13,10 @@ class Projects::GroupLinksController < Projects::ApplicationController
group
=
Group
.
find
(
params
[
:link_group_id
])
if
params
[
:link_group_id
].
present?
group
=
Group
.
find
(
params
[
:link_group_id
])
if
params
[
:link_group_id
].
present?
if
group
if
group
return
render_404
unless
can?
(
current_user
,
:read_group
,
group
)
result
=
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
current_user
,
group_link_create_params
).
execute
(
group
)
return
render_404
if
result
[
:http_status
]
==
404
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
current_user
,
group_link_create_params
).
execute
(
group
)
flash
[
:alert
]
=
result
[
:message
]
if
result
[
:http_status
]
==
409
else
else
flash
[
:alert
]
=
'Please select a group.'
flash
[
:alert
]
=
'Please select a group.'
end
end
...
...
app/finders/merge_requests_finder.rb
View file @
59db98a0
...
@@ -37,13 +37,20 @@ class MergeRequestsFinder < IssuableFinder
...
@@ -37,13 +37,20 @@ class MergeRequestsFinder < IssuableFinder
end
end
def
filter_items
(
_items
)
def
filter_items
(
_items
)
items
=
by_source_branch
(
super
)
items
=
by_commit
(
super
)
items
=
by_source_branch
(
items
)
items
=
by_wip
(
items
)
items
=
by_wip
(
items
)
by_target_branch
(
items
)
by_target_branch
(
items
)
end
end
private
private
def
by_commit
(
items
)
return
items
unless
params
[
:commit_sha
].
presence
items
.
by_commit_sha
(
params
[
:commit_sha
])
end
def
source_branch
def
source_branch
@source_branch
||=
params
[
:source_branch
].
presence
@source_branch
||=
params
[
:source_branch
].
presence
end
end
...
...
app/graphql/types/project_type.rb
View file @
59db98a0
...
@@ -16,7 +16,6 @@ module Types
...
@@ -16,7 +16,6 @@ module Types
field
:description
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:description
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:default_branch
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:tag_list
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:tag_list
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:ssh_url_to_repo
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:ssh_url_to_repo
,
GraphQL
::
STRING_TYPE
,
null:
true
...
@@ -59,7 +58,6 @@ module Types
...
@@ -59,7 +58,6 @@ module Types
end
end
field
:import_status
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:import_status
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:ci_config_path
,
GraphQL
::
STRING_TYPE
,
null:
true
field
:only_allow_merge_if_pipeline_succeeds
,
GraphQL
::
BOOLEAN_TYPE
,
null:
true
field
:only_allow_merge_if_pipeline_succeeds
,
GraphQL
::
BOOLEAN_TYPE
,
null:
true
field
:request_access_enabled
,
GraphQL
::
BOOLEAN_TYPE
,
null:
true
field
:request_access_enabled
,
GraphQL
::
BOOLEAN_TYPE
,
null:
true
...
...
app/mailers/emails/issues.rb
View file @
59db98a0
...
@@ -74,6 +74,7 @@ module Emails
...
@@ -74,6 +74,7 @@ module Emails
@new_issue
=
new_issue
@new_issue
=
new_issue
@new_project
=
new_issue
.
project
@new_project
=
new_issue
.
project
@can_access_project
=
recipient
.
can?
(
:read_project
,
@new_project
)
mail_answer_thread
(
issue
,
issue_thread_options
(
updated_by_user
.
id
,
recipient
.
id
,
reason
))
mail_answer_thread
(
issue
,
issue_thread_options
(
updated_by_user
.
id
,
recipient
.
id
,
reason
))
end
end
...
...
app/models/active_session.rb
View file @
59db98a0
...
@@ -5,7 +5,8 @@ class ActiveSession
...
@@ -5,7 +5,8 @@ class ActiveSession
attr_accessor
:created_at
,
:updated_at
,
attr_accessor
:created_at
,
:updated_at
,
:session_id
,
:ip_address
,
:session_id
,
:ip_address
,
:browser
,
:os
,
:device_name
,
:device_type
:browser
,
:os
,
:device_name
,
:device_type
,
:is_impersonated
def
current?
(
session
)
def
current?
(
session
)
return
false
if
session_id
.
nil?
||
session
.
id
.
nil?
return
false
if
session_id
.
nil?
||
session
.
id
.
nil?
...
@@ -31,7 +32,8 @@ class ActiveSession
...
@@ -31,7 +32,8 @@ class ActiveSession
device_type:
client
.
device_type
,
device_type:
client
.
device_type
,
created_at:
user
.
current_sign_in_at
||
timestamp
,
created_at:
user
.
current_sign_in_at
||
timestamp
,
updated_at:
timestamp
,
updated_at:
timestamp
,
session_id:
session_id
session_id:
session_id
,
is_impersonated:
request
.
session
[
:impersonator_id
].
present?
)
)
redis
.
pipelined
do
redis
.
pipelined
do
...
...
app/models/clusters/platforms/kubernetes.rb
View file @
59db98a0
...
@@ -41,7 +41,7 @@ module Clusters
...
@@ -41,7 +41,7 @@ module Clusters
validate
:no_namespace
,
unless: :allow_user_defined_namespace?
validate
:no_namespace
,
unless: :allow_user_defined_namespace?
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
validates
:api_url
,
url:
true
,
presence:
true
validates
:api_url
,
public_
url:
true
,
presence:
true
validates
:token
,
presence:
true
validates
:token
,
presence:
true
validates
:ca_cert
,
certificate:
true
,
allow_blank:
true
,
if: :ca_cert_changed?
validates
:ca_cert
,
certificate:
true
,
allow_blank:
true
,
if: :ca_cert_changed?
...
...
app/models/concerns/issuable.rb
View file @
59db98a0
...
@@ -75,6 +75,7 @@ module Issuable
...
@@ -75,6 +75,7 @@ module Issuable
validates
:author
,
presence:
true
validates
:author
,
presence:
true
validates
:title
,
presence:
true
,
length:
{
maximum:
255
}
validates
:title
,
presence:
true
,
length:
{
maximum:
255
}
validate
:milestone_is_valid
scope
:authored
,
->
(
user
)
{
where
(
author_id:
user
)
}
scope
:authored
,
->
(
user
)
{
where
(
author_id:
user
)
}
scope
:recent
,
->
{
reorder
(
id: :desc
)
}
scope
:recent
,
->
{
reorder
(
id: :desc
)
}
...
@@ -118,6 +119,16 @@ module Issuable
...
@@ -118,6 +119,16 @@ module Issuable
def
has_multiple_assignees?
def
has_multiple_assignees?
assignees
.
count
>
1
assignees
.
count
>
1
end
end
def
milestone_available?
project_id
==
milestone
&
.
project_id
||
project
.
ancestors_upto
.
compact
.
include?
(
milestone
&
.
group
)
end
private
def
milestone_is_valid
errors
.
add
(
:milestone_id
,
message:
"is invalid"
)
if
milestone_id
.
present?
&&
!
milestone_available?
end
end
end
class_methods
do
class_methods
do
...
...
app/models/concerns/milestoneish.rb
View file @
59db98a0
...
@@ -46,12 +46,19 @@ module Milestoneish
...
@@ -46,12 +46,19 @@ module Milestoneish
end
end
end
end
def
merge_requests_visible_to_user
(
user
)
memoize_per_user
(
user
,
:merge_requests_visible_to_user
)
do
MergeRequestsFinder
.
new
(
user
,
{})
.
execute
.
where
(
milestone_id:
milestoneish_id
)
end
end
def
sorted_issues
(
user
)
def
sorted_issues
(
user
)
issues_visible_to_user
(
user
).
preload_associations
.
sort_by_attribute
(
'label_priority'
)
issues_visible_to_user
(
user
).
preload_associations
.
sort_by_attribute
(
'label_priority'
)
end
end
def
sorted_merge_requests
def
sorted_merge_requests
(
user
)
merge_requests
.
sort_by_attribute
(
'label_priority'
)
merge_requests
_visible_to_user
(
user
)
.
sort_by_attribute
(
'label_priority'
)
end
end
def
upcoming?
def
upcoming?
...
...
app/models/merge_request.rb
View file @
59db98a0
...
@@ -71,7 +71,7 @@ class MergeRequest < ActiveRecord::Base
...
@@ -71,7 +71,7 @@ class MergeRequest < ActiveRecord::Base
serialize
:merge_params
,
Hash
# rubocop:disable Cop/ActiveRecordSerialize
serialize
:merge_params
,
Hash
# rubocop:disable Cop/ActiveRecordSerialize
after_create
:ensure_merge_request_diff
,
unless: :importing?
after_create
:ensure_merge_request_diff
after_update
:clear_memoized_shas
after_update
:clear_memoized_shas
after_update
:reload_diff_if_branch_changed
after_update
:reload_diff_if_branch_changed
after_save
:ensure_metrics
after_save
:ensure_metrics
...
@@ -189,6 +189,9 @@ class MergeRequest < ActiveRecord::Base
...
@@ -189,6 +189,9 @@ class MergeRequest < ActiveRecord::Base
after_save
:keep_around_commit
after_save
:keep_around_commit
alias_attribute
:project
,
:target_project
alias_attribute
:project_id
,
:target_project_id
def
self
.
reference_prefix
def
self
.
reference_prefix
'!'
'!'
end
end
...
@@ -847,10 +850,6 @@ class MergeRequest < ActiveRecord::Base
...
@@ -847,10 +850,6 @@ class MergeRequest < ActiveRecord::Base
target_project
!=
source_project
target_project
!=
source_project
end
end
def
project
target_project
end
# If the merge request closes any issues, save this information in the
# If the merge request closes any issues, save this information in the
# `MergeRequestsClosingIssues` model. This is a performance optimization.
# `MergeRequestsClosingIssues` model. This is a performance optimization.
# Calculating this information for a number of merge requests requires
# Calculating this information for a number of merge requests requires
...
...
app/models/merge_request_diff.rb
View file @
59db98a0
...
@@ -22,6 +22,8 @@ class MergeRequestDiff < ActiveRecord::Base
...
@@ -22,6 +22,8 @@ class MergeRequestDiff < ActiveRecord::Base
has_many
:merge_request_diff_commits
,
->
{
order
(
:merge_request_diff_id
,
:relative_order
)
}
has_many
:merge_request_diff_commits
,
->
{
order
(
:merge_request_diff_id
,
:relative_order
)
}
validates
:base_commit_sha
,
:head_commit_sha
,
:start_commit_sha
,
sha:
true
state_machine
:state
,
initial: :empty
do
state_machine
:state
,
initial: :empty
do
event
:clean
do
event
:clean
do
transition
any
=>
:without_files
transition
any
=>
:without_files
...
...
app/models/project_services/prometheus_service.rb
View file @
59db98a0
...
@@ -71,7 +71,7 @@ class PrometheusService < MonitoringService
...
@@ -71,7 +71,7 @@ class PrometheusService < MonitoringService
end
end
def
prometheus_client
def
prometheus_client
RestClient
::
Resource
.
new
(
api_url
,
max_redirects:
0
)
if
api_url
&&
manual_configuration?
&&
active
?
RestClient
::
Resource
.
new
(
api_url
,
max_redirects:
0
)
if
should_return_client
?
end
end
def
prometheus_available?
def
prometheus_available?
...
@@ -83,6 +83,10 @@ class PrometheusService < MonitoringService
...
@@ -83,6 +83,10 @@ class PrometheusService < MonitoringService
private
private
def
should_return_client?
api_url
&&
manual_configuration?
&&
active?
&&
valid?
end
def
synchronize_service_state
def
synchronize_service_state
self
.
active
=
prometheus_available?
||
manual_configuration?
self
.
active
=
prometheus_available?
||
manual_configuration?
...
...
app/policies/group_policy.rb
View file @
59db98a0
...
@@ -53,8 +53,11 @@ class GroupPolicy < BasePolicy
...
@@ -53,8 +53,11 @@ class GroupPolicy < BasePolicy
rule
{
admin
}.
enable
:read_group
rule
{
admin
}.
enable
:read_group
rule
{
has_projects
}.
policy
do
rule
{
has_projects
}.
policy
do
<<<<<<<
HEAD
enable
:read_group
enable
:read_group
enable
:read_list
enable
:read_list
=======
>>>>>>>
dev
/
master
enable
:read_label
enable
:read_label
end
end
...
...
app/policies/project_policy.rb
View file @
59db98a0
...
@@ -300,6 +300,8 @@ class ProjectPolicy < BasePolicy
...
@@ -300,6 +300,8 @@ class ProjectPolicy < BasePolicy
rule
{
issues_disabled
}.
policy
do
rule
{
issues_disabled
}.
policy
do
prevent
(
*
create_read_update_admin_destroy
(
:issue
))
prevent
(
*
create_read_update_admin_destroy
(
:issue
))
prevent
(
*
create_read_update_admin_destroy
(
:board
))
prevent
(
*
create_read_update_admin_destroy
(
:list
))
end
end
rule
{
merge_requests_disabled
|
repository_disabled
}.
policy
do
rule
{
merge_requests_disabled
|
repository_disabled
}.
policy
do
...
...
app/services/issuable_base_service.rb
View file @
59db98a0
...
@@ -387,4 +387,10 @@ class IssuableBaseService < BaseService
...
@@ -387,4 +387,10 @@ class IssuableBaseService < BaseService
def
parent
def
parent
project
project
end
end
# we need to check this because milestone from milestone_id param is displayed on "new" page
# where private project milestone could leak without this check
def
ensure_milestone_available
(
issuable
)
issuable
.
milestone_id
=
nil
unless
issuable
.
milestone_available?
end
end
end
app/services/issues/build_service.rb
View file @
59db98a0
...
@@ -6,7 +6,9 @@ module Issues
...
@@ -6,7 +6,9 @@ module Issues
def
execute
def
execute
filter_resolve_discussion_params
filter_resolve_discussion_params
@issue
=
project
.
issues
.
new
(
issue_params
)
@issue
=
project
.
issues
.
new
(
issue_params
).
tap
do
|
issue
|
ensure_milestone_available
(
issue
)
end
end
end
def
issue_params_with_info_from_discussions
def
issue_params_with_info_from_discussions
...
...
app/services/merge_requests/build_service.rb
View file @
59db98a0
...
@@ -19,6 +19,7 @@ module MergeRequests
...
@@ -19,6 +19,7 @@ module MergeRequests
merge_request
.
target_project
=
find_target_project
merge_request
.
target_project
=
find_target_project
merge_request
.
target_branch
=
find_target_branch
merge_request
.
target_branch
=
find_target_branch
merge_request
.
can_be_created
=
projects_and_branches_valid?
merge_request
.
can_be_created
=
projects_and_branches_valid?
ensure_milestone_available
(
merge_request
)
# compare branches only if branches are valid, otherwise
# compare branches only if branches are valid, otherwise
# compare_branches may raise an error
# compare_branches may raise an error
...
...
app/services/projects/group_links/create_service.rb
View file @
59db98a0
...
@@ -4,13 +4,19 @@ module Projects
...
@@ -4,13 +4,19 @@ module Projects
module
GroupLinks
module
GroupLinks
class
CreateService
<
BaseService
class
CreateService
<
BaseService
def
execute
(
group
)
def
execute
(
group
)
return
false
unless
group
return
error
(
'Not Found'
,
404
)
unless
group
&&
can?
(
current_user
,
:read_namespace
,
group
)
project
.
project_group_links
.
create
(
link
=
project
.
project_group_links
.
new
(
group:
group
,
group:
group
,
group_access:
params
[
:link_group_access
],
group_access:
params
[
:link_group_access
],
expires_at:
params
[
:expires_at
]
expires_at:
params
[
:expires_at
]
)
)
if
link
.
save
success
(
link:
link
)
else
error
(
link
.
errors
.
full_messages
.
to_sentence
,
409
)
end
end
end
end
end
end
end
...
...
app/uploaders/file_mover.rb
View file @
59db98a0
...
@@ -11,6 +11,8 @@ class FileMover
...
@@ -11,6 +11,8 @@ class FileMover
end
end
def
execute
def
execute
return
unless
valid?
move
move
if
update_markdown
if
update_markdown
...
@@ -21,6 +23,12 @@ class FileMover
...
@@ -21,6 +23,12 @@ class FileMover
private
private
def
valid?
Pathname
.
new
(
temp_file_path
).
realpath
.
to_path
.
start_with?
(
(
Pathname
(
temp_file_uploader
.
root
)
+
temp_file_uploader
.
base_dir
).
to_path
)
end
def
move
def
move
FileUtils
.
mkdir_p
(
File
.
dirname
(
file_path
))
FileUtils
.
mkdir_p
(
File
.
dirname
(
file_path
))
FileUtils
.
move
(
temp_file_path
,
file_path
)
FileUtils
.
move
(
temp_file_path
,
file_path
)
...
...
app/validators/sha_validator.rb
0 → 100644
View file @
59db98a0
# frozen_string_literal: true
class
ShaValidator
<
ActiveModel
::
EachValidator
def
validate_each
(
record
,
attribute
,
value
)
return
if
value
.
blank?
||
value
.
match
(
/\A\h{40}\z/
)
record
.
errors
.
add
(
attribute
,
'is not a valid SHA'
)
end
end
app/views/notify/issue_moved_email.html.haml
View file @
59db98a0
%p
%p
Issue was moved to another project.
Issue was moved to another project.
%p
-
if
@can_access_project
New issue:
%p
=
link_to
project_issue_url
(
@new_project
,
@new_issue
)
do
New issue:
=
@new_issue
.
title
=
link_to
project_issue_url
(
@new_project
,
@new_issue
)
do
=
@new_issue
.
title
-
else
You don't have access to the project.
app/views/notify/issue_moved_email.text.erb
View file @
59db98a0
Issue was moved to another project.
Issue was moved to another project.
<%
if
@can_access_project
%>
New issue location:
New issue location:
<%=
project_issue_url
(
@new_project
,
@new_issue
)
%>
<%=
project_issue_url
(
@new_project
,
@new_issue
)
%>
<%
else
%>
You don't have access to the project.
<%
end
%>
app/views/profiles/active_sessions/_active_session.html.haml
View file @
59db98a0
...
@@ -23,9 +23,3 @@
...
@@ -23,9 +23,3 @@
%strong
Signed in
%strong
Signed in
on
on
=
l
(
active_session
.
created_at
,
format: :short
)
=
l
(
active_session
.
created_at
,
format: :short
)
-
unless
is_current_session
.float-right
=
link_to
profile_active_session_path
(
active_session
.
session_id
),
data:
{
confirm:
'Are you sure? The device will be signed out of GitLab.'
},
method: :delete
,
class:
"btn btn-danger prepend-left-10"
do
%span
.sr-only
Revoke
Revoke
app/views/projects/blob/viewers/_dependency_manager.html.haml
View file @
59db98a0
...
@@ -3,9 +3,4 @@
...
@@ -3,9 +3,4 @@
This project manages its dependencies using
This project manages its dependencies using
%strong
=
viewer
.
manager_name
%strong
=
viewer
.
manager_name
-
if
viewer
.
package_name
and defines a
#{
viewer
.
package_type
}
named
%strong<
=
link_to_if
viewer
.
package_url
.
present?
,
viewer
.
package_name
,
viewer
.
package_url
,
target:
'_blank'
,
rel:
'noopener noreferrer'
=
link_to
'Learn more'
,
viewer
.
manager_url
,
target:
'_blank'
,
rel:
'noopener noreferrer'
=
link_to
'Learn more'
,
viewer
.
manager_url
,
target:
'_blank'
,
rel:
'noopener noreferrer'
changelogs/unreleased/2802-security-add-public-internal-groups-as-members-to-your-project-idor.yml
0 → 100644
View file @
59db98a0
---
title
:
Remove the possibility to share a project with a group that a user is not a member
of
merge_request
:
author
:
type
:
security
changelogs/unreleased/51971-milestones-visibility.yml
0 → 100644
View file @
59db98a0
---
title
:
Check if desired milestone for an issue is available
merge_request
:
author
:
type
:
security
changelogs/unreleased/57534_filter_impersonated_sessions.yml
0 → 100644
View file @
59db98a0
---
title
:
Do not display impersonated sessions under active sessions and remove ability
to revoke session
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-2797-milestone-mrs.yml
0 → 100644
View file @
59db98a0
---
title
:
Show only merge requests visible to user on milestone detail page
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-2798-fix-boards-policy.yml
0 → 100644
View file @
59db98a0
---
title
:
Disable issue boards API when issues are disabled
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-2799-emails.yml
0 → 100644
View file @
59db98a0
---
title
:
Don't show new issue link after move when a user does not have permissions
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-50334.yml
0 → 100644
View file @
59db98a0
---
title
:
Fix git clone revealing private repo's presence
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-55468-check-validity-before-querying.yml
0 → 100644
View file @
59db98a0
---
title
:
Fix blind SSRF in Prometheus integration by checking URL before querying
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-56348.yml
0 → 100644
View file @
59db98a0
---
title
:
Check snippet attached file to be moved is within designated directory
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-commit-private-related-mr.yml
0 → 100644
View file @
59db98a0
---
title
:
Don't allow non-members to see private related MRs.
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-fj-diff-import-file-read-fix.yml
0 → 100644
View file @
59db98a0
---
title
:
Fix arbitrary file read via diffs during import
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-id-restricted-access-to-private-repo.yml
0 → 100644
View file @
59db98a0
---
title
:
Forbid creating discussions for users with restricted access
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-issue_54789_2.yml
0 → 100644
View file @
59db98a0
---
title
:
Do not disclose milestone titles for unauthorized users
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-kubernetes-google-login-csrf.yml
0 → 100644
View file @
59db98a0
---
title
:
Validate session key when authorizing with GCP to create a cluster
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-kubernetes-local-ssrf.yml
0 → 100644
View file @
59db98a0
---
title
:
Block local URLs for Kubernetes integration
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-mermaid.yml
0 → 100644
View file @
59db98a0
---
title
:
Limit mermaid rendering to 5K characters
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-osw-stop-linking-to-packages.yml
0 → 100644
View file @
59db98a0
---
title
:
Stop linking to unrecognized package sources
merge_request
:
55518
author
:
type
:
security
changelogs/unreleased/security-protect-private-repo-information.yml
0 → 100644
View file @
59db98a0
---
title
:
Fix leaking private repository information in API
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-shared-project-private-group.yml
0 → 100644
View file @
59db98a0
---
title
:
Fixed ability to see private groups by users not belonging to given group
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-tags-oracle.yml
0 → 100644
View file @
59db98a0
---
title
:
Prevent releases links API to leak tag existance
merge_request
:
author
:
type
:
security
config/routes/git_http.rb
View file @
59db98a0
...
@@ -40,7 +40,7 @@ scope(path: '*namespace_id/:project_id',
...
@@ -40,7 +40,7 @@ scope(path: '*namespace_id/:project_id',
# /info/refs?service=git-receive-pack, but nothing else.
# /info/refs?service=git-receive-pack, but nothing else.
#
#
git_http_handshake
=
lambda
do
|
request
|
git_http_handshake
=
lambda
do
|
request
|
::
Constraints
::
ProjectUrlConstrainer
.
new
.
matches?
(
request
)
&&
::
Constraints
::
ProjectUrlConstrainer
.
new
.
matches?
(
request
,
existence_check:
false
)
&&
(
request
.
query_string
.
blank?
||
(
request
.
query_string
.
blank?
||
request
.
query_string
.
match
(
/\Aservice=git-(upload|receive)-pack\z/
))
request
.
query_string
.
match
(
/\Aservice=git-(upload|receive)-pack\z/
))
end
end
...
...
doc/user/profile/active_sessions.md
View file @
59db98a0
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
> in GitLab 10.8.
> in GitLab 10.8.
GitLab lists all devices that have logged into your account. This allows you to
GitLab lists all devices that have logged into your account. This allows you to
review the sessions
and revoke any of it that you don't recognize
.
review the sessions.
## Listing all active sessions
## Listing all active sessions
...
@@ -12,9 +12,3 @@ review the sessions and revoke any of it that you don't recognize.
...
@@ -12,9 +12,3 @@ review the sessions and revoke any of it that you don't recognize.
1.
Navigate to the
**Active Sessions**
tab.
1.
Navigate to the
**Active Sessions**
tab.
![
Active sessions list
](
img/active_sessions_list.png
)
![
Active sessions list
](
img/active_sessions_list.png
)
## Revoking a session
1.
Navigate to your
[
profile's
](
#profile-settings
)
**Settings > Active Sessions**
.
1.
Click on
**Revoke**
besides a session. The current session cannot be
revoked, as this would sign you out of GitLab.
doc/user/profile/img/active_sessions_list.png
View replaced file @
5c80bbb3
View file @
59db98a0
21.7 KB
|
W:
|
H:
18.9 KB
|
W:
|
H:
2-up
Swipe
Onion skin
lib/api/commits.rb
View file @
59db98a0
...
@@ -318,10 +318,18 @@ module API
...
@@ -318,10 +318,18 @@ module API
use
:pagination
use
:pagination
end
end
get
':id/repository/commits/:sha/merge_requests'
,
requirements:
API
::
COMMIT_ENDPOINT_REQUIREMENTS
do
get
':id/repository/commits/:sha/merge_requests'
,
requirements:
API
::
COMMIT_ENDPOINT_REQUIREMENTS
do
authorize!
:read_merge_request
,
user_project
commit
=
user_project
.
commit
(
params
[
:sha
])
commit
=
user_project
.
commit
(
params
[
:sha
])
not_found!
'Commit'
unless
commit
not_found!
'Commit'
unless
commit
present
paginate
(
commit
.
merge_requests
),
with:
Entities
::
MergeRequestBasic
commit_merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
project_id:
user_project
.
id
,
commit_sha:
commit
.
sha
).
execute
present
paginate
(
commit_merge_requests
),
with:
Entities
::
MergeRequestBasic
end
end
desc
"Get a commit's GPG signature"
do
desc
"Get a commit's GPG signature"
do
...
...
lib/api/entities.rb
View file @
59db98a0
...
@@ -156,7 +156,7 @@ module API
...
@@ -156,7 +156,7 @@ module API
class
BasicProjectDetails
<
ProjectIdentity
class
BasicProjectDetails
<
ProjectIdentity
include
::
API
::
ProjectsRelationBuilder
include
::
API
::
ProjectsRelationBuilder
expose
:default_branch
expose
:default_branch
,
if:
->
(
project
,
options
)
{
Ability
.
allowed?
(
options
[
:current_user
],
:download_code
,
project
)
}
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
# Avoids an N+1 query: https://github.com/mbleigh/acts-as-taggable-on/issues/91#issuecomment-168273770
expose
:tag_list
do
|
project
|
expose
:tag_list
do
|
project
|
# project.tags.order(:name).pluck(:name) is the most suitable option
# project.tags.order(:name).pluck(:name) is the most suitable option
...
@@ -261,7 +261,7 @@ module API
...
@@ -261,7 +261,7 @@ module API
expose
:open_issues_count
,
if:
lambda
{
|
project
,
options
|
project
.
feature_available?
(
:issues
,
options
[
:current_user
])
}
expose
:open_issues_count
,
if:
lambda
{
|
project
,
options
|
project
.
feature_available?
(
:issues
,
options
[
:current_user
])
}
expose
:runners_token
,
if:
lambda
{
|
_project
,
options
|
options
[
:user_can_admin_project
]
}
expose
:runners_token
,
if:
lambda
{
|
_project
,
options
|
options
[
:user_can_admin_project
]
}
expose
:public_builds
,
as: :public_jobs
expose
:public_builds
,
as: :public_jobs
expose
:ci_config_path
expose
:ci_config_path
,
if:
->
(
project
,
options
)
{
Ability
.
allowed?
(
options
[
:current_user
],
:download_code
,
project
)
}
expose
:shared_with_groups
do
|
project
,
options
|
expose
:shared_with_groups
do
|
project
,
options
|
SharedGroup
.
represent
(
project
.
project_group_links
,
options
)
SharedGroup
.
represent
(
project
.
project_group_links
,
options
)
end
end
...
@@ -270,8 +270,9 @@ module API
...
@@ -270,8 +270,9 @@ module API
expose
:only_allow_merge_if_all_discussions_are_resolved
expose
:only_allow_merge_if_all_discussions_are_resolved
expose
:printing_merge_request_link_enabled
expose
:printing_merge_request_link_enabled
expose
:merge_method
expose
:merge_method
expose
:statistics
,
using:
'API::Entities::ProjectStatistics'
,
if:
->
(
project
,
options
)
{
expose
:statistics
,
using:
'API::Entities::ProjectStatistics'
,
if: :statistics
options
[
:statistics
]
&&
Ability
.
allowed?
(
options
[
:current_user
],
:download_code
,
project
)
}
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
self
.
preload_relation
(
projects_relation
,
options
=
{})
def
self
.
preload_relation
(
projects_relation
,
options
=
{})
...
...
lib/api/environments.rb
View file @
59db98a0
...
@@ -22,7 +22,7 @@ module API
...
@@ -22,7 +22,7 @@ module API
get
':id/environments'
do
get
':id/environments'
do
authorize!
:read_environment
,
user_project
authorize!
:read_environment
,
user_project
present
paginate
(
user_project
.
environments
),
with:
Entities
::
Environment
present
paginate
(
user_project
.
environments
),
with:
Entities
::
Environment
,
current_user:
current_user
end
end
desc
'Creates a new environment'
do
desc
'Creates a new environment'
do
...
@@ -40,7 +40,7 @@ module API
...
@@ -40,7 +40,7 @@ module API
environment
=
user_project
.
environments
.
create
(
declared_params
)
environment
=
user_project
.
environments
.
create
(
declared_params
)
if
environment
.
persisted?
if
environment
.
persisted?
present
environment
,
with:
Entities
::
Environment
present
environment
,
with:
Entities
::
Environment
,
current_user:
current_user
else
else
render_validation_error!
(
environment
)
render_validation_error!
(
environment
)
end
end
...
@@ -63,7 +63,7 @@ module API
...
@@ -63,7 +63,7 @@ module API
update_params
=
declared_params
(
include_missing:
false
).
extract!
(
:name
,
:external_url
)
update_params
=
declared_params
(
include_missing:
false
).
extract!
(
:name
,
:external_url
)
if
environment
.
update
(
update_params
)
if
environment
.
update
(
update_params
)
present
environment
,
with:
Entities
::
Environment
present
environment
,
with:
Entities
::
Environment
,
current_user:
current_user
else
else
render_validation_error!
(
environment
)
render_validation_error!
(
environment
)
end
end
...
@@ -99,7 +99,7 @@ module API
...
@@ -99,7 +99,7 @@ module API
environment
.
stop_with_action!
(
current_user
)
environment
.
stop_with_action!
(
current_user
)
status
200
status
200
present
environment
,
with:
Entities
::
Environment
present
environment
,
with:
Entities
::
Environment
,
current_user:
current_user
end
end
end
end
end
end
...
...
lib/api/helpers/notes_helpers.rb
View file @
59db98a0
...
@@ -70,14 +70,7 @@ module API
...
@@ -70,14 +70,7 @@ module API
def
find_noteable
(
parent
,
noteables_str
,
noteable_id
)
def
find_noteable
(
parent
,
noteables_str
,
noteable_id
)
noteable
=
public_send
(
"find_
#{
parent
}
_
#{
noteables_str
.
singularize
}
"
,
noteable_id
)
# rubocop:disable GitlabSecurity/PublicSend
noteable
=
public_send
(
"find_
#{
parent
}
_
#{
noteables_str
.
singularize
}
"
,
noteable_id
)
# rubocop:disable GitlabSecurity/PublicSend
readable
=
readable
=
can?
(
current_user
,
noteable_read_ability_name
(
noteable
),
noteable
)
if
noteable
.
is_a?
(
Commit
)
# for commits there is not :read_commit policy, check if user
# has :read_note permission on the commit's project
can?
(
current_user
,
:read_note
,
user_project
)
else
can?
(
current_user
,
noteable_read_ability_name
(
noteable
),
noteable
)
end
return
not_found!
(
noteables_str
)
unless
readable
return
not_found!
(
noteables_str
)
unless
readable
...
@@ -89,12 +82,11 @@ module API
...
@@ -89,12 +82,11 @@ module API
end
end
def
create_note
(
noteable
,
opts
)
def
create_note
(
noteable
,
opts
)
policy_object
=
noteable
.
is_a?
(
Commit
)
?
user_project
:
noteable
authorize!
(
:create_note
,
noteable
)
authorize!
(
:create_note
,
policy_object
)
parent
=
noteable_parent
(
noteable
)
parent
=
noteable_parent
(
noteable
)
opts
.
delete
(
:created_at
)
unless
current_user
.
can?
(
:set_note_created_at
,
policy_object
)
opts
.
delete
(
:created_at
)
unless
current_user
.
can?
(
:set_note_created_at
,
noteable
)
opts
[
:updated_at
]
=
opts
[
:created_at
]
if
opts
[
:created_at
]
opts
[
:updated_at
]
=
opts
[
:created_at
]
if
opts
[
:created_at
]
...
...
lib/api/projects.rb
View file @
59db98a0
...
@@ -184,7 +184,8 @@ module API
...
@@ -184,7 +184,8 @@ module API
if
project
.
saved?
if
project
.
saved?
present
project
,
with:
Entities
::
Project
,
present
project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
)
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
),
current_user:
current_user
else
else
if
project
.
errors
[
:limit_reached
].
present?
if
project
.
errors
[
:limit_reached
].
present?
error!
(
project
.
errors
[
:limit_reached
],
403
)
error!
(
project
.
errors
[
:limit_reached
],
403
)
...
@@ -217,7 +218,8 @@ module API
...
@@ -217,7 +218,8 @@ module API
if
project
.
saved?
if
project
.
saved?
present
project
,
with:
Entities
::
Project
,
present
project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
)
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
project
),
current_user:
current_user
else
else
render_validation_error!
(
project
)
render_validation_error!
(
project
)
end
end
...
@@ -281,7 +283,8 @@ module API
...
@@ -281,7 +283,8 @@ module API
conflict!
(
forked_project
.
errors
.
messages
)
conflict!
(
forked_project
.
errors
.
messages
)
else
else
present
forked_project
,
with:
Entities
::
Project
,
present
forked_project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
forked_project
)
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
forked_project
),
current_user:
current_user
end
end
end
end
...
@@ -330,7 +333,8 @@ module API
...
@@ -330,7 +333,8 @@ module API
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
present
user_project
,
with:
Entities
::
Project
,
present
user_project
,
with:
Entities
::
Project
,
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
user_project
)
user_can_admin_project:
can?
(
current_user
,
:admin_project
,
user_project
),
current_user:
current_user
else
else
render_validation_error!
(
user_project
)
render_validation_error!
(
user_project
)
end
end
...
@@ -344,7 +348,7 @@ module API
...
@@ -344,7 +348,7 @@ module API
::
Projects
::
UpdateService
.
new
(
user_project
,
current_user
,
archived:
true
).
execute
::
Projects
::
UpdateService
.
new
(
user_project
,
current_user
,
archived:
true
).
execute
present
user_project
,
with:
Entities
::
Project
present
user_project
,
with:
Entities
::
Project
,
current_user:
current_user
end
end
desc
'Unarchive a project'
do
desc
'Unarchive a project'
do
...
@@ -355,7 +359,7 @@ module API
...
@@ -355,7 +359,7 @@ module API
::
Projects
::
UpdateService
.
new
(
@project
,
current_user
,
archived:
false
).
execute
::
Projects
::
UpdateService
.
new
(
@project
,
current_user
,
archived:
false
).
execute
present
user_project
,
with:
Entities
::
Project
present
user_project
,
with:
Entities
::
Project
,
current_user:
current_user
end
end
desc
'Star a project'
do
desc
'Star a project'
do
...
@@ -368,7 +372,7 @@ module API
...
@@ -368,7 +372,7 @@ module API
current_user
.
toggle_star
(
user_project
)
current_user
.
toggle_star
(
user_project
)
user_project
.
reload
user_project
.
reload
present
user_project
,
with:
Entities
::
Project
present
user_project
,
with:
Entities
::
Project
,
current_user:
current_user
end
end
end
end
...
@@ -380,7 +384,7 @@ module API
...
@@ -380,7 +384,7 @@ module API
current_user
.
toggle_star
(
user_project
)
current_user
.
toggle_star
(
user_project
)
user_project
.
reload
user_project
.
reload
present
user_project
,
with:
Entities
::
Project
present
user_project
,
with:
Entities
::
Project
,
current_user:
current_user
else
else
not_modified!
not_modified!
end
end
...
@@ -420,7 +424,7 @@ module API
...
@@ -420,7 +424,7 @@ module API
result
=
::
Projects
::
ForkService
.
new
(
fork_from_project
,
current_user
).
execute
(
user_project
)
result
=
::
Projects
::
ForkService
.
new
(
fork_from_project
,
current_user
).
execute
(
user_project
)
if
result
if
result
present
user_project
.
reload
,
with:
Entities
::
Project
present
user_project
.
reload
,
with:
Entities
::
Project
,
current_user:
current_user
else
else
render_api_error!
(
"Project already forked"
,
409
)
if
user_project
.
forked?
render_api_error!
(
"Project already forked"
,
409
)
if
user_project
.
forked?
end
end
...
@@ -442,27 +446,24 @@ module API
...
@@ -442,27 +446,24 @@ module API
end
end
params
do
params
do
requires
:group_id
,
type:
Integer
,
desc:
'The ID of a group'
requires
:group_id
,
type:
Integer
,
desc:
'The ID of a group'
requires
:group_access
,
type:
Integer
,
values:
Gitlab
::
Access
.
values
,
desc:
'The group access level'
requires
:group_access
,
type:
Integer
,
values:
Gitlab
::
Access
.
values
,
as: :link_group_access
,
desc:
'The group access level'
optional
:expires_at
,
type:
Date
,
desc:
'Share expiration date'
optional
:expires_at
,
type:
Date
,
desc:
'Share expiration date'
end
end
post
":id/share"
do
post
":id/share"
do
authorize!
:admin_project
,
user_project
authorize!
:admin_project
,
user_project
group
=
Group
.
find_by_id
(
params
[
:group_id
])
group
=
Group
.
find_by_id
(
params
[
:group_id
])
unless
group
&&
can?
(
current_user
,
:read_group
,
group
)
not_found!
(
'Group'
)
end
unless
user_project
.
allowed_to_share_with_group?
unless
user_project
.
allowed_to_share_with_group?
break
render_api_error!
(
"The project sharing with group is disabled"
,
400
)
break
render_api_error!
(
"The project sharing with group is disabled"
,
400
)
end
end
link
=
user_project
.
project_group_links
.
new
(
declared_params
(
include_missing:
false
))
result
=
::
Projects
::
GroupLinks
::
CreateService
.
new
(
user_project
,
current_user
,
declared_params
(
include_missing:
false
))
.
execute
(
group
)
if
link
.
save
if
result
[
:status
]
==
:success
present
link
,
with:
Entities
::
ProjectGroupLink
present
result
[
:link
]
,
with:
Entities
::
ProjectGroupLink
else
else
render_api_error!
(
link
.
errors
.
full_messages
.
first
,
409
)
render_api_error!
(
result
[
:message
],
result
[
:http_status
]
)
end
end
end
end
...
@@ -526,7 +527,7 @@ module API
...
@@ -526,7 +527,7 @@ module API
result
=
::
Projects
::
TransferService
.
new
(
user_project
,
current_user
).
execute
(
namespace
)
result
=
::
Projects
::
TransferService
.
new
(
user_project
,
current_user
).
execute
(
namespace
)
if
result
if
result
present
user_project
,
with:
Entities
::
Project
present
user_project
,
with:
Entities
::
Project
,
current_user:
current_user
else
else
render_api_error!
(
"Failed to transfer project
#{
user_project
.
errors
.
messages
}
"
,
400
)
render_api_error!
(
"Failed to transfer project
#{
user_project
.
errors
.
messages
}
"
,
400
)
end
end
...
...
lib/api/release/links.rb
View file @
59db98a0
...
@@ -8,6 +8,8 @@ module API
...
@@ -8,6 +8,8 @@ module API
RELEASE_ENDPOINT_REQUIREMETS
=
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
RELEASE_ENDPOINT_REQUIREMETS
=
API
::
NAMESPACE_OR_PROJECT_REQUIREMENTS
.
merge
(
tag_name:
API
::
NO_SLASH_URL_PART_REGEX
)
.
merge
(
tag_name:
API
::
NO_SLASH_URL_PART_REGEX
)
before
{
authorize!
:read_release
,
user_project
}
params
do
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
end
...
...
lib/constraints/project_url_constrainer.rb
View file @
59db98a0
...
@@ -2,12 +2,13 @@
...
@@ -2,12 +2,13 @@
module
Constraints
module
Constraints
class
ProjectUrlConstrainer
class
ProjectUrlConstrainer
def
matches?
(
request
)
def
matches?
(
request
,
existence_check:
true
)
namespace_path
=
request
.
params
[
:namespace_id
]
namespace_path
=
request
.
params
[
:namespace_id
]
project_path
=
request
.
params
[
:project_id
]
||
request
.
params
[
:id
]
project_path
=
request
.
params
[
:project_id
]
||
request
.
params
[
:id
]
full_path
=
[
namespace_path
,
project_path
].
join
(
'/'
)
full_path
=
[
namespace_path
,
project_path
].
join
(
'/'
)
return
false
unless
ProjectPathValidator
.
valid_path?
(
full_path
)
return
false
unless
ProjectPathValidator
.
valid_path?
(
full_path
)
return
true
unless
existence_check
# We intentionally allow SELECT(*) here so result of this query can be used
# We intentionally allow SELECT(*) here so result of this query can be used
# as cache for further Project.find_by_full_path calls within request
# as cache for further Project.find_by_full_path calls within request
...
...
lib/gitlab/auth/omniauth_identity_linker_base.rb
View file @
59db98a0
...
@@ -12,7 +12,7 @@ module Gitlab
...
@@ -12,7 +12,7 @@ module Gitlab
end
end
def
link
def
link
save
if
identity
.
new_recor
d?
save
if
unlinke
d?
end
end
def
changed?
def
changed?
...
@@ -35,6 +35,10 @@ module Gitlab
...
@@ -35,6 +35,10 @@ module Gitlab
@changed
=
identity
.
save
@changed
=
identity
.
save
end
end
def
unlinked?
identity
.
new_record?
end
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
identity
def
identity
@identity
||=
current_user
.
identities
@identity
||=
current_user
.
identities
...
...
lib/gitlab/dependency_linker/base_linker.rb
View file @
59db98a0
...
@@ -4,6 +4,7 @@ module Gitlab
...
@@ -4,6 +4,7 @@ module Gitlab
module
DependencyLinker
module
DependencyLinker
class
BaseLinker
class
BaseLinker
URL_REGEX
=
%r{https?://[^'" ]+}
.
freeze
URL_REGEX
=
%r{https?://[^'" ]+}
.
freeze
GIT_INVALID_URL_REGEX
=
/^git\+
#{
URL_REGEX
}
/
.
freeze
REPO_REGEX
=
%r{[^/'" ]+/[^/'" ]+}
.
freeze
REPO_REGEX
=
%r{[^/'" ]+/[^/'" ]+}
.
freeze
class_attribute
:file_type
class_attribute
:file_type
...
@@ -29,8 +30,25 @@ module Gitlab
...
@@ -29,8 +30,25 @@ module Gitlab
highlighted_lines
.
join
.
html_safe
highlighted_lines
.
join
.
html_safe
end
end
def
external_url
(
name
,
external_ref
)
return
if
external_ref
=~
GIT_INVALID_URL_REGEX
case
external_ref
when
/\A
#{
URL_REGEX
}
\z/
external_ref
when
/\A
#{
REPO_REGEX
}
\z/
github_url
(
external_ref
)
else
package_url
(
name
)
end
end
private
private
def
package_url
(
_name
)
raise
NotImplementedError
end
def
link_dependencies
def
link_dependencies
raise
NotImplementedError
raise
NotImplementedError
end
end
...
...
lib/gitlab/dependency_linker/composer_json_linker.rb
View file @
59db98a0
...
@@ -8,8 +8,8 @@ module Gitlab
...
@@ -8,8 +8,8 @@ module Gitlab
private
private
def
link_packages
def
link_packages
link_packages_at_key
(
"require"
,
&
method
(
:package_url
)
)
link_packages_at_key
(
"require"
)
link_packages_at_key
(
"require-dev"
,
&
method
(
:package_url
)
)
link_packages_at_key
(
"require-dev"
)
end
end
def
package_url
(
name
)
def
package_url
(
name
)
...
...
lib/gitlab/dependency_linker/gemfile_linker.rb
View file @
59db98a0
...
@@ -3,8 +3,14 @@
...
@@ -3,8 +3,14 @@
module
Gitlab
module
Gitlab
module
DependencyLinker
module
DependencyLinker
class
GemfileLinker
<
MethodLinker
class
GemfileLinker
<
MethodLinker
class_attribute
:package_keyword
self
.
package_keyword
=
:gem
self
.
file_type
=
:gemfile
self
.
file_type
=
:gemfile
GITHUB_REGEX
=
/(github:|:github\s*=>)\s*['"](?<name>[^'"]+)['"]/
.
freeze
GIT_REGEX
=
/(git:|:git\s*=>)\s*['"](?<name>
#{
URL_REGEX
}
)['"]/
.
freeze
private
private
def
link_dependencies
def
link_dependencies
...
@@ -14,21 +20,35 @@ module Gitlab
...
@@ -14,21 +20,35 @@ module Gitlab
def
link_urls
def
link_urls
# Link `github: "user/repo"` to https://github.com/user/repo
# Link `github: "user/repo"` to https://github.com/user/repo
link_regex
(
/(github:|:github\s*=>)\s*['"](?<name>[^'"]+)['"]/
,
&
method
(
:github_url
))
link_regex
(
GITHUB_REGEX
,
&
method
(
:github_url
))
# Link `git: "https://gitlab.example.com/user/repo"` to https://gitlab.example.com/user/repo
# Link `git: "https://gitlab.example.com/user/repo"` to https://gitlab.example.com/user/repo
link_regex
(
/(git:|:git\s*=>)\s*['"](?<name>
#{
URL_REGEX
}
)['"]/
,
&
:itself
)
link_regex
(
GIT_REGEX
,
&
:itself
)
# Link `source "https://rubygems.org"` to https://rubygems.org
# Link `source "https://rubygems.org"` to https://rubygems.org
link_method_call
(
'source'
,
URL_REGEX
,
&
:itself
)
link_method_call
(
'source'
,
URL_REGEX
,
&
:itself
)
end
end
def
link_packages
def
link_packages
# Link `gem "package_name"` to https://rubygems.org/gems/package_name
packages
=
parse_packages
link_method_call
(
'gem'
)
do
|
name
|
"https://rubygems.org/gems/
#{
name
}
"
return
if
packages
.
blank?
packages
.
each
do
|
package
|
link_method_call
(
'gem'
,
package
.
name
)
do
external_url
(
package
.
name
,
package
.
external_ref
)
end
end
end
end
end
def
package_url
(
name
)
"https://rubygems.org/gems/
#{
name
}
"
end
def
parse_packages
parser
=
Gitlab
::
DependencyLinker
::
Parser
::
Gemfile
.
new
(
plain_text
)
parser
.
parse
(
keyword:
self
.
class
.
package_keyword
)
end
end
end
end
end
end
end
lib/gitlab/dependency_linker/gemspec_linker.rb
View file @
59db98a0
...
@@ -11,7 +11,7 @@ module Gitlab
...
@@ -11,7 +11,7 @@ module Gitlab
link_method_call
(
'homepage'
,
URL_REGEX
,
&
:itself
)
link_method_call
(
'homepage'
,
URL_REGEX
,
&
:itself
)
link_method_call
(
'license'
,
&
method
(
:license_url
))
link_method_call
(
'license'
,
&
method
(
:license_url
))
link_method_call
(
%w[
name
add_dependency add_runtime_dependency add_development_dependency]
)
do
|
name
|
link_method_call
(
%w[add_dependency add_runtime_dependency add_development_dependency]
)
do
|
name
|
"https://rubygems.org/gems/
#{
name
}
"
"https://rubygems.org/gems/
#{
name
}
"
end
end
end
end
...
...
lib/gitlab/dependency_linker/method_linker.rb
View file @
59db98a0
...
@@ -23,18 +23,22 @@ module Gitlab
...
@@ -23,18 +23,22 @@ module Gitlab
# link_method_call('name')
# link_method_call('name')
# # Will link `package` in `self.name = "package"`
# # Will link `package` in `self.name = "package"`
def
link_method_call
(
method_name
,
value
=
nil
,
&
url_proc
)
def
link_method_call
(
method_name
,
value
=
nil
,
&
url_proc
)
regex
=
method_call_regex
(
method_name
,
value
)
link_regex
(
regex
,
&
url_proc
)
end
def
method_call_regex
(
method_name
,
value
=
nil
)
method_name
=
regexp_for_value
(
method_name
)
method_name
=
regexp_for_value
(
method_name
)
value
=
regexp_for_value
(
value
)
value
=
regexp_for_value
(
value
)
regex
=
%r{
%r{
#{
method_name
}
# Method name
#{
method_name
}
# Method name
\s
* # Whitespace
\s
* # Whitespace
[(=]? # Opening brace or equals sign
[(=]? # Opening brace or equals sign
\s
* # Whitespace
\s
* # Whitespace
['"](?<name>
#{
value
}
)['"] # Package name in quotes
['"](?<name>
#{
value
}
)['"] # Package name in quotes
}x
}x
link_regex
(
regex
,
&
url_proc
)
end
end
end
end
end
end
...
...
lib/gitlab/dependency_linker/package.rb
0 → 100644
View file @
59db98a0
# frozen_string_literal: true
module
Gitlab
module
DependencyLinker
class
Package
attr_reader
:name
,
:git_ref
,
:github_ref
def
initialize
(
name
,
git_ref
,
github_ref
)
@name
=
name
@git_ref
=
git_ref
@github_ref
=
github_ref
end
def
external_ref
@git_ref
||
@github_ref
end
end
end
end
lib/gitlab/dependency_linker/package_json_linker.rb
View file @
59db98a0
...
@@ -8,7 +8,6 @@ module Gitlab
...
@@ -8,7 +8,6 @@ module Gitlab
private
private
def
link_dependencies
def
link_dependencies
link_json
(
'name'
,
json
[
"name"
],
&
method
(
:package_url
))
link_json
(
'license'
,
&
method
(
:license_url
))
link_json
(
'license'
,
&
method
(
:license_url
))
link_json
(
%w[homepage url]
,
URL_REGEX
,
&
:itself
)
link_json
(
%w[homepage url]
,
URL_REGEX
,
&
:itself
)
...
@@ -16,25 +15,19 @@ module Gitlab
...
@@ -16,25 +15,19 @@ module Gitlab
end
end
def
link_packages
def
link_packages
link_packages_at_key
(
"dependencies"
,
&
method
(
:package_url
)
)
link_packages_at_key
(
"dependencies"
)
link_packages_at_key
(
"devDependencies"
,
&
method
(
:package_url
)
)
link_packages_at_key
(
"devDependencies"
)
end
end
def
link_packages_at_key
(
key
,
&
url_proc
)
def
link_packages_at_key
(
key
)
dependencies
=
json
[
key
]
dependencies
=
json
[
key
]
return
unless
dependencies
return
unless
dependencies
dependencies
.
each
do
|
name
,
version
|
dependencies
.
each
do
|
name
,
version
|
link_json
(
name
,
version
,
link: :key
,
&
url_proc
)
external_url
=
external_url
(
name
,
version
)
link_json
(
name
)
do
|
value
|
link_json
(
name
,
version
,
link: :key
)
{
external_url
}
case
value
link_json
(
name
)
{
external_url
}
when
/\A
#{
URL_REGEX
}
\z/
value
when
/\A
#{
REPO_REGEX
}
\z/
github_url
(
value
)
end
end
end
end
end
end
...
...
lib/gitlab/dependency_linker/parser/gemfile.rb
0 → 100644
View file @
59db98a0
# frozen_string_literal: true
module
Gitlab
module
DependencyLinker
module
Parser
class
Gemfile
<
MethodLinker
GIT_REGEX
=
Gitlab
::
DependencyLinker
::
GemfileLinker
::
GIT_REGEX
GITHUB_REGEX
=
Gitlab
::
DependencyLinker
::
GemfileLinker
::
GITHUB_REGEX
def
initialize
(
plain_text
)
@plain_text
=
plain_text
end
# Returns a list of Gitlab::DependencyLinker::Package
#
# keyword - The package definition keyword, e.g. `:gem` for
# Gemfile parsing, `:pod` for Podfile.
def
parse
(
keyword
:)
plain_lines
.
each_with_object
([])
do
|
line
,
packages
|
name
=
fetch
(
line
,
method_call_regex
(
keyword
))
next
unless
name
git_ref
=
fetch
(
line
,
GIT_REGEX
)
github_ref
=
fetch
(
line
,
GITHUB_REGEX
)
packages
<<
Gitlab
::
DependencyLinker
::
Package
.
new
(
name
,
git_ref
,
github_ref
)
end
end
private
def
fetch
(
line
,
regex
,
group: :name
)
match
=
line
.
match
(
regex
)
match
[
group
]
if
match
end
end
end
end
end
lib/gitlab/dependency_linker/podfile_linker.rb
View file @
59db98a0
...
@@ -5,12 +5,21 @@ module Gitlab
...
@@ -5,12 +5,21 @@ module Gitlab
class
PodfileLinker
<
GemfileLinker
class
PodfileLinker
<
GemfileLinker
include
Cocoapods
include
Cocoapods
self
.
package_keyword
=
:pod
self
.
file_type
=
:podfile
self
.
file_type
=
:podfile
private
private
def
link_packages
def
link_packages
link_method_call
(
'pod'
,
&
method
(
:package_url
))
packages
=
parse_packages
return
unless
packages
packages
.
each
do
|
package
|
link_method_call
(
'pod'
,
package
.
name
)
do
external_url
(
package
.
name
,
package
.
external_ref
)
end
end
end
end
end
end
end
end
...
...
lib/gitlab/dependency_linker/podspec_linker.rb
View file @
59db98a0
...
@@ -19,7 +19,7 @@ module Gitlab
...
@@ -19,7 +19,7 @@ module Gitlab
link_method_call
(
'license'
,
&
method
(
:license_url
))
link_method_call
(
'license'
,
&
method
(
:license_url
))
link_regex
(
/license\s*=\s*\{\s*(type:|:type\s*=>)\s*
#{
STRING_REGEX
}
/
,
&
method
(
:license_url
))
link_regex
(
/license\s*=\s*\{\s*(type:|:type\s*=>)\s*
#{
STRING_REGEX
}
/
,
&
method
(
:license_url
))
link_method_call
(
%w[name dependency]
,
&
method
(
:package_url
))
link_method_call
(
'dependency'
,
&
method
(
:package_url
))
end
end
end
end
end
end
...
...
lib/gitlab/import_export/merge_request_parser.rb
View file @
59db98a0
...
@@ -20,6 +20,17 @@ module Gitlab
...
@@ -20,6 +20,17 @@ module Gitlab
create_target_branch
unless
branch_exists?
(
@merge_request
.
target_branch
)
create_target_branch
unless
branch_exists?
(
@merge_request
.
target_branch
)
end
end
# The merge_request_diff associated with the current @merge_request might
# be invalid. Than means, when the @merge_request object is saved, the
# @merge_request.merge_request_diff won't. This can leave the merge request
# in an invalid state, because a merge request must have an associated
# merge request diff.
# In this change, if the associated merge request diff is invalid, we set
# it to nil. This change, in association with the after callback
# :ensure_merge_request_diff in the MergeRequest class, makes that
# when the merge request is going to be created and it doesn't have
# one, a default one will be generated.
@merge_request
.
merge_request_diff
=
nil
unless
@merge_request
.
merge_request_diff
&
.
valid?
@merge_request
@merge_request
end
end
...
...
lib/gitlab/kubernetes/kube_client.rb
View file @
59db98a0
...
@@ -82,6 +82,8 @@ module Gitlab
...
@@ -82,6 +82,8 @@ module Gitlab
def
initialize
(
api_prefix
,
**
kubeclient_options
)
def
initialize
(
api_prefix
,
**
kubeclient_options
)
@api_prefix
=
api_prefix
@api_prefix
=
api_prefix
@kubeclient_options
=
kubeclient_options
.
merge
(
http_max_redirects:
0
)
@kubeclient_options
=
kubeclient_options
.
merge
(
http_max_redirects:
0
)
validate_url!
end
end
def
create_or_update_cluster_role_binding
(
resource
)
def
create_or_update_cluster_role_binding
(
resource
)
...
@@ -118,6 +120,12 @@ module Gitlab
...
@@ -118,6 +120,12 @@ module Gitlab
private
private
def
validate_url!
return
if
Gitlab
::
CurrentSettings
.
allow_local_requests_from_hooks_and_services?
Gitlab
::
UrlBlocker
.
validate!
(
api_prefix
,
allow_local_network:
false
)
end
def
cluster_role_binding_exists?
(
resource
)
def
cluster_role_binding_exists?
(
resource
)
get_cluster_role_binding
(
resource
.
metadata
.
name
)
get_cluster_role_binding
(
resource
.
metadata
.
name
)
rescue
::
Kubeclient
::
ResourceNotFoundError
rescue
::
Kubeclient
::
ResourceNotFoundError
...
...
locale/gitlab.pot
View file @
59db98a0
...
@@ -1341,6 +1341,9 @@ msgstr ""
...
@@ -1341,6 +1341,9 @@ msgstr ""
msgid "Cannot modify managed Kubernetes cluster"
msgid "Cannot modify managed Kubernetes cluster"
msgstr ""
msgstr ""
msgid "Cannot render the image. Maximum character count (%{charLimit}) has been exceeded."
msgstr ""
msgid "Certificate"
msgid "Certificate"
msgstr ""
msgstr ""
...
...
spec/controllers/dashboard/milestones_controller_spec.rb
View file @
59db98a0
...
@@ -13,7 +13,7 @@ describe Dashboard::MilestonesController do
...
@@ -13,7 +13,7 @@ describe Dashboard::MilestonesController do
)
)
end
end
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
milestone:
project_milestone
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
milestone:
project_milestone
)
}
let
(
:group_issue
)
{
create
(
:issue
,
milestone:
group_milestone
)
}
let
(
:group_issue
)
{
create
(
:issue
,
milestone:
group_milestone
,
project:
create
(
:project
,
group:
group
)
)
}
let!
(
:label
)
{
create
(
:label
,
project:
project
,
title:
'Issue Label'
,
issues:
[
issue
])
}
let!
(
:label
)
{
create
(
:label
,
project:
project
,
title:
'Issue Label'
,
issues:
[
issue
])
}
let!
(
:group_label
)
{
create
(
:group_label
,
group:
group
,
title:
'Group Issue Label'
,
issues:
[
group_issue
])
}
let!
(
:group_label
)
{
create
(
:group_label
,
group:
group
,
title:
'Group Issue Label'
,
issues:
[
group_issue
])
}
...
...
spec/controllers/google_api/authorizations_controller_spec.rb
View file @
59db98a0
...
@@ -6,7 +6,7 @@ describe GoogleApi::AuthorizationsController do
...
@@ -6,7 +6,7 @@ describe GoogleApi::AuthorizationsController do
let
(
:token
)
{
'token'
}
let
(
:token
)
{
'token'
}
let
(
:expires_at
)
{
1
.
hour
.
since
.
strftime
(
'%s'
)
}
let
(
:expires_at
)
{
1
.
hour
.
since
.
strftime
(
'%s'
)
}
subject
{
get
:callback
,
params:
{
code:
'xxx'
,
state:
@
state
}
}
subject
{
get
:callback
,
params:
{
code:
'xxx'
,
state:
state
}
}
before
do
before
do
sign_in
(
user
)
sign_in
(
user
)
...
@@ -15,35 +15,57 @@ describe GoogleApi::AuthorizationsController do
...
@@ -15,35 +15,57 @@ describe GoogleApi::AuthorizationsController do
.
to
receive
(
:get_token
).
and_return
([
token
,
expires_at
])
.
to
receive
(
:get_token
).
and_return
([
token
,
expires_at
])
end
end
it
'sets token and expires_at in session'
do
shared_examples_for
'access denied'
do
subject
it
'returns a 404'
do
subject
expect
(
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_token
])
expect
(
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_token
]).
to
be_nil
.
to
eq
(
token
)
expect
(
response
).
to
have_http_status
(
:not_found
)
expect
(
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
])
end
.
to
eq
(
expires_at
)
end
end
context
'
when redirect uri key is stored in state
'
do
context
'
session key is present
'
do
set
(
:project
)
{
create
(
:project
)
}
let
(
:session_key
)
{
'session-key'
}
let
(
:redirect_uri
)
{
project_clusters_url
(
project
).
to_s
}
let
(
:redirect_uri
)
{
'example.com'
}
before
do
before
do
@state
=
GoogleApi
::
CloudPlatform
::
Client
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_redirect_uri
(
session_key
)]
=
redirect_uri
.
new_session_key_for_redirect_uri
do
|
key
|
end
session
[
key
]
=
redirect_uri
context
'session key matches state param'
do
let
(
:state
)
{
session_key
}
it
'sets token and expires_at in session'
do
subject
expect
(
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_token
])
.
to
eq
(
token
)
expect
(
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
])
.
to
eq
(
expires_at
)
end
it
'redirects to the URL stored in state param'
do
expect
(
subject
).
to
redirect_to
(
redirect_uri
)
end
end
end
end
it
'redirects to the URL stored in state param'
do
context
'session key does not match state param'
do
expect
(
subject
).
to
redirect_to
(
redirect_uri
)
let
(
:state
)
{
'bad-key'
}
it_behaves_like
'access denied'
end
end
end
context
'when redirection url is not stored in state'
do
context
'state param is blank'
do
it
'redirects to root_path'
do
let
(
:state
)
{
''
}
expect
(
subject
).
to
redirect_to
(
root_path
)
it_behaves_like
'access denied'
end
end
end
end
context
'state param is present, but session key is blank'
do
let
(
:state
)
{
'session-key'
}
it_behaves_like
'access denied'
end
end
end
end
end
spec/controllers/groups/shared_projects_controller_spec.rb
View file @
59db98a0
...
@@ -6,6 +6,8 @@ describe Groups::SharedProjectsController do
...
@@ -6,6 +6,8 @@ describe Groups::SharedProjectsController do
end
end
def
share_project
(
project
)
def
share_project
(
project
)
group
.
add_developer
(
user
)
Projects
::
GroupLinks
::
CreateService
.
new
(
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
project
,
user
,
user
,
...
...
spec/controllers/omniauth_callbacks_controller_spec.rb
View file @
59db98a0
...
@@ -193,7 +193,7 @@ describe OmniauthCallbacksController, type: :controller do
...
@@ -193,7 +193,7 @@ describe OmniauthCallbacksController, type: :controller do
before
do
before
do
stub_omniauth_saml_config
({
enabled:
true
,
auto_link_saml_user:
true
,
allow_single_sign_on:
[
'saml'
],
stub_omniauth_saml_config
({
enabled:
true
,
auto_link_saml_user:
true
,
allow_single_sign_on:
[
'saml'
],
providers:
[
saml_config
]
})
providers:
[
saml_config
]
})
mock_auth_hash
(
'saml'
,
'my-uid'
,
user
.
email
,
mock_saml_response
)
mock_auth_hash
_with_saml_xml
(
'saml'
,
'my-uid'
,
user
.
email
,
mock_saml_response
)
request
.
env
[
"devise.mapping"
]
=
Devise
.
mappings
[
:user
]
request
.
env
[
"devise.mapping"
]
=
Devise
.
mappings
[
:user
]
request
.
env
[
'omniauth.auth'
]
=
Rails
.
application
.
env_config
[
'omniauth.auth'
]
request
.
env
[
'omniauth.auth'
]
=
Rails
.
application
.
env_config
[
'omniauth.auth'
]
post
:saml
,
params:
{
SAMLResponse
:
mock_saml_response
}
post
:saml
,
params:
{
SAMLResponse
:
mock_saml_response
}
...
...
spec/controllers/projects/autocomplete_sources_controller_spec.rb
View file @
59db98a0
...
@@ -35,4 +35,35 @@ describe Projects::AutocompleteSourcesController do
...
@@ -35,4 +35,35 @@ describe Projects::AutocompleteSourcesController do
avatar_url:
user
.
avatar_url
)
avatar_url:
user
.
avatar_url
)
end
end
end
end
describe
'GET milestones'
do
let
(
:group
)
{
create
(
:group
,
:public
)
}
let
(
:project
)
{
create
(
:project
,
:public
,
namespace:
group
)
}
let!
(
:project_milestone
)
{
create
(
:milestone
,
project:
project
)
}
let!
(
:group_milestone
)
{
create
(
:milestone
,
group:
group
)
}
before
do
sign_in
(
user
)
end
it
'lists milestones'
do
group
.
add_owner
(
user
)
get
:milestones
,
format: :json
,
params:
{
namespace_id:
group
.
path
,
project_id:
project
.
path
}
milestone_titles
=
json_response
.
map
{
|
milestone
|
milestone
[
"title"
]
}
expect
(
milestone_titles
).
to
match_array
([
project_milestone
.
title
,
group_milestone
.
title
])
end
context
'when user cannot read project issues and merge requests'
do
it
'renders 404'
do
project
.
project_feature
.
update!
(
issues_access_level:
ProjectFeature
::
PRIVATE
)
project
.
project_feature
.
update!
(
merge_requests_access_level:
ProjectFeature
::
PRIVATE
)
get
:milestones
,
format: :json
,
params:
{
namespace_id:
group
.
path
,
project_id:
project
.
path
}
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
end
end
end
spec/controllers/projects/group_links_controller_spec.rb
View file @
59db98a0
...
@@ -65,8 +65,24 @@ describe Projects::GroupLinksController do
...
@@ -65,8 +65,24 @@ describe Projects::GroupLinksController do
end
end
end
end
context
'when user does not have access to the public group'
do
let
(
:group
)
{
create
(
:group
,
:public
)
}
include_context
'link project to group'
it
'renders 404'
do
expect
(
response
.
status
).
to
eq
404
end
it
'does not share project with that group'
do
expect
(
group
.
shared_projects
).
not_to
include
project
end
end
context
'when project group id equal link group id'
do
context
'when project group id equal link group id'
do
before
do
before
do
group2
.
add_developer
(
user
)
post
(
:create
,
params:
{
post
(
:create
,
params:
{
namespace_id:
project
.
namespace
,
namespace_id:
project
.
namespace
,
project_id:
project
,
project_id:
project
,
...
@@ -102,5 +118,26 @@ describe Projects::GroupLinksController do
...
@@ -102,5 +118,26 @@ describe Projects::GroupLinksController do
expect
(
flash
[
:alert
]).
to
eq
(
'Please select a group.'
)
expect
(
flash
[
:alert
]).
to
eq
(
'Please select a group.'
)
end
end
end
end
context
'when link is not persisted in the database'
do
before
do
allow
(
::
Projects
::
GroupLinks
::
CreateService
).
to
receive_message_chain
(
:new
,
:execute
)
.
and_return
({
status: :error
,
http_status:
409
,
message:
'error'
})
post
(
:create
,
params:
{
namespace_id:
project
.
namespace
,
project_id:
project
,
link_group_id:
group
.
id
,
link_group_access:
ProjectGroupLink
.
default_access
})
end
it
'redirects to project group links page'
do
expect
(
response
).
to
redirect_to
(
project_project_members_path
(
project
)
)
expect
(
flash
[
:alert
]).
to
eq
(
'error'
)
end
end
end
end
end
end
spec/controllers/snippets_controller_spec.rb
View file @
59db98a0
...
@@ -205,6 +205,8 @@ describe SnippetsController do
...
@@ -205,6 +205,8 @@ describe SnippetsController do
end
end
context
'when the snippet description contains a file'
do
context
'when the snippet description contains a file'
do
include
FileMoverHelpers
let
(
:picture_file
)
{
'/-/system/temp/secret56/picture.jpg'
}
let
(
:picture_file
)
{
'/-/system/temp/secret56/picture.jpg'
}
let
(
:text_file
)
{
'/-/system/temp/secret78/text.txt'
}
let
(
:text_file
)
{
'/-/system/temp/secret78/text.txt'
}
let
(
:description
)
do
let
(
:description
)
do
...
@@ -215,6 +217,8 @@ describe SnippetsController do
...
@@ -215,6 +217,8 @@ describe SnippetsController do
before
do
before
do
allow
(
FileUtils
).
to
receive
(
:mkdir_p
)
allow
(
FileUtils
).
to
receive
(
:mkdir_p
)
allow
(
FileUtils
).
to
receive
(
:move
)
allow
(
FileUtils
).
to
receive
(
:move
)
stub_file_mover
(
text_file
)
stub_file_mover
(
picture_file
)
end
end
subject
{
create_snippet
({
description:
description
},
{
files:
[
picture_file
,
text_file
]
})
}
subject
{
create_snippet
({
description:
description
},
{
files:
[
picture_file
,
text_file
]
})
}
...
...
spec/features/issues_spec.rb
View file @
59db98a0
...
@@ -233,8 +233,8 @@ describe 'Issues' do
...
@@ -233,8 +233,8 @@ describe 'Issues' do
created_at:
Time
.
now
-
(
index
*
60
))
created_at:
Time
.
now
-
(
index
*
60
))
end
end
end
end
let
(
:newer_due_milestone
)
{
create
(
:milestone
,
due_date:
'2013-12-11'
)
}
let
(
:newer_due_milestone
)
{
create
(
:milestone
,
project:
project
,
due_date:
'2013-12-11'
)
}
let
(
:later_due_milestone
)
{
create
(
:milestone
,
due_date:
'2013-12-12'
)
}
let
(
:later_due_milestone
)
{
create
(
:milestone
,
project:
project
,
due_date:
'2013-12-12'
)
}
it
'sorts by newest'
do
it
'sorts by newest'
do
visit
project_issues_path
(
project
,
sort:
sort_value_created_date
)
visit
project_issues_path
(
project
,
sort:
sort_value_created_date
)
...
...
spec/features/merge_request/user_sees_versions_spec.rb
View file @
59db98a0
require
'rails_helper'
require
'rails_helper'
describe
'Merge request > User sees versions'
,
:js
do
describe
'Merge request > User sees versions'
,
:js
do
let
(
:merge_request
)
{
create
(
:merge_request
,
importing:
true
)
}
let
(
:merge_request
)
do
create
(
:merge_request
).
tap
do
|
mr
|
mr
.
merge_request_diff
.
destroy
end
end
let
(
:project
)
{
merge_request
.
source_project
}
let
(
:project
)
{
merge_request
.
source_project
}
let
(
:user
)
{
project
.
creator
}
let
(
:user
)
{
project
.
creator
}
let!
(
:merge_request_diff1
)
{
merge_request
.
merge_request_diffs
.
create
(
head_commit_sha:
'6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9'
)
}
let!
(
:merge_request_diff1
)
{
merge_request
.
merge_request_diffs
.
create
(
head_commit_sha:
'6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9'
)
}
...
...
spec/features/merge_requests/user_lists_merge_requests_spec.rb
View file @
59db98a0
...
@@ -13,7 +13,7 @@ describe 'Merge requests > User lists merge requests' do
...
@@ -13,7 +13,7 @@ describe 'Merge requests > User lists merge requests' do
source_project:
project
,
source_project:
project
,
source_branch:
'fix'
,
source_branch:
'fix'
,
assignee:
user
,
assignee:
user
,
milestone:
create
(
:milestone
,
due_date:
'2013-12-11'
),
milestone:
create
(
:milestone
,
project:
project
,
due_date:
'2013-12-11'
),
created_at:
1
.
minute
.
ago
,
created_at:
1
.
minute
.
ago
,
updated_at:
1
.
minute
.
ago
)
updated_at:
1
.
minute
.
ago
)
create
(
:merge_request
,
create
(
:merge_request
,
...
@@ -21,7 +21,7 @@ describe 'Merge requests > User lists merge requests' do
...
@@ -21,7 +21,7 @@ describe 'Merge requests > User lists merge requests' do
source_project:
project
,
source_project:
project
,
source_branch:
'markdown'
,
source_branch:
'markdown'
,
assignee:
user
,
assignee:
user
,
milestone:
create
(
:milestone
,
due_date:
'2013-12-12'
),
milestone:
create
(
:milestone
,
project:
project
,
due_date:
'2013-12-12'
),
created_at:
2
.
minutes
.
ago
,
created_at:
2
.
minutes
.
ago
,
updated_at:
2
.
minutes
.
ago
)
updated_at:
2
.
minutes
.
ago
)
create
(
:merge_request
,
create
(
:merge_request
,
...
...
spec/features/profiles/active_sessions_spec.rb
View file @
59db98a0
...
@@ -7,6 +7,8 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
...
@@ -7,6 +7,8 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
end
end
end
end
let
(
:admin
)
{
create
(
:admin
)
}
around
do
|
example
|
around
do
|
example
|
Timecop
.
freeze
(
Time
.
zone
.
parse
(
'2018-03-12 09:06'
))
do
Timecop
.
freeze
(
Time
.
zone
.
parse
(
'2018-03-12 09:06'
))
do
example
.
run
example
.
run
...
@@ -16,6 +18,7 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
...
@@ -16,6 +18,7 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
it
'User sees their active sessions'
do
it
'User sees their active sessions'
do
Capybara
::
Session
.
new
(
:session1
)
Capybara
::
Session
.
new
(
:session1
)
Capybara
::
Session
.
new
(
:session2
)
Capybara
::
Session
.
new
(
:session2
)
Capybara
::
Session
.
new
(
:session3
)
# note: headers can only be set on the non-js (aka. rack-test) driver
# note: headers can only be set on the non-js (aka. rack-test) driver
using_session
:session1
do
using_session
:session1
do
...
@@ -37,9 +40,27 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
...
@@ -37,9 +40,27 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
gitlab_sign_in
(
user
)
gitlab_sign_in
(
user
)
end
end
# set an admin session impersonating the user
using_session
:session3
do
Capybara
.
page
.
driver
.
header
(
'User-Agent'
,
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36'
)
gitlab_sign_in
(
admin
)
visit
admin_user_path
(
user
)
click_link
'Impersonate'
end
using_session
:session1
do
using_session
:session1
do
visit
profile_active_sessions_path
visit
profile_active_sessions_path
expect
(
page
).
to
(
have_selector
(
'ul.list-group li.list-group-item'
,
{
text:
'Signed in on'
,
count:
2
}))
expect
(
page
).
to
have_content
(
expect
(
page
).
to
have_content
(
'127.0.0.1 '
\
'127.0.0.1 '
\
'This is your current session '
\
'This is your current session '
\
...
@@ -57,33 +78,8 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
...
@@ -57,33 +78,8 @@ describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do
)
)
expect
(
page
).
to
have_selector
'[title="Smartphone"]'
,
count:
1
expect
(
page
).
to
have_selector
'[title="Smartphone"]'
,
count:
1
end
end
it
'User can revoke a session'
,
:js
,
:redis_session_store
do
Capybara
::
Session
.
new
(
:session1
)
Capybara
::
Session
.
new
(
:session2
)
# set an additional session in another browser
using_session
:session2
do
gitlab_sign_in
(
user
)
end
using_session
:session1
do
gitlab_sign_in
(
user
)
visit
profile_active_sessions_path
expect
(
page
).
to
have_link
(
'Revoke'
,
count:
1
)
accept_confirm
{
click_on
'Revoke'
}
expect
(
page
).
not_to
have_link
(
'Revoke'
)
end
using_session
:session2
do
visit
profile_active_sessions_path
expect
(
page
).
to
have_content
(
'You need to sign in or sign up before continuing.
'
)
expect
(
page
).
not_to
have_content
(
'Chrome on Windows
'
)
end
end
end
end
end
end
spec/features/projects/blobs/blob_show_spec.rb
View file @
59db98a0
...
@@ -548,10 +548,7 @@ describe 'File blob', :js do
...
@@ -548,10 +548,7 @@ describe 'File blob', :js do
it
'displays an auxiliary viewer'
do
it
'displays an auxiliary viewer'
do
aggregate_failures
do
aggregate_failures
do
# shows names of dependency manager and package
# shows names of dependency manager and package
expect
(
page
).
to
have_content
(
'This project manages its dependencies using RubyGems and defines a gem named activerecord.'
)
expect
(
page
).
to
have_content
(
'This project manages its dependencies using RubyGems.'
)
# shows a link to the gem
expect
(
page
).
to
have_link
(
'activerecord'
,
href:
'https://rubygems.org/gems/activerecord'
)
# shows a learn more link
# shows a learn more link
expect
(
page
).
to
have_link
(
'Learn more'
,
href:
'https://rubygems.org/'
)
expect
(
page
).
to
have_link
(
'Learn more'
,
href:
'https://rubygems.org/'
)
...
...
spec/features/projects/members/invite_group_spec.rb
View file @
59db98a0
...
@@ -27,6 +27,7 @@ describe 'Project > Members > Invite group', :js do
...
@@ -27,6 +27,7 @@ describe 'Project > Members > Invite group', :js do
before
do
before
do
project
.
add_maintainer
(
maintainer
)
project
.
add_maintainer
(
maintainer
)
group_to_share_with
.
add_guest
(
maintainer
)
sign_in
(
maintainer
)
sign_in
(
maintainer
)
end
end
...
@@ -112,6 +113,7 @@ describe 'Project > Members > Invite group', :js do
...
@@ -112,6 +113,7 @@ describe 'Project > Members > Invite group', :js do
before
do
before
do
project
.
add_maintainer
(
maintainer
)
project
.
add_maintainer
(
maintainer
)
group
.
add_guest
(
maintainer
)
sign_in
(
maintainer
)
sign_in
(
maintainer
)
visit
project_settings_members_path
(
project
)
visit
project_settings_members_path
(
project
)
...
...
spec/features/projects/settings/user_manages_group_links_spec.rb
View file @
59db98a0
...
@@ -10,6 +10,7 @@ describe 'Projects > Settings > User manages group links' do
...
@@ -10,6 +10,7 @@ describe 'Projects > Settings > User manages group links' do
before
do
before
do
project
.
add_maintainer
(
user
)
project
.
add_maintainer
(
user
)
group_market
.
add_guest
(
user
)
sign_in
(
user
)
sign_in
(
user
)
share_link
=
project
.
project_group_links
.
new
(
group_access:
Gitlab
::
Access
::
MAINTAINER
)
share_link
=
project
.
project_group_links
.
new
(
group_access:
Gitlab
::
Access
::
MAINTAINER
)
...
...
spec/features/security/group/private_access_spec.rb
View file @
59db98a0
...
@@ -27,7 +27,7 @@ describe 'Private Group access' do
...
@@ -27,7 +27,7 @@ describe 'Private Group access' do
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_
allow
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_
deni
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
...
@@ -42,7 +42,7 @@ describe 'Private Group access' do
...
@@ -42,7 +42,7 @@ describe 'Private Group access' do
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_
allow
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_
deni
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
...
@@ -58,7 +58,7 @@ describe 'Private Group access' do
...
@@ -58,7 +58,7 @@ describe 'Private Group access' do
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_
allow
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_
deni
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
...
@@ -73,7 +73,7 @@ describe 'Private Group access' do
...
@@ -73,7 +73,7 @@ describe 'Private Group access' do
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_
allow
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_
deni
ed_for
(
project_guest
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
...
@@ -93,4 +93,28 @@ describe 'Private Group access' do
...
@@ -93,4 +93,28 @@ describe 'Private Group access' do
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
end
end
describe
'GET /groups/:path for shared projects'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
before
do
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
create
(
:user
),
link_group_access:
ProjectGroupLink
::
DEVELOPER
).
execute
(
group
)
end
subject
{
group_path
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:admin
)
}
it
{
is_expected
.
to
be_allowed_for
(
:owner
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:maintainer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:developer
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:reporter
).
of
(
group
)
}
it
{
is_expected
.
to
be_allowed_for
(
:guest
).
of
(
group
)
}
it
{
is_expected
.
to
be_denied_for
(
project_guest
)
}
it
{
is_expected
.
to
be_denied_for
(
:user
)
}
it
{
is_expected
.
to
be_denied_for
(
:external
)
}
it
{
is_expected
.
to
be_denied_for
(
:visitor
)
}
end
end
end
spec/finders/merge_requests_finder_spec.rb
View file @
59db98a0
...
@@ -31,7 +31,7 @@ describe MergeRequestsFinder do
...
@@ -31,7 +31,7 @@ describe MergeRequestsFinder do
p
p
end
end
end
end
let
(
:project4
)
{
create_project_without_n_plus_1
(
group:
subgroup
)
}
let
(
:project4
)
{
create_project_without_n_plus_1
(
:repository
,
group:
subgroup
)
}
let
(
:project5
)
{
create_project_without_n_plus_1
(
group:
subgroup
)
}
let
(
:project5
)
{
create_project_without_n_plus_1
(
group:
subgroup
)
}
let
(
:project6
)
{
create_project_without_n_plus_1
(
group:
subgroup
)
}
let
(
:project6
)
{
create_project_without_n_plus_1
(
group:
subgroup
)
}
...
@@ -68,6 +68,15 @@ describe MergeRequestsFinder do
...
@@ -68,6 +68,15 @@ describe MergeRequestsFinder do
expect
(
merge_requests
.
size
).
to
eq
(
2
)
expect
(
merge_requests
.
size
).
to
eq
(
2
)
end
end
it
'filters by commit sha'
do
merge_requests
=
described_class
.
new
(
user
,
commit_sha:
merge_request5
.
merge_request_diff
.
last_commit_sha
).
execute
expect
(
merge_requests
).
to
contain_exactly
(
merge_request5
)
end
context
'filtering by group'
do
context
'filtering by group'
do
it
'includes all merge requests when user has access'
do
it
'includes all merge requests when user has access'
do
params
=
{
group_id:
group
.
id
}
params
=
{
group_id:
group
.
id
}
...
@@ -269,6 +278,21 @@ describe MergeRequestsFinder do
...
@@ -269,6 +278,21 @@ describe MergeRequestsFinder do
expect
(
merge_requests
).
to
contain_exactly
(
old_merge_request
,
new_merge_request
)
expect
(
merge_requests
).
to
contain_exactly
(
old_merge_request
,
new_merge_request
)
end
end
end
end
context
'when project restricts merge requests'
do
let
(
:non_member
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
,
:merge_requests_private
)
}
let!
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
)
}
it
"returns nothing to to non members"
do
merge_requests
=
described_class
.
new
(
non_member
,
project_id:
project
.
id
).
execute
expect
(
merge_requests
).
to
be_empty
end
end
end
end
describe
'#row_count'
,
:request_store
do
describe
'#row_count'
,
:request_store
do
...
...
spec/lib/constraints/project_url_constrainer_spec.rb
View file @
59db98a0
...
@@ -16,6 +16,10 @@ describe Constraints::ProjectUrlConstrainer do
...
@@ -16,6 +16,10 @@ describe Constraints::ProjectUrlConstrainer do
let
(
:request
)
{
build_request
(
'foo'
,
'bar'
)
}
let
(
:request
)
{
build_request
(
'foo'
,
'bar'
)
}
it
{
expect
(
subject
.
matches?
(
request
)).
to
be_falsey
}
it
{
expect
(
subject
.
matches?
(
request
)).
to
be_falsey
}
context
'existence_check is false'
do
it
{
expect
(
subject
.
matches?
(
request
,
existence_check:
false
)).
to
be_truthy
}
end
end
end
context
"project id ending with .git"
do
context
"project id ending with .git"
do
...
...
spec/lib/gitlab/dependency_linker/composer_json_linker_spec.rb
View file @
59db98a0
...
@@ -50,8 +50,8 @@ describe Gitlab::DependencyLinker::ComposerJsonLinker do
...
@@ -50,8 +50,8 @@ describe Gitlab::DependencyLinker::ComposerJsonLinker do
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
end
end
it
'
links
the module name'
do
it
'
does not link
the module name'
do
expect
(
subject
).
to
include
(
link
(
'laravel/laravel'
,
'https://packagist.org/packages/laravel/laravel'
))
expect
(
subject
).
not_
to
include
(
link
(
'laravel/laravel'
,
'https://packagist.org/packages/laravel/laravel'
))
end
end
it
'links the homepage'
do
it
'links the homepage'
do
...
...
spec/lib/gitlab/dependency_linker/gemfile_linker_spec.rb
View file @
59db98a0
...
@@ -41,13 +41,16 @@ describe Gitlab::DependencyLinker::GemfileLinker do
...
@@ -41,13 +41,16 @@ describe Gitlab::DependencyLinker::GemfileLinker do
end
end
it
'links dependencies'
do
it
'links dependencies'
do
expect
(
subject
).
to
include
(
link
(
'rails'
,
'https://rubygems.org/gems/rails'
))
expect
(
subject
).
to
include
(
link
(
'rails-deprecated_sanitizer'
,
'https://rubygems.org/gems/rails-deprecated_sanitizer'
))
expect
(
subject
).
to
include
(
link
(
'rails-deprecated_sanitizer'
,
'https://rubygems.org/gems/rails-deprecated_sanitizer'
))
expect
(
subject
).
to
include
(
link
(
'responders'
,
'https://rubygems.org/gems/responders'
))
expect
(
subject
).
to
include
(
link
(
'sprockets'
,
'https://rubygems.org/gems/sprockets'
))
expect
(
subject
).
to
include
(
link
(
'default_value_for'
,
'https://rubygems.org/gems/default_value_for'
))
expect
(
subject
).
to
include
(
link
(
'default_value_for'
,
'https://rubygems.org/gems/default_value_for'
))
end
end
it
'links to external dependencies'
do
expect
(
subject
).
to
include
(
link
(
'rails'
,
'https://github.com/rails/rails'
))
expect
(
subject
).
to
include
(
link
(
'responders'
,
'https://github.com/rails/responders'
))
expect
(
subject
).
to
include
(
link
(
'sprockets'
,
'https://gitlab.example.com/gems/sprockets'
))
end
it
'links GitHub repos'
do
it
'links GitHub repos'
do
expect
(
subject
).
to
include
(
link
(
'rails/rails'
,
'https://github.com/rails/rails'
))
expect
(
subject
).
to
include
(
link
(
'rails/rails'
,
'https://github.com/rails/rails'
))
expect
(
subject
).
to
include
(
link
(
'rails/responders'
,
'https://github.com/rails/responders'
))
expect
(
subject
).
to
include
(
link
(
'rails/responders'
,
'https://github.com/rails/responders'
))
...
...
spec/lib/gitlab/dependency_linker/gemspec_linker_spec.rb
View file @
59db98a0
...
@@ -43,8 +43,8 @@ describe Gitlab::DependencyLinker::GemspecLinker do
...
@@ -43,8 +43,8 @@ describe Gitlab::DependencyLinker::GemspecLinker do
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
end
end
it
'
links
the gem name'
do
it
'
does not link
the gem name'
do
expect
(
subject
).
to
include
(
link
(
'gitlab_git'
,
'https://rubygems.org/gems/gitlab_git'
))
expect
(
subject
).
not_
to
include
(
link
(
'gitlab_git'
,
'https://rubygems.org/gems/gitlab_git'
))
end
end
it
'links the license'
do
it
'links the license'
do
...
...
spec/lib/gitlab/dependency_linker/package_json_linker_spec.rb
View file @
59db98a0
...
@@ -33,7 +33,8 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
...
@@ -33,7 +33,8 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
"express": "4.2.x",
"express": "4.2.x",
"bigpipe": "bigpipe/pagelet",
"bigpipe": "bigpipe/pagelet",
"plates": "https://github.com/flatiron/plates/tarball/master",
"plates": "https://github.com/flatiron/plates/tarball/master",
"karma": "^1.4.1"
"karma": "^1.4.1",
"random": "git+https://EdOverflow@github.com/example/example.git"
},
},
"devDependencies": {
"devDependencies": {
"vows": "^0.7.0",
"vows": "^0.7.0",
...
@@ -51,8 +52,8 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
...
@@ -51,8 +52,8 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
end
end
it
'
links
the module name'
do
it
'
does not link
the module name'
do
expect
(
subject
).
to
include
(
link
(
'module-name'
,
'https://npmjs.com/package/module-name'
))
expect
(
subject
).
not_
to
include
(
link
(
'module-name'
,
'https://npmjs.com/package/module-name'
))
end
end
it
'links the homepage'
do
it
'links the homepage'
do
...
@@ -71,14 +72,21 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
...
@@ -71,14 +72,21 @@ describe Gitlab::DependencyLinker::PackageJsonLinker do
expect
(
subject
).
to
include
(
link
(
'primus'
,
'https://npmjs.com/package/primus'
))
expect
(
subject
).
to
include
(
link
(
'primus'
,
'https://npmjs.com/package/primus'
))
expect
(
subject
).
to
include
(
link
(
'async'
,
'https://npmjs.com/package/async'
))
expect
(
subject
).
to
include
(
link
(
'async'
,
'https://npmjs.com/package/async'
))
expect
(
subject
).
to
include
(
link
(
'express'
,
'https://npmjs.com/package/express'
))
expect
(
subject
).
to
include
(
link
(
'express'
,
'https://npmjs.com/package/express'
))
expect
(
subject
).
to
include
(
link
(
'bigpipe'
,
'https://npmjs.com/package/bigpipe'
))
expect
(
subject
).
to
include
(
link
(
'plates'
,
'https://npmjs.com/package/plates'
))
expect
(
subject
).
to
include
(
link
(
'karma'
,
'https://npmjs.com/package/karma'
))
expect
(
subject
).
to
include
(
link
(
'karma'
,
'https://npmjs.com/package/karma'
))
expect
(
subject
).
to
include
(
link
(
'vows'
,
'https://npmjs.com/package/vows'
))
expect
(
subject
).
to
include
(
link
(
'vows'
,
'https://npmjs.com/package/vows'
))
expect
(
subject
).
to
include
(
link
(
'assume'
,
'https://npmjs.com/package/assume'
))
expect
(
subject
).
to
include
(
link
(
'assume'
,
'https://npmjs.com/package/assume'
))
expect
(
subject
).
to
include
(
link
(
'pre-commit'
,
'https://npmjs.com/package/pre-commit'
))
expect
(
subject
).
to
include
(
link
(
'pre-commit'
,
'https://npmjs.com/package/pre-commit'
))
end
end
it
'links dependencies to URL detected on value'
do
expect
(
subject
).
to
include
(
link
(
'bigpipe'
,
'https://github.com/bigpipe/pagelet'
))
expect
(
subject
).
to
include
(
link
(
'plates'
,
'https://github.com/flatiron/plates/tarball/master'
))
end
it
'does not link to NPM when invalid git URL'
do
expect
(
subject
).
not_to
include
(
link
(
'random'
,
'https://npmjs.com/package/random'
))
end
it
'links GitHub repos'
do
it
'links GitHub repos'
do
expect
(
subject
).
to
include
(
link
(
'bigpipe/pagelet'
,
'https://github.com/bigpipe/pagelet'
))
expect
(
subject
).
to
include
(
link
(
'bigpipe/pagelet'
,
'https://github.com/bigpipe/pagelet'
))
end
end
...
...
spec/lib/gitlab/dependency_linker/parser/gemfile_spec.rb
0 → 100644
View file @
59db98a0
require
'rails_helper'
describe
Gitlab
::
DependencyLinker
::
Parser
::
Gemfile
do
describe
'#parse'
do
let
(
:file_content
)
do
<<-
CONTENT
.
strip_heredoc
source 'https://rubygems.org'
gem "rails", '4.2.6', github: "rails/rails"
gem 'rails-deprecated_sanitizer', '~> 1.0.3'
gem 'responders', '~> 2.0', :github => 'rails/responders'
gem 'sprockets', '~> 3.6.0', git: 'https://gitlab.example.com/gems/sprockets'
gem 'default_value_for', '~> 3.0.0'
CONTENT
end
subject
{
described_class
.
new
(
file_content
).
parse
(
keyword:
'gem'
)
}
def
fetch_package
(
name
)
subject
.
find
{
|
package
|
package
.
name
==
name
}
end
it
'returns parsed packages'
do
expect
(
subject
.
size
).
to
eq
(
5
)
expect
(
subject
).
to
all
(
be_a
(
Gitlab
::
DependencyLinker
::
Package
))
end
it
'packages respond to name and external_ref accordingly'
do
expect
(
fetch_package
(
'rails'
)).
to
have_attributes
(
name:
'rails'
,
github_ref:
'rails/rails'
,
git_ref:
nil
)
expect
(
fetch_package
(
'sprockets'
)).
to
have_attributes
(
name:
'sprockets'
,
github_ref:
nil
,
git_ref:
'https://gitlab.example.com/gems/sprockets'
)
expect
(
fetch_package
(
'default_value_for'
)).
to
have_attributes
(
name:
'default_value_for'
,
github_ref:
nil
,
git_ref:
nil
)
end
end
end
spec/lib/gitlab/dependency_linker/podfile_linker_spec.rb
View file @
59db98a0
...
@@ -43,7 +43,10 @@ describe Gitlab::DependencyLinker::PodfileLinker do
...
@@ -43,7 +43,10 @@ describe Gitlab::DependencyLinker::PodfileLinker do
it
'links packages'
do
it
'links packages'
do
expect
(
subject
).
to
include
(
link
(
'AFNetworking'
,
'https://cocoapods.org/pods/AFNetworking'
))
expect
(
subject
).
to
include
(
link
(
'AFNetworking'
,
'https://cocoapods.org/pods/AFNetworking'
))
expect
(
subject
).
to
include
(
link
(
'Interstellar/Core'
,
'https://cocoapods.org/pods/Interstellar'
))
end
it
'links external packages'
do
expect
(
subject
).
to
include
(
link
(
'Interstellar/Core'
,
'https://github.com/ashfurrow/Interstellar.git'
))
end
end
it
'links Git repos'
do
it
'links Git repos'
do
...
...
spec/lib/gitlab/dependency_linker/podspec_linker_spec.rb
View file @
59db98a0
...
@@ -42,8 +42,8 @@ describe Gitlab::DependencyLinker::PodspecLinker do
...
@@ -42,8 +42,8 @@ describe Gitlab::DependencyLinker::PodspecLinker do
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
%{<a href="#{url}" rel="nofollow noreferrer noopener" target="_blank">#{name}</a>}
end
end
it
'
links the gem
name'
do
it
'
does not link the pod
name'
do
expect
(
subject
).
to
include
(
link
(
'Reachability'
,
'https://cocoapods.org/pods/Reachability'
))
expect
(
subject
).
not_
to
include
(
link
(
'Reachability'
,
'https://cocoapods.org/pods/Reachability'
))
end
end
it
'links the license'
do
it
'links the license'
do
...
...
spec/lib/gitlab/import_export/merge_request_parser_spec.rb
View file @
59db98a0
...
@@ -41,4 +41,20 @@ describe Gitlab::ImportExport::MergeRequestParser do
...
@@ -41,4 +41,20 @@ describe Gitlab::ImportExport::MergeRequestParser do
expect
(
parsed_merge_request
).
to
eq
(
merge_request
)
expect
(
parsed_merge_request
).
to
eq
(
merge_request
)
end
end
context
'when the merge request has diffs'
do
let
(
:merge_request
)
do
build
(
:merge_request
,
source_project:
forked_project
,
target_project:
project
)
end
context
'when the diff is invalid'
do
let
(
:merge_request_diff
)
{
build
(
:merge_request_diff
,
merge_request:
merge_request
,
base_commit_sha:
'foobar'
)
}
it
'sets the diff to nil'
do
expect
(
merge_request_diff
).
to
be_invalid
expect
(
merge_request_diff
.
merge_request
).
to
eq
merge_request
expect
(
parsed_merge_request
.
merge_request_diff
).
to
be_nil
end
end
end
end
end
spec/lib/gitlab/kubernetes/kube_client_spec.rb
View file @
59db98a0
...
@@ -50,6 +50,36 @@ describe Gitlab::Kubernetes::KubeClient do
...
@@ -50,6 +50,36 @@ describe Gitlab::Kubernetes::KubeClient do
end
end
end
end
describe
'#initialize'
do
shared_examples
'local address'
do
it
'blocks local addresses'
do
expect
{
client
}.
to
raise_error
(
Gitlab
::
UrlBlocker
::
BlockedUrlError
)
end
context
'when local requests are allowed'
do
before
do
stub_application_setting
(
allow_local_requests_from_hooks_and_services:
true
)
end
it
'allows local addresses'
do
expect
{
client
}.
not_to
raise_error
end
end
end
context
'localhost address'
do
let
(
:api_url
)
{
'http://localhost:22'
}
it_behaves_like
'local address'
end
context
'private network address'
do
let
(
:api_url
)
{
'http://192.168.1.2:3003'
}
it_behaves_like
'local address'
end
end
describe
'#core_client'
do
describe
'#core_client'
do
subject
{
client
.
core_client
}
subject
{
client
.
core_client
}
...
...
spec/mailers/notify_spec.rb
View file @
59db98a0
...
@@ -208,6 +208,7 @@ describe Notify do
...
@@ -208,6 +208,7 @@ describe Notify do
let
(
:new_issue
)
{
create
(
:issue
)
}
let
(
:new_issue
)
{
create
(
:issue
)
}
subject
{
described_class
.
issue_moved_email
(
recipient
,
issue
,
new_issue
,
current_user
)
}
subject
{
described_class
.
issue_moved_email
(
recipient
,
issue
,
new_issue
,
current_user
)
}
<<<<<<<
HEAD
it_behaves_like
'an answer to an existing thread with reply-by-email enabled'
do
it_behaves_like
'an answer to an existing thread with reply-by-email enabled'
do
let
(
:model
)
{
issue
}
let
(
:model
)
{
issue
}
end
end
...
@@ -215,18 +216,55 @@ describe Notify do
...
@@ -215,18 +216,55 @@ describe Notify do
it_behaves_like
'an unsubscribeable thread'
it_behaves_like
'an unsubscribeable thread'
it_behaves_like
'appearance header and footer enabled'
it_behaves_like
'appearance header and footer enabled'
it_behaves_like
'appearance header and footer not enabled'
it_behaves_like
'appearance header and footer not enabled'
=======
context
'when a user has permissions to access the new issue'
do
before
do
new_issue
.
project
.
add_developer
(
recipient
)
end
it_behaves_like
'an answer to an existing thread with reply-by-email enabled'
do
let
(
:model
)
{
issue
}
end
it_behaves_like
'it should show Gmail Actions View Issue link'
it_behaves_like
'an unsubscribeable thread'
it
'contains description about action taken'
do
is_expected
.
to
have_body_text
'Issue was moved to another project'
end
it
'has the correct subject and body'
do
new_issue_url
=
project_issue_path
(
new_issue
.
project
,
new_issue
)
>>>>>>>
dev
/
master
aggregate_failures
do
is_expected
.
to
have_referable_subject
(
issue
,
reply:
true
)
is_expected
.
to
have_body_text
(
new_issue_url
)
is_expected
.
to
have_body_text
(
project_issue_path
(
project
,
issue
))
end
end
it
'contains description about action taken'
do
it
'contains the issue title'
do
is_expected
.
to
have_body_text
'Issue was moved to another project'
is_expected
.
to
have_body_text
new_issue
.
title
end
end
end
it
'has the correct subject and body'
do
context
'when a user does not permissions to access the new issue'
do
new_issue_url
=
project_issue_path
(
new_issue
.
project
,
new_issue
)
it
'has the correct subject and body'
do
new_issue_url
=
project_issue_path
(
new_issue
.
project
,
new_issue
)
aggregate_failures
do
aggregate_failures
do
is_expected
.
to
have_referable_subject
(
issue
,
reply:
true
)
is_expected
.
to
have_referable_subject
(
issue
,
reply:
true
)
is_expected
.
to
have_body_text
(
new_issue_url
)
is_expected
.
not_to
have_body_text
(
new_issue_url
)
is_expected
.
to
have_body_text
(
project_issue_path
(
project
,
issue
))
is_expected
.
to
have_body_text
(
project_issue_path
(
project
,
issue
))
end
end
it
'does not contain the issue title'
do
is_expected
.
not_to
have_body_text
new_issue
.
title
end
it
'contains information about missing permissions'
do
is_expected
.
to
have_body_text
"You don't have access to the project."
end
end
end
end
end
end
...
...
spec/models/active_session_spec.rb
View file @
59db98a0
...
@@ -7,7 +7,10 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
...
@@ -7,7 +7,10 @@ RSpec.describe ActiveSession, :clean_gitlab_redis_shared_state do
end
end
end
end
let
(
:session
)
{
double
(
:session
,
id:
'6919a6f1bb119dd7396fadc38fd18d0d'
)
}
let
(
:session
)
do
double
(
:session
,
{
id:
'6919a6f1bb119dd7396fadc38fd18d0d'
,
'[]'
:
{}
})
end
let
(
:request
)
do
let
(
:request
)
do
double
(
:request
,
{
double
(
:request
,
{
...
...
spec/models/clusters/platforms/kubernetes_spec.rb
View file @
59db98a0
...
@@ -98,6 +98,22 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
...
@@ -98,6 +98,22 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
it
{
expect
(
kubernetes
.
save
).
to
be_truthy
}
it
{
expect
(
kubernetes
.
save
).
to
be_truthy
}
end
end
context
'when api_url is localhost'
do
let
(
:api_url
)
{
'http://localhost:22'
}
it
{
expect
(
kubernetes
.
save
).
to
be_falsey
}
context
'Application settings allows local requests'
do
before
do
allow
(
ApplicationSetting
)
.
to
receive
(
:current
)
.
and_return
(
ApplicationSetting
.
build_from_defaults
(
allow_local_requests_from_hooks_and_services:
true
))
end
it
{
expect
(
kubernetes
.
save
).
to
be_truthy
}
end
end
end
end
context
'when validates token'
do
context
'when validates token'
do
...
...
spec/models/concerns/issuable_spec.rb
View file @
59db98a0
...
@@ -32,17 +32,56 @@ describe Issuable do
...
@@ -32,17 +32,56 @@ describe Issuable do
end
end
describe
"Validation"
do
describe
"Validation"
do
subject
{
build
(
:issue
)
}
context
'general validations'
do
subject
{
build
(
:issue
)
}
before
do
before
do
allow
(
InternalId
).
to
receive
(
:generate_next
).
and_return
(
nil
)
allow
(
InternalId
).
to
receive
(
:generate_next
).
and_return
(
nil
)
end
it
{
is_expected
.
to
validate_presence_of
(
:project
)
}
it
{
is_expected
.
to
validate_presence_of
(
:iid
)
}
it
{
is_expected
.
to
validate_presence_of
(
:author
)
}
it
{
is_expected
.
to
validate_presence_of
(
:title
)
}
it
{
is_expected
.
to
validate_length_of
(
:title
).
is_at_most
(
255
)
}
end
end
it
{
is_expected
.
to
validate_presence_of
(
:project
)
}
describe
'milestone'
do
it
{
is_expected
.
to
validate_presence_of
(
:iid
)
}
let
(
:project
)
{
create
(
:project
)
}
it
{
is_expected
.
to
validate_presence_of
(
:author
)
}
let
(
:milestone_id
)
{
create
(
:milestone
,
project:
project
).
id
}
it
{
is_expected
.
to
validate_presence_of
(
:title
)
}
let
(
:params
)
do
it
{
is_expected
.
to
validate_length_of
(
:title
).
is_at_most
(
255
)
}
{
title:
'something'
,
project:
project
,
author:
build
(
:user
),
milestone_id:
milestone_id
}
end
subject
{
issuable_class
.
new
(
params
)
}
context
'with correct params'
do
it
{
is_expected
.
to
be_valid
}
end
context
'with empty string milestone'
do
let
(
:milestone_id
)
{
''
}
it
{
is_expected
.
to
be_valid
}
end
context
'with nil milestone id'
do
let
(
:milestone_id
)
{
nil
}
it
{
is_expected
.
to
be_valid
}
end
context
'with a milestone id from another project'
do
let
(
:milestone_id
)
{
create
(
:milestone
).
id
}
it
{
is_expected
.
to
be_invalid
}
end
end
end
end
describe
"Scope"
do
describe
"Scope"
do
...
@@ -66,6 +105,48 @@ describe Issuable do
...
@@ -66,6 +105,48 @@ describe Issuable do
end
end
end
end
describe
'#milestone_available?'
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
def
build_issuable
(
milestone_id
)
issuable_class
.
new
(
project:
project
,
milestone_id:
milestone_id
)
end
it
'returns true with a milestone from the issue project'
do
milestone
=
create
(
:milestone
,
project:
project
)
expect
(
build_issuable
(
milestone
.
id
).
milestone_available?
).
to
be_truthy
end
it
'returns true with a milestone from the issue project group'
do
milestone
=
create
(
:milestone
,
group:
group
)
expect
(
build_issuable
(
milestone
.
id
).
milestone_available?
).
to
be_truthy
end
it
'returns true with a milestone from the the parent of the issue project group'
,
:nested_groups
do
parent
=
create
(
:group
)
group
.
update
(
parent:
parent
)
milestone
=
create
(
:milestone
,
group:
parent
)
expect
(
build_issuable
(
milestone
.
id
).
milestone_available?
).
to
be_truthy
end
it
'returns false with a milestone from another project'
do
milestone
=
create
(
:milestone
)
expect
(
build_issuable
(
milestone
.
id
).
milestone_available?
).
to
be_falsey
end
it
'returns false with a milestone from another group'
do
milestone
=
create
(
:milestone
,
group:
create
(
:group
))
expect
(
build_issuable
(
milestone
.
id
).
milestone_available?
).
to
be_falsey
end
end
describe
".search"
do
describe
".search"
do
let!
(
:searchable_issue
)
{
create
(
:issue
,
title:
"Searchable awesome issue"
)
}
let!
(
:searchable_issue
)
{
create
(
:issue
,
title:
"Searchable awesome issue"
)
}
let!
(
:searchable_issue2
)
{
create
(
:issue
,
title:
'Aw'
)
}
let!
(
:searchable_issue2
)
{
create
(
:issue
,
title:
'Aw'
)
}
...
...
spec/models/concerns/milestoneish_spec.rb
View file @
59db98a0
...
@@ -48,7 +48,7 @@ describe Milestone, 'Milestoneish' do
...
@@ -48,7 +48,7 @@ describe Milestone, 'Milestoneish' do
merge_request_2
=
create
(
:labeled_merge_request
,
labels:
[
label_1
],
source_project:
project
,
source_branch:
'branch_2'
,
milestone:
milestone
)
merge_request_2
=
create
(
:labeled_merge_request
,
labels:
[
label_1
],
source_project:
project
,
source_branch:
'branch_2'
,
milestone:
milestone
)
merge_request_3
=
create
(
:labeled_merge_request
,
labels:
[
label_3
],
source_project:
project
,
source_branch:
'branch_3'
,
milestone:
milestone
)
merge_request_3
=
create
(
:labeled_merge_request
,
labels:
[
label_3
],
source_project:
project
,
source_branch:
'branch_3'
,
milestone:
milestone
)
merge_requests
=
milestone
.
sorted_merge_requests
merge_requests
=
milestone
.
sorted_merge_requests
(
member
)
expect
(
merge_requests
.
first
).
to
eq
(
merge_request_2
)
expect
(
merge_requests
.
first
).
to
eq
(
merge_request_2
)
expect
(
merge_requests
.
second
).
to
eq
(
merge_request_1
)
expect
(
merge_requests
.
second
).
to
eq
(
merge_request_1
)
...
@@ -56,6 +56,51 @@ describe Milestone, 'Milestoneish' do
...
@@ -56,6 +56,51 @@ describe Milestone, 'Milestoneish' do
end
end
end
end
describe
'#merge_requests_visible_to_user'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
source_project:
project
,
milestone:
milestone
)
}
context
'when project is private'
do
before
do
project
.
update
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PRIVATE
)
end
it
'does not return any merge request for a non member'
do
merge_requests
=
milestone
.
merge_requests_visible_to_user
(
non_member
)
expect
(
merge_requests
).
to
be_empty
end
it
'returns milestone merge requests for a member'
do
merge_requests
=
milestone
.
merge_requests_visible_to_user
(
member
)
expect
(
merge_requests
).
to
contain_exactly
(
merge_request
)
end
end
context
'when project is public'
do
context
'when merge requests are available to anyone'
do
it
'returns milestone merge requests for a non member'
do
merge_requests
=
milestone
.
merge_requests_visible_to_user
(
non_member
)
expect
(
merge_requests
).
to
contain_exactly
(
merge_request
)
end
end
context
'when merge requests are available to project members'
do
before
do
project
.
project_feature
.
update
(
merge_requests_access_level:
ProjectFeature
::
PRIVATE
)
end
it
'does not return any merge request for a non member'
do
merge_requests
=
milestone
.
merge_requests_visible_to_user
(
non_member
)
expect
(
merge_requests
).
to
be_empty
end
it
'returns milestone merge requests for a member'
do
merge_requests
=
milestone
.
merge_requests_visible_to_user
(
member
)
expect
(
merge_requests
).
to
contain_exactly
(
merge_request
)
end
end
end
end
describe
'#closed_items_count'
do
describe
'#closed_items_count'
do
it
'does not count confidential issues for non project members'
do
it
'does not count confidential issues for non project members'
do
expect
(
milestone
.
closed_items_count
(
non_member
)).
to
eq
2
expect
(
milestone
.
closed_items_count
(
non_member
)).
to
eq
2
...
...
spec/models/issue/metrics_spec.rb
View file @
59db98a0
...
@@ -9,7 +9,7 @@ describe Issue::Metrics do
...
@@ -9,7 +9,7 @@ describe Issue::Metrics do
context
"milestones"
do
context
"milestones"
do
it
"records the first time an issue is associated with a milestone"
do
it
"records the first time an issue is associated with a milestone"
do
time
=
Time
.
now
time
=
Time
.
now
Timecop
.
freeze
(
time
)
{
subject
.
update
(
milestone:
create
(
:milestone
))
}
Timecop
.
freeze
(
time
)
{
subject
.
update
(
milestone:
create
(
:milestone
,
project:
project
))
}
metrics
=
subject
.
metrics
metrics
=
subject
.
metrics
expect
(
metrics
).
to
be_present
expect
(
metrics
).
to
be_present
...
@@ -18,9 +18,9 @@ describe Issue::Metrics do
...
@@ -18,9 +18,9 @@ describe Issue::Metrics do
it
"does not record the second time an issue is associated with a milestone"
do
it
"does not record the second time an issue is associated with a milestone"
do
time
=
Time
.
now
time
=
Time
.
now
Timecop
.
freeze
(
time
)
{
subject
.
update
(
milestone:
create
(
:milestone
))
}
Timecop
.
freeze
(
time
)
{
subject
.
update
(
milestone:
create
(
:milestone
,
project:
project
))
}
Timecop
.
freeze
(
time
+
2
.
hours
)
{
subject
.
update
(
milestone:
nil
)
}
Timecop
.
freeze
(
time
+
2
.
hours
)
{
subject
.
update
(
milestone:
nil
)
}
Timecop
.
freeze
(
time
+
6
.
hours
)
{
subject
.
update
(
milestone:
create
(
:milestone
))
}
Timecop
.
freeze
(
time
+
6
.
hours
)
{
subject
.
update
(
milestone:
create
(
:milestone
,
project:
project
))
}
metrics
=
subject
.
metrics
metrics
=
subject
.
metrics
expect
(
metrics
).
to
be_present
expect
(
metrics
).
to
be_present
...
...
spec/models/merge_request_diff_spec.rb
View file @
59db98a0
...
@@ -3,6 +3,18 @@ require 'spec_helper'
...
@@ -3,6 +3,18 @@ require 'spec_helper'
describe
MergeRequestDiff
do
describe
MergeRequestDiff
do
let
(
:diff_with_commits
)
{
create
(
:merge_request
).
merge_request_diff
}
let
(
:diff_with_commits
)
{
create
(
:merge_request
).
merge_request_diff
}
describe
'validations'
do
subject
{
diff_with_commits
}
it
'checks sha format of base_commit_sha, head_commit_sha and start_commit_sha'
do
subject
.
base_commit_sha
=
subject
.
head_commit_sha
=
subject
.
start_commit_sha
=
'foobar'
expect
(
subject
.
valid?
).
to
be
false
expect
(
subject
.
errors
.
count
).
to
eq
3
expect
(
subject
.
errors
).
to
all
(
include
(
'is not a valid SHA'
))
end
end
describe
'create new record'
do
describe
'create new record'
do
subject
{
diff_with_commits
}
subject
{
diff_with_commits
}
...
@@ -78,7 +90,7 @@ describe MergeRequestDiff do
...
@@ -78,7 +90,7 @@ describe MergeRequestDiff do
it
'returns persisted diffs if cannot compare with diff refs'
do
it
'returns persisted diffs if cannot compare with diff refs'
do
expect
(
diff
).
to
receive
(
:load_diffs
).
and_call_original
expect
(
diff
).
to
receive
(
:load_diffs
).
and_call_original
diff
.
update!
(
head_commit_sha:
'invalid-sha'
)
diff
.
update!
(
head_commit_sha:
Digest
::
SHA1
.
hexdigest
(
SecureRandom
.
hex
)
)
diff
.
diffs
.
diff_files
diff
.
diffs
.
diff_files
end
end
...
...
spec/models/milestone_spec.rb
View file @
59db98a0
...
@@ -182,7 +182,7 @@ describe Milestone do
...
@@ -182,7 +182,7 @@ describe Milestone do
describe
'#total_items_count'
do
describe
'#total_items_count'
do
before
do
before
do
create
:closed_issue
,
milestone:
milestone
,
project:
project
create
:closed_issue
,
milestone:
milestone
,
project:
project
create
:merge_request
,
milestone:
milestone
create
:merge_request
,
milestone:
milestone
,
source_project:
project
end
end
it
'returns total count of issues and merge requests assigned to milestone'
do
it
'returns total count of issues and merge requests assigned to milestone'
do
...
@@ -192,10 +192,10 @@ describe Milestone do
...
@@ -192,10 +192,10 @@ describe Milestone do
describe
'#can_be_closed?'
do
describe
'#can_be_closed?'
do
before
do
before
do
milestone
=
create
:milestone
milestone
=
create
:milestone
,
project:
project
create
:closed_issue
,
milestone:
milestone
create
:closed_issue
,
milestone:
milestone
,
project:
project
create
:issue
create
:issue
,
project:
project
end
end
it
'returns true if milestone active and all nested issues closed'
do
it
'returns true if milestone active and all nested issues closed'
do
...
...
spec/models/project_services/prometheus_service_spec.rb
View file @
59db98a0
...
@@ -33,18 +33,38 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
...
@@ -33,18 +33,38 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
describe
'Validations'
do
describe
'Validations'
do
context
'when manual_configuration is enabled'
do
context
'when manual_configuration is enabled'
do
before
do
before
do
s
ubject
.
manual_configuration
=
true
s
ervice
.
manual_configuration
=
true
end
end
it
{
is_expected
.
to
validate_presence_of
(
:api_url
)
}
it
'validates presence of api_url'
do
expect
(
service
).
to
validate_presence_of
(
:api_url
)
end
end
end
context
'when manual configuration is disabled'
do
context
'when manual configuration is disabled'
do
before
do
before
do
s
ubject
.
manual_configuration
=
false
s
ervice
.
manual_configuration
=
false
end
end
it
{
is_expected
.
not_to
validate_presence_of
(
:api_url
)
}
it
'does not validate presence of api_url'
do
expect
(
service
).
not_to
validate_presence_of
(
:api_url
)
end
end
context
'when the api_url domain points to localhost or local network'
do
let
(
:domain
)
{
Addressable
::
URI
.
parse
(
service
.
api_url
).
hostname
}
it
'cannot query'
do
expect
(
service
.
can_query?
).
to
be
true
aggregate_failures
do
[
'127.0.0.1'
,
'192.168.2.3'
].
each
do
|
url
|
allow
(
Addrinfo
).
to
receive
(
:getaddrinfo
).
with
(
domain
,
any_args
).
and_return
([
Addrinfo
.
tcp
(
url
,
80
)])
expect
(
service
.
can_query?
).
to
be
false
end
end
end
end
end
end
end
...
@@ -74,30 +94,35 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
...
@@ -74,30 +94,35 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
end
describe
'#prometheus_client'
do
describe
'#prometheus_client'
do
let
(
:api_url
)
{
'http://some_url'
}
before
do
service
.
active
=
true
service
.
api_url
=
api_url
service
.
manual_configuration
=
manual_configuration
end
context
'manual configuration is enabled'
do
context
'manual configuration is enabled'
do
let
(
:
api_url
)
{
'http://some_url'
}
let
(
:
manual_configuration
)
{
true
}
before
do
it
'returns rest client from api_url'
do
subject
.
active
=
true
expect
(
service
.
prometheus_client
.
url
).
to
eq
(
api_url
)
subject
.
manual_configuration
=
true
subject
.
api_url
=
api_url
end
end
it
'returns rest client from api_url'
do
it
'calls valid?'
do
expect
(
subject
.
prometheus_client
.
url
).
to
eq
(
api_url
)
allow
(
service
).
to
receive
(
:valid?
).
and_call_original
expect
(
service
.
prometheus_client
).
not_to
be_nil
expect
(
service
).
to
have_received
(
:valid?
)
end
end
end
end
context
'manual configuration is disabled'
do
context
'manual configuration is disabled'
do
let
(
:api_url
)
{
'http://some_url'
}
let
(
:manual_configuration
)
{
false
}
before
do
subject
.
manual_configuration
=
false
subject
.
api_url
=
api_url
end
it
'no client provided'
do
it
'no client provided'
do
expect
(
s
ubject
.
prometheus_client
).
to
be_nil
expect
(
s
ervice
.
prometheus_client
).
to
be_nil
end
end
end
end
end
end
...
...
spec/policies/commit_policy_spec.rb
0 → 100644
View file @
59db98a0
require
'spec_helper'
describe
CommitPolicy
do
describe
'#rules'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:commit
)
{
project
.
repository
.
head_commit
}
let
(
:policy
)
{
described_class
.
new
(
user
,
commit
)
}
context
'when project is public'
do
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
)
}
it
'can read commit and create a note'
do
expect
(
policy
).
to
be_allowed
(
:read_commit
)
end
context
'when repository access level is private'
do
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
,
:repository_private
)
}
it
'can not read commit and create a note'
do
expect
(
policy
).
to
be_disallowed
(
:read_commit
)
end
context
'when the user is a project member'
do
before
do
project
.
add_developer
(
user
)
end
it
'can read commit and create a note'
do
expect
(
policy
).
to
be_allowed
(
:read_commit
)
end
end
end
end
context
'when project is private'
do
let
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
it
'can not read commit and create a note'
do
expect
(
policy
).
to
be_disallowed
(
:read_commit
)
end
context
'when the user is a project member'
do
before
do
project
.
add_developer
(
user
)
end
it
'can read commit and create a note'
do
expect
(
policy
).
to
be_allowed
(
:read_commit
)
end
end
end
end
end
spec/policies/group_policy_spec.rb
View file @
59db98a0
...
@@ -74,6 +74,38 @@ describe GroupPolicy do
...
@@ -74,6 +74,38 @@ describe GroupPolicy do
end
end
end
end
context
'with no user and public project'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
nil
}
before
do
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
user
,
link_group_access:
ProjectGroupLink
::
DEVELOPER
).
execute
(
group
)
end
it
{
expect_disallowed
(
:read_group
)
}
end
context
'with foreign user and public project'
do
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
create
(
:user
)
}
before
do
Projects
::
GroupLinks
::
CreateService
.
new
(
project
,
user
,
link_group_access:
ProjectGroupLink
::
DEVELOPER
).
execute
(
group
)
end
it
{
expect_disallowed
(
:read_group
)
}
end
context
'has projects'
do
context
'has projects'
do
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
group
)
}
...
@@ -82,17 +114,25 @@ describe GroupPolicy do
...
@@ -82,17 +114,25 @@ describe GroupPolicy do
project
.
add_developer
(
current_user
)
project
.
add_developer
(
current_user
)
end
end
<<<<<<<
HEAD
it
do
it
do
expect_allowed
(
:read_group
,
:read_list
,
:read_label
)
expect_allowed
(
:read_group
,
:read_list
,
:read_label
)
end
end
=======
it
{
expect_allowed
(
:read_label
)
}
>>>>>>>
dev
/
master
context
'in subgroups'
,
:nested_groups
do
context
'in subgroups'
,
:nested_groups
do
let
(
:subgroup
)
{
create
(
:group
,
:private
,
parent:
group
)
}
let
(
:subgroup
)
{
create
(
:group
,
:private
,
parent:
group
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
subgroup
)
}
let
(
:project
)
{
create
(
:project
,
namespace:
subgroup
)
}
<<<<<<<
HEAD
it
do
it
do
expect_allowed
(
:read_group
,
:read_list
,
:read_label
)
expect_allowed
(
:read_group
,
:read_list
,
:read_label
)
end
end
=======
it
{
expect_allowed
(
:read_label
)
}
>>>>>>>
dev
/
master
end
end
end
end
...
...
spec/policies/note_policy_spec.rb
View file @
59db98a0
require
'spec_helper'
require
'spec_helper'
describe
NotePolicy
,
mdoels:
true
do
describe
NotePolicy
do
describe
'#rules'
do
describe
'#rules'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:project
)
{
create
(
:project
,
:public
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
)
}
let
(
:noteable
)
{
issue
}
def
policies
(
noteable
=
nil
)
let
(
:policy
)
{
described_class
.
new
(
user
,
note
)
}
return
@policies
if
@policies
let
(
:note
)
{
create
(
:note
,
noteable:
noteable
,
author:
user
,
project:
project
)
}
noteable
||=
issue
note
=
if
noteable
.
is_a?
(
Commit
)
create
(
:note_on_commit
,
commit_id:
noteable
.
id
,
author:
user
,
project:
project
)
else
create
(
:note
,
noteable:
noteable
,
author:
user
,
project:
project
)
end
@policies
=
described_class
.
new
(
user
,
note
)
end
shared_examples_for
'a discussion with a private noteable'
do
shared_examples_for
'a discussion with a private noteable'
do
let
(
:noteable
)
{
issue
}
let
(
:policy
)
{
policies
(
noteable
)
}
context
'when the note author can no longer see the noteable'
do
context
'when the note author can no longer see the noteable'
do
it
'can not edit nor read the note'
do
it
'can not edit nor read the note'
do
expect
(
policy
).
to
be_disallowed
(
:admin_note
)
expect
(
policy
).
to
be_disallowed
(
:admin_note
)
...
@@ -46,12 +33,21 @@ describe NotePolicy, mdoels: true do
...
@@ -46,12 +33,21 @@ describe NotePolicy, mdoels: true do
end
end
end
end
context
'when the project is private'
do
context
'when the noteable is a commit'
do
let
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
let
(
:commit
)
{
project
.
repository
.
head_commit
}
let
(
:note
)
{
create
(
:note_on_commit
,
commit_id:
commit
.
id
,
author:
user
,
project:
project
)
}
context
'when the project is private'
do
let
(
:project
)
{
create
(
:project
,
:private
,
:repository
)
}
it_behaves_like
'a discussion with a private noteable'
end
context
'when the noteable is a commit'
do
context
'when the project is public'
do
it_behaves_like
'a discussion with a private noteable'
do
context
'when repository access level is private'
do
let
(
:noteable
)
{
project
.
repository
.
head_commit
}
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
,
:repository_private
)
}
it_behaves_like
'a discussion with a private noteable'
end
end
end
end
end
end
...
@@ -59,44 +55,44 @@ describe NotePolicy, mdoels: true do
...
@@ -59,44 +55,44 @@ describe NotePolicy, mdoels: true do
context
'when the project is public'
do
context
'when the project is public'
do
context
'when the note author is not a project member'
do
context
'when the note author is not a project member'
do
it
'can edit a note'
do
it
'can edit a note'
do
expect
(
polic
ies
).
to
be_allowed
(
:admin_note
)
expect
(
polic
y
).
to
be_allowed
(
:admin_note
)
expect
(
polic
ies
).
to
be_allowed
(
:resolve_note
)
expect
(
polic
y
).
to
be_allowed
(
:resolve_note
)
expect
(
polic
ies
).
to
be_allowed
(
:read_note
)
expect
(
polic
y
).
to
be_allowed
(
:read_note
)
end
end
end
end
context
'when the noteable is a project snippet'
do
context
'when the noteable is a project snippet'
do
it
'can edit note'
do
let
(
:noteable
)
{
create
(
:project_snippet
,
:public
,
project:
project
)
}
policies
=
policies
(
create
(
:project_snippet
,
:public
,
project:
project
))
expect
(
policies
).
to
be_allowed
(
:admin_note
)
it
'can edit note'
do
expect
(
policies
).
to
be_allowed
(
:resolve_note
)
expect
(
policy
).
to
be_allowed
(
:admin_note
)
expect
(
policies
).
to
be_allowed
(
:read_note
)
expect
(
policy
).
to
be_allowed
(
:resolve_note
)
expect
(
policy
).
to
be_allowed
(
:read_note
)
end
end
context
'when it is private'
do
context
'when it is private'
do
it_behaves_like
'a discussion with a private noteable'
do
let
(
:noteable
)
{
create
(
:project_snippet
,
:private
,
project:
project
)
}
let
(
:noteable
)
{
create
(
:project_snippet
,
:private
,
project:
project
)
}
end
it_behaves_like
'a discussion with a private noteable'
end
end
end
end
context
'when the noteable is a personal snippet'
do
context
'when the noteable is a personal snippet'
do
it
'can edit note'
do
let
(
:noteable
)
{
create
(
:personal_snippet
,
:public
)
}
policies
=
policies
(
create
(
:personal_snippet
,
:public
))
expect
(
policies
).
to
be_allowed
(
:admin_note
)
it
'can edit note'
do
expect
(
policies
).
to
be_allowed
(
:resolve_note
)
expect
(
policy
).
to
be_allowed
(
:admin_note
)
expect
(
policies
).
to
be_allowed
(
:read_note
)
expect
(
policy
).
to
be_allowed
(
:resolve_note
)
expect
(
policy
).
to
be_allowed
(
:read_note
)
end
end
context
'when it is private'
do
context
'when it is private'
do
it
'can not edit nor read the note'
do
let
(
:noteable
)
{
create
(
:personal_snippet
,
:private
)
}
policies
=
policies
(
create
(
:personal_snippet
,
:private
))
expect
(
policies
).
to
be_disallowed
(
:admin_note
)
it
'can not edit nor read the note'
do
expect
(
policies
).
to
be_disallowed
(
:resolve_note
)
expect
(
policy
).
to
be_disallowed
(
:admin_note
)
expect
(
policies
).
to
be_disallowed
(
:read_note
)
expect
(
policy
).
to
be_disallowed
(
:resolve_note
)
expect
(
policy
).
to
be_disallowed
(
:read_note
)
end
end
end
end
end
end
...
@@ -120,20 +116,20 @@ describe NotePolicy, mdoels: true do
...
@@ -120,20 +116,20 @@ describe NotePolicy, mdoels: true do
end
end
it
'can edit a note'
do
it
'can edit a note'
do
expect
(
polic
ies
).
to
be_allowed
(
:admin_note
)
expect
(
polic
y
).
to
be_allowed
(
:admin_note
)
expect
(
polic
ies
).
to
be_allowed
(
:resolve_note
)
expect
(
polic
y
).
to
be_allowed
(
:resolve_note
)
expect
(
polic
ies
).
to
be_allowed
(
:read_note
)
expect
(
polic
y
).
to
be_allowed
(
:read_note
)
end
end
end
end
context
'when the note author is not a project member'
do
context
'when the note author is not a project member'
do
it
'can not edit a note'
do
it
'can not edit a note'
do
expect
(
polic
ies
).
to
be_disallowed
(
:admin_note
)
expect
(
polic
y
).
to
be_disallowed
(
:admin_note
)
expect
(
polic
ies
).
to
be_disallowed
(
:resolve_note
)
expect
(
polic
y
).
to
be_disallowed
(
:resolve_note
)
end
end
it
'can read a note'
do
it
'can read a note'
do
expect
(
polic
ies
).
to
be_allowed
(
:read_note
)
expect
(
polic
y
).
to
be_allowed
(
:read_note
)
end
end
end
end
end
end
...
...
spec/policies/project_policy_spec.rb
View file @
59db98a0
...
@@ -131,22 +131,26 @@ describe ProjectPolicy do
...
@@ -131,22 +131,26 @@ describe ProjectPolicy do
subject
{
described_class
.
new
(
owner
,
project
)
}
subject
{
described_class
.
new
(
owner
,
project
)
}
context
'when the feature is disabled'
do
context
'when the feature is disabled'
do
it
'does not include the issues permissions'
do
before
do
project
.
issues_enabled
=
false
project
.
issues_enabled
=
false
project
.
save!
project
.
save!
end
it
'does not include the issues permissions'
do
expect_disallowed
:read_issue
,
:read_issue_iid
,
:create_issue
,
:update_issue
,
:admin_issue
expect_disallowed
:read_issue
,
:read_issue_iid
,
:create_issue
,
:update_issue
,
:admin_issue
end
end
end
context
'when the feature is disabled and external tracker configured'
do
it
'disables boards and lists permissions'
do
it
'does not include the issues permissions'
do
expect_disallowed
:read_board
,
:create_board
,
:update_board
,
:admin_board
create
(
:jira_service
,
project:
project
)
expect_disallowed
:read_list
,
:create_list
,
:update_list
,
:admin_list
end
project
.
issues_enabled
=
false
context
'when external tracker configured'
do
project
.
save!
it
'does not include the issues permissions'
do
create
(
:jira_service
,
project:
project
)
expect_disallowed
:read_issue
,
:read_issue_iid
,
:create_issue
,
:update_issue
,
:admin_issue
expect_disallowed
:read_issue
,
:read_issue_iid
,
:create_issue
,
:update_issue
,
:admin_issue
end
end
end
end
end
end
end
...
...
spec/requests/api/commits_spec.rb
View file @
59db98a0
...
@@ -1430,8 +1430,8 @@ describe API::Commits do
...
@@ -1430,8 +1430,8 @@ describe API::Commits do
end
end
describe
'GET /projects/:id/repository/commits/:sha/merge_requests'
do
describe
'GET /projects/:id/repository/commits/:sha/merge_requests'
do
let
!
(
:project
)
{
create
(
:project
,
:repository
,
:private
)
}
let
(
:project
)
{
create
(
:project
,
:repository
,
:private
)
}
let
!
(
:merged_mr
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
'master'
,
target_branch:
'feature'
)
}
let
(
:merged_mr
)
{
create
(
:merge_request
,
source_project:
project
,
source_branch:
'master'
,
target_branch:
'feature'
)
}
let
(
:commit
)
{
merged_mr
.
merge_request_diff
.
commits
.
last
}
let
(
:commit
)
{
merged_mr
.
merge_request_diff
.
commits
.
last
}
it
'returns the correct merge request'
do
it
'returns the correct merge request'
do
...
@@ -1456,6 +1456,17 @@ describe API::Commits do
...
@@ -1456,6 +1456,17 @@ describe API::Commits do
expect
(
response
).
to
have_gitlab_http_status
(
404
)
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
context
'public project'
do
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
,
:merge_requests_private
)
}
let
(
:non_member
)
{
create
(
:user
)
}
it
'responds 403 when only members are allowed to read merge requests'
do
get
api
(
"/projects/
#{
project
.
id
}
/repository/commits/
#{
commit
.
id
}
/merge_requests"
,
non_member
)
expect
(
response
).
to
have_gitlab_http_status
(
403
)
end
end
end
end
describe
'GET /projects/:id/repository/commits/:sha/signature'
do
describe
'GET /projects/:id/repository/commits/:sha/signature'
do
...
...
spec/requests/api/issues_spec.rb
View file @
59db98a0
...
@@ -49,7 +49,7 @@ describe API::Issues do
...
@@ -49,7 +49,7 @@ describe API::Issues do
create
(
:label
,
title:
'label'
,
color:
'#FFAABB'
,
project:
project
)
create
(
:label
,
title:
'label'
,
color:
'#FFAABB'
,
project:
project
)
end
end
let!
(
:label_link
)
{
create
(
:label_link
,
label:
label
,
target:
issue
)
}
let!
(
:label_link
)
{
create
(
:label_link
,
label:
label
,
target:
issue
)
}
s
et
(
:milestone
)
{
create
(
:milestone
,
title:
'1.0.0'
,
project:
project
)
}
l
et
(
:milestone
)
{
create
(
:milestone
,
title:
'1.0.0'
,
project:
project
)
}
set
(
:empty_milestone
)
do
set
(
:empty_milestone
)
do
create
(
:milestone
,
title:
'2.0.0'
,
project:
project
)
create
(
:milestone
,
title:
'2.0.0'
,
project:
project
)
end
end
...
...
spec/requests/api/projects_spec.rb
View file @
59db98a0
...
@@ -136,6 +136,7 @@ describe API::Projects do
...
@@ -136,6 +136,7 @@ describe API::Projects do
end
end
let!
(
:public_project
)
{
create
(
:project
,
:public
,
name:
'public_project'
)
}
let!
(
:public_project
)
{
create
(
:project
,
:public
,
name:
'public_project'
)
}
before
do
before
do
project
project
project2
project2
...
@@ -968,8 +969,16 @@ describe API::Projects do
...
@@ -968,8 +969,16 @@ describe API::Projects do
describe
'GET /projects/:id'
do
describe
'GET /projects/:id'
do
context
'when unauthenticated'
do
context
'when unauthenticated'
do
it
'returns the public projects'
do
it
'does not return private projects'
do
public_project
=
create
(
:project
,
:public
)
private_project
=
create
(
:project
,
:private
)
get
api
(
"/projects/
#{
private_project
.
id
}
"
)
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
it
'returns public projects'
do
public_project
=
create
(
:project
,
:repository
,
:public
)
get
api
(
"/projects/
#{
public_project
.
id
}
"
)
get
api
(
"/projects/
#{
public_project
.
id
}
"
)
...
@@ -977,8 +986,34 @@ describe API::Projects do
...
@@ -977,8 +986,34 @@ describe API::Projects do
expect
(
json_response
[
'id'
]).
to
eq
(
public_project
.
id
)
expect
(
json_response
[
'id'
]).
to
eq
(
public_project
.
id
)
expect
(
json_response
[
'description'
]).
to
eq
(
public_project
.
description
)
expect
(
json_response
[
'description'
]).
to
eq
(
public_project
.
description
)
expect
(
json_response
[
'default_branch'
]).
to
eq
(
public_project
.
default_branch
)
expect
(
json_response
[
'default_branch'
]).
to
eq
(
public_project
.
default_branch
)
expect
(
json_response
[
'ci_config_path'
]).
to
eq
(
public_project
.
ci_config_path
)
expect
(
json_response
.
keys
).
not_to
include
(
'permissions'
)
expect
(
json_response
.
keys
).
not_to
include
(
'permissions'
)
end
end
context
'and the project has a private repository'
do
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
,
:repository_private
)
}
let
(
:protected_attributes
)
{
%w(default_branch ci_config_path)
}
it
'hides protected attributes of private repositories if user is not a member'
do
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
protected_attributes
.
each
do
|
attribute
|
expect
(
json_response
.
keys
).
not_to
include
(
attribute
)
end
end
it
'exposes protected attributes of private repositories if user is a member'
do
project
.
add_developer
(
user
)
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
protected_attributes
.
each
do
|
attribute
|
expect
(
json_response
.
keys
).
to
include
(
attribute
)
end
end
end
end
end
context
'when authenticated'
do
context
'when authenticated'
do
...
@@ -1130,6 +1165,26 @@ describe API::Projects do
...
@@ -1130,6 +1165,26 @@ describe API::Projects do
expect
(
json_response
).
to
include
'statistics'
expect
(
json_response
).
to
include
'statistics'
end
end
context
"and the project has a private repository"
do
let
(
:project
)
{
create
(
:project
,
:public
,
:repository
,
:repository_private
)
}
it
"does not include statistics if user is not a member"
do
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
),
params:
{
statistics:
true
}
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
).
not_to
include
'statistics'
end
it
"includes statistics if user is a member"
do
project
.
add_developer
(
user
)
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
),
params:
{
statistics:
true
}
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
).
to
include
'statistics'
end
end
it
"includes import_error if user can admin project"
do
it
"includes import_error if user can admin project"
do
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
"
,
user
)
...
@@ -1510,6 +1565,9 @@ describe API::Projects do
...
@@ -1510,6 +1565,9 @@ describe API::Projects do
describe
"POST /projects/:id/share"
do
describe
"POST /projects/:id/share"
do
let
(
:group
)
{
create
(
:group
)
}
let
(
:group
)
{
create
(
:group
)
}
before
do
group
.
add_developer
(
user
)
end
it
"shares project with group"
do
it
"shares project with group"
do
expires_at
=
10
.
days
.
from_now
.
to_date
expires_at
=
10
.
days
.
from_now
.
to_date
...
@@ -1560,6 +1618,15 @@ describe API::Projects do
...
@@ -1560,6 +1618,15 @@ describe API::Projects do
expect
(
response
).
to
have_gitlab_http_status
(
400
)
expect
(
response
).
to
have_gitlab_http_status
(
400
)
expect
(
json_response
[
'error'
]).
to
eq
'group_access does not have a valid value'
expect
(
json_response
[
'error'
]).
to
eq
'group_access does not have a valid value'
end
end
it
"returns a 409 error when link is not saved"
do
allow
(
::
Projects
::
GroupLinks
::
CreateService
).
to
receive_message_chain
(
:new
,
:execute
)
.
and_return
({
status: :error
,
http_status:
409
,
message:
'error'
})
post
api
(
"/projects/
#{
project
.
id
}
/share"
,
user
),
params:
{
group_id:
group
.
id
,
group_access:
Gitlab
::
Access
::
DEVELOPER
}
expect
(
response
).
to
have_gitlab_http_status
(
409
)
end
end
end
describe
'DELETE /projects/:id/share/:group_id'
do
describe
'DELETE /projects/:id/share/:group_id'
do
...
...
spec/requests/api/release/links_spec.rb
View file @
59db98a0
...
@@ -73,6 +73,22 @@ describe API::Release::Links do
...
@@ -73,6 +73,22 @@ describe API::Release::Links do
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
end
end
end
end
context
'when project is public and the repository is private'
do
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
,
:repository_private
)
}
it_behaves_like
'403 response'
do
let
(
:request
)
{
get
api
(
"/projects/
#{
project
.
id
}
/releases/v0.1/assets/links"
,
non_project_member
)
}
end
context
'when the release does not exists'
do
let!
(
:release
)
{
}
it_behaves_like
'403 response'
do
let
(
:request
)
{
get
api
(
"/projects/
#{
project
.
id
}
/releases/v0.1/assets/links"
,
non_project_member
)
}
end
end
end
end
end
end
end
...
...
spec/requests/git_http_spec.rb
View file @
59db98a0
...
@@ -104,6 +104,70 @@ describe 'Git HTTP requests' do
...
@@ -104,6 +104,70 @@ describe 'Git HTTP requests' do
end
end
end
end
shared_examples_for
'project path without .git suffix'
do
context
"GET info/refs"
do
let
(
:path
)
{
"/
#{
project_path
}
/info/refs"
}
context
"when no params are added"
do
before
do
get
path
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project_path
}
.git/info/refs"
)
end
end
context
"when the upload-pack service is requested"
do
let
(
:params
)
{
{
service:
'git-upload-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project_path
}
.git/info/refs?service=
#{
params
[
:service
]
}
"
)
end
end
context
"when the receive-pack service is requested"
do
let
(
:params
)
{
{
service:
'git-receive-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project_path
}
.git/info/refs?service=
#{
params
[
:service
]
}
"
)
end
end
context
"when the params are anything else"
do
let
(
:params
)
{
{
service:
'git-implode-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the sign-in page"
do
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
end
context
"POST git-upload-pack"
do
it
"fails to find a route"
do
expect
{
clone_post
(
project_path
)
}.
to
raise_error
(
ActionController
::
RoutingError
)
end
end
context
"POST git-receive-pack"
do
it
"fails to find a route"
do
expect
{
push_post
(
project_path
)
}.
to
raise_error
(
ActionController
::
RoutingError
)
end
end
end
describe
"User with no identities"
do
describe
"User with no identities"
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
...
@@ -143,6 +207,10 @@ describe 'Git HTTP requests' do
...
@@ -143,6 +207,10 @@ describe 'Git HTTP requests' do
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
end
end
end
end
it_behaves_like
'project path without .git suffix'
do
let
(
:project_path
)
{
"
#{
user
.
namespace
.
path
}
/project.git-project"
}
end
end
end
end
end
...
@@ -706,70 +774,8 @@ describe 'Git HTTP requests' do
...
@@ -706,70 +774,8 @@ describe 'Git HTTP requests' do
end
end
end
end
context
"when the project path doesn't end in .git"
do
it_behaves_like
'project path without .git suffix'
do
let
(
:project
)
{
create
(
:project
,
:repository
,
:public
,
path:
'project.git-project'
)
}
let
(
:project_path
)
{
create
(
:project
,
:repository
,
:public
,
path:
'project.git-project'
).
full_path
}
context
"GET info/refs"
do
let
(
:path
)
{
"/
#{
project
.
full_path
}
/info/refs"
}
context
"when no params are added"
do
before
do
get
path
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project
.
full_path
}
.git/info/refs"
)
end
end
context
"when the upload-pack service is requested"
do
let
(
:params
)
{
{
service:
'git-upload-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project
.
full_path
}
.git/info/refs?service=
#{
params
[
:service
]
}
"
)
end
end
context
"when the receive-pack service is requested"
do
let
(
:params
)
{
{
service:
'git-receive-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the .git suffix version"
do
expect
(
response
).
to
redirect_to
(
"/
#{
project
.
full_path
}
.git/info/refs?service=
#{
params
[
:service
]
}
"
)
end
end
context
"when the params are anything else"
do
let
(
:params
)
{
{
service:
'git-implode-pack'
}
}
before
do
get
path
,
params:
params
end
it
"redirects to the sign-in page"
do
expect
(
response
).
to
redirect_to
(
new_user_session_path
)
end
end
end
context
"POST git-upload-pack"
do
it
"fails to find a route"
do
expect
{
clone_post
(
project
.
full_path
)
}.
to
raise_error
(
ActionController
::
RoutingError
)
end
end
context
"POST git-receive-pack"
do
it
"fails to find a route"
do
expect
{
push_post
(
project
.
full_path
)
}.
to
raise_error
(
ActionController
::
RoutingError
)
end
end
end
end
context
"retrieving an info/refs file"
do
context
"retrieving an info/refs file"
do
...
...
spec/services/issuable/common_system_notes_service_spec.rb
View file @
59db98a0
...
@@ -3,7 +3,7 @@ require 'spec_helper'
...
@@ -3,7 +3,7 @@ require 'spec_helper'
describe
Issuable
::
CommonSystemNotesService
do
describe
Issuable
::
CommonSystemNotesService
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:issuable
)
{
create
(
:issue
)
}
let
(
:issuable
)
{
create
(
:issue
,
project:
project
)
}
context
'on issuable update'
do
context
'on issuable update'
do
it_behaves_like
'system note creation'
,
{
title:
'New title'
},
'changed title'
it_behaves_like
'system note creation'
,
{
title:
'New title'
},
'changed title'
...
@@ -70,7 +70,7 @@ describe Issuable::CommonSystemNotesService do
...
@@ -70,7 +70,7 @@ describe Issuable::CommonSystemNotesService do
end
end
context
'on issuable create'
do
context
'on issuable create'
do
let
(
:issuable
)
{
build
(
:issue
)
}
let
(
:issuable
)
{
build
(
:issue
,
project:
project
)
}
subject
{
described_class
.
new
(
project
,
user
).
execute
(
issuable
,
old_labels:
[],
is_update:
false
)
}
subject
{
described_class
.
new
(
project
,
user
).
execute
(
issuable
,
old_labels:
[],
is_update:
false
)
}
...
...
spec/services/issues/build_service_spec.rb
View file @
59db98a0
...
@@ -8,29 +8,29 @@ describe Issues::BuildService do
...
@@ -8,29 +8,29 @@ describe Issues::BuildService do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
end
end
def
build_issue
(
issue_params
=
{})
described_class
.
new
(
project
,
user
,
issue_params
).
execute
end
context
'for a single discussion'
do
context
'for a single discussion'
do
describe
'#execute'
do
describe
'#execute'
do
let
(
:merge_request
)
{
create
(
:merge_request
,
title:
"Hello world"
,
source_project:
project
)
}
let
(
:merge_request
)
{
create
(
:merge_request
,
title:
"Hello world"
,
source_project:
project
)
}
let
(
:discussion
)
{
create
(
:diff_note_on_merge_request
,
project:
project
,
noteable:
merge_request
,
note:
"Almost done"
).
to_discussion
}
let
(
:discussion
)
{
create
(
:diff_note_on_merge_request
,
project:
project
,
noteable:
merge_request
,
note:
"Almost done"
).
to_discussion
}
let
(
:service
)
{
described_class
.
new
(
project
,
user
,
merge_request_to_resolve_discussions_of:
merge_request
.
iid
,
discussion_to_resolve:
discussion
.
id
)
}
it
'references the noteable title in the issue title'
do
subject
{
build_issue
(
merge_request_to_resolve_discussions_of:
merge_request
.
iid
,
discussion_to_resolve:
discussion
.
id
)
}
issue
=
service
.
execute
expect
(
issue
.
title
).
to
include
(
'Hello world'
)
it
'references the noteable title in the issue title'
do
expect
(
subject
.
title
).
to
include
(
'Hello world'
)
end
end
it
'adds the note content to the description'
do
it
'adds the note content to the description'
do
issue
=
service
.
execute
expect
(
subject
.
description
).
to
include
(
'Almost done'
)
expect
(
issue
.
description
).
to
include
(
'Almost done'
)
end
end
end
end
end
end
context
'for discussions in a merge request'
do
context
'for discussions in a merge request'
do
let
(
:merge_request
)
{
create
(
:merge_request_with_diff_notes
,
source_project:
project
)
}
let
(
:merge_request
)
{
create
(
:merge_request_with_diff_notes
,
source_project:
project
)
}
let
(
:issue
)
{
described_class
.
new
(
project
,
user
,
merge_request_to_resolve_discussions_of:
merge_request
.
iid
).
execute
}
describe
'#items_for_discussions'
do
describe
'#items_for_discussions'
do
it
'has an item for each discussion'
do
it
'has an item for each discussion'
do
...
@@ -66,28 +66,30 @@ describe Issues::BuildService do
...
@@ -66,28 +66,30 @@ describe Issues::BuildService do
end
end
describe
'#execute'
do
describe
'#execute'
do
it
'has the merge request reference in the title'
do
let
(
:base_params
)
{
{
merge_request_to_resolve_discussions_of:
merge_request
.
iid
}
}
expect
(
issue
.
title
).
to
include
(
merge_request
.
title
)
end
it
'has the reference of the merge request in the description'
do
context
'without additional params'
do
expect
(
issue
.
description
).
to
include
(
merge_request
.
to_reference
)
subject
{
build_issue
(
base_params
)
}
it
'has the merge request reference in the title'
do
expect
(
subject
.
title
).
to
include
(
merge_request
.
title
)
end
it
'has the reference of the merge request in the description'
do
expect
(
subject
.
description
).
to
include
(
merge_request
.
to_reference
)
end
end
end
it
'does not assign title when a title was given'
do
it
'uses provided title if title param given'
do
issue
=
described_class
.
new
(
project
,
user
,
issue
=
build_issue
(
base_params
.
merge
(
title:
'What an issue'
))
merge_request_to_resolve_discussions_of:
merge_request
,
title:
'What an issue'
).
execute
expect
(
issue
.
title
).
to
eq
(
'What an issue'
)
expect
(
issue
.
title
).
to
eq
(
'What an issue'
)
end
end
it
'does not assign description when a description was given'
do
it
'uses provided description if description param given'
do
issue
=
described_class
.
new
(
project
,
user
,
issue
=
build_issue
(
base_params
.
merge
(
description:
'Fix at your earliest convenience'
))
merge_request_to_resolve_discussions_of:
merge_request
,
description:
'Fix at your earliest conveignance'
).
execute
expect
(
issue
.
description
).
to
eq
(
'Fix at your earliest conve
igna
nce'
)
expect
(
issue
.
description
).
to
eq
(
'Fix at your earliest conve
nie
nce'
)
end
end
describe
'with multiple discussions'
do
describe
'with multiple discussions'
do
...
@@ -96,20 +98,20 @@ describe Issues::BuildService do
...
@@ -96,20 +98,20 @@ describe Issues::BuildService do
it
'mentions all the authors in the description'
do
it
'mentions all the authors in the description'
do
authors
=
merge_request
.
resolvable_discussions
.
map
(
&
:author
)
authors
=
merge_request
.
resolvable_discussions
.
map
(
&
:author
)
expect
(
issue
.
description
).
to
include
(
*
authors
.
map
(
&
:to_reference
))
expect
(
build_issue
(
base_params
)
.
description
).
to
include
(
*
authors
.
map
(
&
:to_reference
))
end
end
it
'has a link for each unresolved discussion in the description'
do
it
'has a link for each unresolved discussion in the description'
do
notes
=
merge_request
.
resolvable_discussions
.
map
(
&
:first_note
)
notes
=
merge_request
.
resolvable_discussions
.
map
(
&
:first_note
)
links
=
notes
.
map
{
|
note
|
Gitlab
::
UrlBuilder
.
build
(
note
)
}
links
=
notes
.
map
{
|
note
|
Gitlab
::
UrlBuilder
.
build
(
note
)
}
expect
(
issue
.
description
).
to
include
(
*
links
)
expect
(
build_issue
(
base_params
)
.
description
).
to
include
(
*
links
)
end
end
it
'mentions additional notes'
do
it
'mentions additional notes'
do
create_list
(
:diff_note_on_merge_request
,
2
,
noteable:
merge_request
,
project:
merge_request
.
target_project
,
in_reply_to:
diff_note
)
create_list
(
:diff_note_on_merge_request
,
2
,
noteable:
merge_request
,
project:
merge_request
.
target_project
,
in_reply_to:
diff_note
)
expect
(
issue
.
description
).
to
include
(
'(+2 comments)'
)
expect
(
build_issue
(
base_params
)
.
description
).
to
include
(
'(+2 comments)'
)
end
end
end
end
end
end
...
@@ -120,7 +122,7 @@ describe Issues::BuildService do
...
@@ -120,7 +122,7 @@ describe Issues::BuildService do
describe
'#execute'
do
describe
'#execute'
do
it
'mentions the merge request in the description'
do
it
'mentions the merge request in the description'
do
issue
=
described_class
.
new
(
project
,
user
,
merge_request_to_resolve_discussions_of:
merge_request
.
iid
).
execute
issue
=
build_issue
(
merge_request_to_resolve_discussions_of:
merge_request
.
iid
)
expect
(
issue
.
description
).
to
include
(
"Review the conversation in
#{
merge_request
.
to_reference
}
"
)
expect
(
issue
.
description
).
to
include
(
"Review the conversation in
#{
merge_request
.
to_reference
}
"
)
end
end
...
@@ -128,20 +130,18 @@ describe Issues::BuildService do
...
@@ -128,20 +130,18 @@ describe Issues::BuildService do
end
end
describe
'#execute'
do
describe
'#execute'
do
let
(
:milestone
)
{
create
(
:milestone
,
project:
project
)
}
it
'builds a new issues with given params'
do
it
'builds a new issues with given params'
do
issue
=
described_class
.
new
(
milestone
=
create
(
:milestone
,
project:
project
)
project
,
issue
=
build_issue
(
milestone_id:
milestone
.
id
)
user
,
title:
'Issue #1'
,
description:
'Issue description'
,
milestone_id:
milestone
.
id
).
execute
expect
(
issue
.
title
).
to
eq
(
'Issue #1'
)
expect
(
issue
.
description
).
to
eq
(
'Issue description'
)
expect
(
issue
.
milestone
).
to
eq
(
milestone
)
expect
(
issue
.
milestone
).
to
eq
(
milestone
)
end
end
it
'sets milestone to nil if it is not available for the project'
do
milestone
=
create
(
:milestone
,
project:
create
(
:project
))
issue
=
build_issue
(
milestone_id:
milestone
.
id
)
expect
(
issue
.
milestone
).
to
be_nil
end
end
end
end
end
spec/services/issues/update_service_spec.rb
View file @
59db98a0
...
@@ -356,7 +356,7 @@ describe Issues::UpdateService, :mailer do
...
@@ -356,7 +356,7 @@ describe Issues::UpdateService, :mailer do
it_behaves_like
'system notes for milestones'
it_behaves_like
'system notes for milestones'
it
'sends notifications for subscribers of changed milestone'
do
it
'sends notifications for subscribers of changed milestone'
do
issue
.
milestone
=
create
(
:milestone
)
issue
.
milestone
=
create
(
:milestone
,
project:
project
)
issue
.
save
issue
.
save
...
@@ -380,7 +380,7 @@ describe Issues::UpdateService, :mailer do
...
@@ -380,7 +380,7 @@ describe Issues::UpdateService, :mailer do
end
end
it
'marks todos as done'
do
it
'marks todos as done'
do
update_issue
(
milestone:
create
(
:milestone
))
update_issue
(
milestone:
create
(
:milestone
,
project:
project
))
expect
(
todo
.
reload
.
done?
).
to
eq
true
expect
(
todo
.
reload
.
done?
).
to
eq
true
end
end
...
@@ -389,7 +389,7 @@ describe Issues::UpdateService, :mailer do
...
@@ -389,7 +389,7 @@ describe Issues::UpdateService, :mailer do
it
'sends notifications for subscribers of changed milestone'
do
it
'sends notifications for subscribers of changed milestone'
do
perform_enqueued_jobs
do
perform_enqueued_jobs
do
update_issue
(
milestone:
create
(
:milestone
))
update_issue
(
milestone:
create
(
:milestone
,
project:
project
))
end
end
should_email
(
subscriber
)
should_email
(
subscriber
)
...
...
spec/services/merge_requests/build_service_spec.rb
View file @
59db98a0
...
@@ -229,6 +229,15 @@ describe MergeRequests::BuildService do
...
@@ -229,6 +229,15 @@ describe MergeRequests::BuildService do
end
end
end
end
end
end
context
'when a milestone is from another project'
do
let
(
:milestone
)
{
create
(
:milestone
,
project:
create
(
:project
))
}
let
(
:milestone_id
)
{
milestone
.
id
}
it
'sets milestone to nil'
do
expect
(
merge_request
.
milestone
).
to
be_nil
end
end
end
end
end
end
...
...
spec/services/merge_requests/update_service_spec.rb
View file @
59db98a0
...
@@ -328,7 +328,7 @@ describe MergeRequests::UpdateService, :mailer do
...
@@ -328,7 +328,7 @@ describe MergeRequests::UpdateService, :mailer do
it_behaves_like
'system notes for milestones'
it_behaves_like
'system notes for milestones'
it
'sends notifications for subscribers of changed milestone'
do
it
'sends notifications for subscribers of changed milestone'
do
merge_request
.
milestone
=
create
(
:milestone
)
merge_request
.
milestone
=
create
(
:milestone
,
project:
project
)
merge_request
.
save
merge_request
.
save
...
@@ -352,7 +352,7 @@ describe MergeRequests::UpdateService, :mailer do
...
@@ -352,7 +352,7 @@ describe MergeRequests::UpdateService, :mailer do
end
end
it
'marks pending todos as done'
do
it
'marks pending todos as done'
do
update_merge_request
({
milestone:
create
(
:milestone
)
})
update_merge_request
({
milestone:
create
(
:milestone
,
project:
project
)
})
expect
(
pending_todo
.
reload
).
to
be_done
expect
(
pending_todo
.
reload
).
to
be_done
end
end
...
@@ -361,7 +361,7 @@ describe MergeRequests::UpdateService, :mailer do
...
@@ -361,7 +361,7 @@ describe MergeRequests::UpdateService, :mailer do
it
'sends notifications for subscribers of changed milestone'
do
it
'sends notifications for subscribers of changed milestone'
do
perform_enqueued_jobs
do
perform_enqueued_jobs
do
update_merge_request
(
milestone:
create
(
:milestone
))
update_merge_request
(
milestone:
create
(
:milestone
,
project:
project
))
end
end
should_email
(
subscriber
)
should_email
(
subscriber
)
...
...
spec/services/projects/group_links/create_service_spec.rb
View file @
59db98a0
...
@@ -12,6 +12,10 @@ describe Projects::GroupLinks::CreateService, '#execute' do
...
@@ -12,6 +12,10 @@ describe Projects::GroupLinks::CreateService, '#execute' do
end
end
let
(
:subject
)
{
described_class
.
new
(
project
,
user
,
opts
)
}
let
(
:subject
)
{
described_class
.
new
(
project
,
user
,
opts
)
}
before
do
group
.
add_developer
(
user
)
end
it
'adds group to project'
do
it
'adds group to project'
do
expect
{
subject
.
execute
(
group
)
}.
to
change
{
project
.
project_group_links
.
count
}.
from
(
0
).
to
(
1
)
expect
{
subject
.
execute
(
group
)
}.
to
change
{
project
.
project_group_links
.
count
}.
from
(
0
).
to
(
1
)
end
end
...
@@ -19,4 +23,8 @@ describe Projects::GroupLinks::CreateService, '#execute' do
...
@@ -19,4 +23,8 @@ describe Projects::GroupLinks::CreateService, '#execute' do
it
'returns false if group is blank'
do
it
'returns false if group is blank'
do
expect
{
subject
.
execute
(
nil
)
}.
not_to
change
{
project
.
project_group_links
.
count
}
expect
{
subject
.
execute
(
nil
)
}.
not_to
change
{
project
.
project_group_links
.
count
}
end
end
it
'returns error if user is not allowed to share with a group'
do
expect
{
subject
.
execute
(
create
:group
)
}.
not_to
change
{
project
.
project_group_links
.
count
}
end
end
end
spec/support/helpers/file_mover_helpers.rb
0 → 100644
View file @
59db98a0
# frozen_string_literal: true
module
FileMoverHelpers
def
stub_file_mover
(
file_path
,
stub_real_path:
nil
)
file_name
=
File
.
basename
(
file_path
)
allow
(
Pathname
).
to
receive
(
:new
).
and_call_original
expect_next_instance_of
(
Pathname
,
a_string_including
(
file_name
))
do
|
pathname
|
allow
(
pathname
).
to
receive
(
:realpath
)
{
stub_real_path
||
pathname
.
cleanpath
}
end
end
end
spec/support/helpers/login_helpers.rb
View file @
59db98a0
...
@@ -47,7 +47,7 @@ module LoginHelpers
...
@@ -47,7 +47,7 @@ module LoginHelpers
end
end
def
gitlab_sign_in_via
(
provider
,
user
,
uid
,
saml_response
=
nil
)
def
gitlab_sign_in_via
(
provider
,
user
,
uid
,
saml_response
=
nil
)
mock_auth_hash
(
provider
,
uid
,
user
.
email
,
saml_response
)
mock_auth_hash
_with_saml_xml
(
provider
,
uid
,
user
.
email
,
saml_response
)
visit
new_user_session_path
visit
new_user_session_path
click_link
provider
click_link
provider
end
end
...
@@ -87,7 +87,12 @@ module LoginHelpers
...
@@ -87,7 +87,12 @@ module LoginHelpers
click_link
"oauth-login-
#{
provider
}
"
click_link
"oauth-login-
#{
provider
}
"
end
end
def
mock_auth_hash
(
provider
,
uid
,
email
,
saml_response
=
nil
)
def
mock_auth_hash_with_saml_xml
(
provider
,
uid
,
email
,
saml_response
)
response_object
=
{
document:
saml_xml
(
saml_response
)
}
mock_auth_hash
(
provider
,
uid
,
email
,
response_object:
response_object
)
end
def
mock_auth_hash
(
provider
,
uid
,
email
,
response_object:
nil
)
# The mock_auth configuration allows you to set per-provider (or default)
# The mock_auth configuration allows you to set per-provider (or default)
# authentication hashes to return during integration testing.
# authentication hashes to return during integration testing.
OmniAuth
.
config
.
mock_auth
[
provider
.
to_sym
]
=
OmniAuth
::
AuthHash
.
new
({
OmniAuth
.
config
.
mock_auth
[
provider
.
to_sym
]
=
OmniAuth
::
AuthHash
.
new
({
...
@@ -110,9 +115,7 @@ module LoginHelpers
...
@@ -110,9 +115,7 @@ module LoginHelpers
image:
'mock_user_thumbnail_url'
image:
'mock_user_thumbnail_url'
}
}
},
},
response_object:
{
response_object:
response_object
document:
saml_xml
(
saml_response
)
}
}
}
})
})
Rails
.
application
.
env_config
[
'omniauth.auth'
]
=
OmniAuth
.
config
.
mock_auth
[
provider
.
to_sym
]
Rails
.
application
.
env_config
[
'omniauth.auth'
]
=
OmniAuth
.
config
.
mock_auth
[
provider
.
to_sym
]
...
...
spec/support/shared_examples/issuable_shared_examples.rb
View file @
59db98a0
...
@@ -31,7 +31,7 @@ shared_examples 'system notes for milestones' do
...
@@ -31,7 +31,7 @@ shared_examples 'system notes for milestones' do
context
'project milestones'
do
context
'project milestones'
do
it
'creates a system note'
do
it
'creates a system note'
do
expect
do
expect
do
update_issuable
(
milestone:
create
(
:milestone
))
update_issuable
(
milestone:
create
(
:milestone
,
project:
project
))
end
.
to
change
{
Note
.
system
.
count
}.
by
(
1
)
end
.
to
change
{
Note
.
system
.
count
}.
by
(
1
)
end
end
end
end
...
...
spec/support/shared_examples/requests/api/discussions.rb
View file @
59db98a0
...
@@ -86,6 +86,37 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
...
@@ -86,6 +86,37 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
expect
(
response
).
to
have_gitlab_http_status
(
404
)
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
end
end
context
'when a project is public with private repo access'
do
let!
(
:parent
)
{
create
(
:project
,
:public
,
:repository
,
:repository_private
,
:snippets_private
)
}
let!
(
:user_without_access
)
{
create
(
:user
)
}
context
'when user is not a team member of private repo'
do
before
do
project
.
team
.
truncate
end
context
"creating a new note"
do
before
do
post
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/discussions"
,
user_without_access
),
params:
{
body:
'hi!'
}
end
it
'raises 404 error'
do
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
context
"fetching a discussion"
do
before
do
get
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/discussions/
#{
note
.
discussion_id
}
"
,
user_without_access
)
end
it
'raises 404 error'
do
expect
(
response
).
to
have_gitlab_http_status
(
404
)
end
end
end
end
end
end
describe
"POST /
#{
parent_type
}
/:id/
#{
noteable_type
}
/:noteable_id/discussions/:discussion_id/notes"
do
describe
"POST /
#{
parent_type
}
/:id/
#{
noteable_type
}
/:noteable_id/discussions/:discussion_id/notes"
do
...
...
spec/uploaders/file_mover_spec.rb
View file @
59db98a0
require
'spec_helper'
require
'spec_helper'
describe
FileMover
do
describe
FileMover
do
include
FileMoverHelpers
let
(
:filename
)
{
'banana_sample.gif'
}
let
(
:filename
)
{
'banana_sample.gif'
}
let
(
:file
)
{
fixture_file_upload
(
File
.
join
(
'spec'
,
'fixtures'
,
filename
))
}
let
(
:temp_file_path
)
{
File
.
join
(
'uploads/-/system/temp'
,
'secret55'
,
filename
)
}
let
(
:temp_file_path
)
{
File
.
join
(
'uploads/-/system/temp'
,
'secret55'
,
filename
)
}
let
(
:temp_description
)
do
let
(
:temp_description
)
do
...
@@ -12,7 +13,7 @@ describe FileMover do
...
@@ -12,7 +13,7 @@ describe FileMover do
let
(
:file_path
)
{
File
.
join
(
'uploads/-/system/personal_snippet'
,
snippet
.
id
.
to_s
,
'secret55'
,
filename
)
}
let
(
:file_path
)
{
File
.
join
(
'uploads/-/system/personal_snippet'
,
snippet
.
id
.
to_s
,
'secret55'
,
filename
)
}
let
(
:snippet
)
{
create
(
:personal_snippet
,
description:
temp_description
)
}
let
(
:snippet
)
{
create
(
:personal_snippet
,
description:
temp_description
)
}
subject
{
described_class
.
new
(
file_path
,
snippet
).
execute
}
subject
{
described_class
.
new
(
temp_
file_path
,
snippet
).
execute
}
describe
'#execute'
do
describe
'#execute'
do
before
do
before
do
...
@@ -20,6 +21,8 @@ describe FileMover do
...
@@ -20,6 +21,8 @@ describe FileMover do
expect
(
FileUtils
).
to
receive
(
:move
).
with
(
a_string_including
(
temp_file_path
),
a_string_including
(
file_path
))
expect
(
FileUtils
).
to
receive
(
:move
).
with
(
a_string_including
(
temp_file_path
),
a_string_including
(
file_path
))
allow_any_instance_of
(
CarrierWave
::
SanitizedFile
).
to
receive
(
:exists?
).
and_return
(
true
)
allow_any_instance_of
(
CarrierWave
::
SanitizedFile
).
to
receive
(
:exists?
).
and_return
(
true
)
allow_any_instance_of
(
CarrierWave
::
SanitizedFile
).
to
receive
(
:size
).
and_return
(
10
)
allow_any_instance_of
(
CarrierWave
::
SanitizedFile
).
to
receive
(
:size
).
and_return
(
10
)
stub_file_mover
(
temp_file_path
)
end
end
context
'when move and field update successful'
do
context
'when move and field update successful'
do
...
@@ -66,4 +69,30 @@ describe FileMover do
...
@@ -66,4 +69,30 @@ describe FileMover do
end
end
end
end
end
end
context
'security'
do
context
'when relative path is involved'
do
let
(
:temp_file_path
)
{
File
.
join
(
'uploads/-/system/temp'
,
'..'
,
'another_subdir_of_temp'
)
}
it
'does not trigger move if path is outside designated directory'
do
stub_file_mover
(
'uploads/-/system/another_subdir_of_temp'
)
expect
(
FileUtils
).
not_to
receive
(
:move
)
subject
expect
(
snippet
.
reload
.
description
).
to
eq
(
temp_description
)
end
end
context
'when symlink is involved'
do
it
'does not trigger move if path is outside designated directory'
do
stub_file_mover
(
temp_file_path
,
stub_real_path:
Pathname
(
'/etc'
))
expect
(
FileUtils
).
not_to
receive
(
:move
)
subject
expect
(
snippet
.
reload
.
description
).
to
eq
(
temp_description
)
end
end
end
end
end
spec/validators/sha_validator_spec.rb
0 → 100644
View file @
59db98a0
require
'spec_helper'
describe
ShaValidator
do
let
(
:validator
)
{
described_class
.
new
(
attributes:
[
:base_commit_sha
])
}
let
(
:merge_diff
)
{
build
(
:merge_request_diff
)
}
subject
{
validator
.
validate_each
(
merge_diff
,
:base_commit_sha
,
value
)
}
context
'with empty value'
do
let
(
:value
)
{
nil
}
it
'does not add any error if value is empty'
do
subject
expect
(
merge_diff
.
errors
).
to
be_empty
end
end
context
'with valid sha'
do
let
(
:value
)
{
Digest
::
SHA1
.
hexdigest
(
SecureRandom
.
hex
)
}
it
'does not add any error if value is empty'
do
subject
expect
(
merge_diff
.
errors
).
to
be_empty
end
end
context
'with invalid sha'
do
let
(
:value
)
{
'foo'
}
it
'adds error to the record'
do
expect
(
merge_diff
.
errors
).
to
be_empty
subject
expect
(
merge_diff
.
errors
).
not_to
be_empty
end
end
end
spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb
View file @
59db98a0
...
@@ -18,7 +18,7 @@ describe UpdateHeadPipelineForMergeRequestWorker do
...
@@ -18,7 +18,7 @@ describe UpdateHeadPipelineForMergeRequestWorker do
context
'when merge request sha does not equal pipeline sha'
do
context
'when merge request sha does not equal pipeline sha'
do
before
do
before
do
merge_request
.
merge_request_diff
.
update
(
head_commit_sha:
'different_sha'
)
merge_request
.
merge_request_diff
.
update
(
head_commit_sha:
Digest
::
SHA1
.
hexdigest
(
SecureRandom
.
hex
)
)
end
end
it
'does not update head pipeline'
do
it
'does not update head pipeline'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment