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
2872c752
Commit
2872c752
authored
Sep 20, 2016
by
Bryce Johnson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into merge-request-push-compare-ui
parents
812806e6
667d2350
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
443 additions
and
78 deletions
+443
-78
CHANGELOG
CHANGELOG
+7
-7
GITLAB_WORKHORSE_VERSION
GITLAB_WORKHORSE_VERSION
+1
-1
app/assets/javascripts/build.js
app/assets/javascripts/build.js
+11
-2
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+9
-7
app/assets/javascripts/labels_select.js
app/assets/javascripts/labels_select.js
+1
-1
app/assets/stylesheets/pages/diff.scss
app/assets/stylesheets/pages/diff.scss
+5
-4
app/controllers/projects/git_http_client_controller.rb
app/controllers/projects/git_http_client_controller.rb
+5
-3
app/helpers/lfs_helper.rb
app/helpers/lfs_helper.rb
+1
-1
app/models/event.rb
app/models/event.rb
+14
-4
app/views/projects/buttons/_download.html.haml
app/views/projects/buttons/_download.html.haml
+1
-1
app/views/shared/issuable/_label_dropdown.html.haml
app/views/shared/issuable/_label_dropdown.html.haml
+1
-1
doc/install/installation.md
doc/install/installation.md
+1
-1
doc/update/8.11-to-8.12.md
doc/update/8.11-to-8.12.md
+1
-1
doc/workflow/lfs/lfs_administration.md
doc/workflow/lfs/lfs_administration.md
+2
-2
doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
+8
-0
lib/api/access_requests.rb
lib/api/access_requests.rb
+1
-1
lib/api/entities.rb
lib/api/entities.rb
+3
-3
lib/api/internal.rb
lib/api/internal.rb
+13
-0
lib/api/members.rb
lib/api/members.rb
+4
-4
lib/gitlab/auth.rb
lib/gitlab/auth.rb
+25
-0
lib/gitlab/auth/result.rb
lib/gitlab/auth/result.rb
+10
-2
lib/gitlab/backend/shell.rb
lib/gitlab/backend/shell.rb
+11
-2
lib/gitlab/ldap/adapter.rb
lib/gitlab/ldap/adapter.rb
+5
-1
lib/gitlab/lfs_token.rb
lib/gitlab/lfs_token.rb
+54
-0
lib/gitlab/regex.rb
lib/gitlab/regex.rb
+3
-3
scripts/lint-doc.sh
scripts/lint-doc.sh
+9
-0
spec/factories/events.rb
spec/factories/events.rb
+3
-2
spec/features/issues/filter_issues_spec.rb
spec/features/issues/filter_issues_spec.rb
+29
-2
spec/features/projects/branches/download_buttons_spec.rb
spec/features/projects/branches/download_buttons_spec.rb
+5
-1
spec/features/projects/files/download_buttons_spec.rb
spec/features/projects/files/download_buttons_spec.rb
+5
-1
spec/features/projects/main/download_buttons_spec.rb
spec/features/projects/main/download_buttons_spec.rb
+5
-1
spec/features/projects/tags/download_buttons_spec.rb
spec/features/projects/tags/download_buttons_spec.rb
+5
-1
spec/lib/gitlab/auth_spec.rb
spec/lib/gitlab/auth_spec.rb
+18
-0
spec/lib/gitlab/backend/shell_spec.rb
spec/lib/gitlab/backend/shell_spec.rb
+28
-4
spec/lib/gitlab/lfs_token_spec.rb
spec/lib/gitlab/lfs_token_spec.rb
+51
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+8
-5
spec/requests/api/internal_spec.rb
spec/requests/api/internal_spec.rb
+46
-0
spec/requests/api/members_spec.rb
spec/requests/api/members_spec.rb
+18
-9
spec/requests/lfs_http_spec.rb
spec/requests/lfs_http_spec.rb
+16
-0
No files found.
CHANGELOG
View file @
2872c752
...
...
@@ -15,6 +15,7 @@ v 8.12.0 (unreleased)
- Update gitlab shell secret file also when it is empty. !3774 (glensc)
- Give project selection dropdowns responsive width, make non-wrapping.
- Make push events have equal vertical spacing.
- API: Ensure invitees are not returned in Members API.
- Add two-factor recovery endpoint to internal API !5510
- Pass the "Remember me" value to the U2F authentication form
- Only update projects.last_activity_at once per hour when creating a new event
...
...
@@ -24,9 +25,11 @@ v 8.12.0 (unreleased)
- Change logo animation to CSS (ClemMakesApps)
- Instructions for enabling Git packfile bitmaps !6104
- Use Search::GlobalService.new in the `GET /projects/search/:query` endpoint
- Fix long comments in diffs messing with table width
- Fix pagination on user snippets page
- Run CI builds with the permissions of users !5735
- Fix sorting of issues in API
- Fix download artifacts button links !6407
- Sort project variables by key. !6275 (Diego Souza)
- Ensure specs on sorting of issues in API are deterministic on MySQL
- Added ability to use predefined CI variables for environment name
...
...
@@ -56,6 +59,7 @@ v 8.12.0 (unreleased)
- Add hover color to emoji icon (ClemMakesApps)
- Increase ci_builds artifacts_size column to 8-byte integer to allow larger files
- Add textarea autoresize after comment (ClemMakesApps)
- Do not write SSH public key 'comments' to authorized_keys !6381
- Refresh todos count cache when an Issue/MR is deleted
- Fix branches page dropdown sort alignment (ClemMakesApps)
- Hides merge request button on branches page is user doesn't have permissions
...
...
@@ -109,6 +113,7 @@ v 8.12.0 (unreleased)
- Remove green outline from `New branch unavailable` button on issue page !5858 (winniehell)
- Fix repo title alignment (ClemMakesApps)
- Change update interval of contacted_at
- Add LFS support to SSH !6043
- Fix branch title trailing space on hover (ClemMakesApps)
- Don't include 'Created By' tag line when importing from GitHub if there is a linked GitLab account (EspadaV8)
- Award emoji tooltips containing more than 10 usernames are now truncated !4780 (jlogandavison)
...
...
@@ -604,6 +609,7 @@ v 8.10.0
- Export and import avatar as part of project import/export
- Fix migration corrupting import data for old version upgrades
- Show tooltip on GitLab export link in new project page
- Fix import_data wrongly saved as a result of an invalid import_url !5206
v 8.9.9
- Exclude some pending or inactivated rows in Member scopes
...
...
@@ -624,12 +630,6 @@ v 8.9.6
- Keeps issue number when importing from Gitlab.com
- Add Pending tab for Builds (Katarzyna Kobierska, Urszula Budziszewska)
v 8.9.7 (unreleased)
- Fix import_data wrongly saved as a result of an invalid import_url
v 8.9.6
- Fix importing of events under notes for GitLab projects
v 8.9.5
- Add more debug info to import/export and memory killer. !5108
- Fixed avatar alignment in new MR view. !5095
...
...
@@ -1895,7 +1895,7 @@ v 8.1.3
- Use issue editor as cross reference comment author when issue is edited with a new mention
- Add Facebook authentication
v 8.1.
1
v 8.1.
2
- Fix cloning Wiki repositories via HTTP (Stan Hu)
- Add migration to remove satellites directory
- Fix specific runners visibility
...
...
GITLAB_WORKHORSE_VERSION
View file @
2872c752
0.8.
1
0.8.
2
app/assets/javascripts/build.js
View file @
2872c752
...
...
@@ -27,10 +27,11 @@
$
(
document
).
off
(
'
click
'
,
'
.js-sidebar-build-toggle
'
).
on
(
'
click
'
,
'
.js-sidebar-build-toggle
'
,
this
.
toggleSidebar
);
$
(
window
).
off
(
'
resize.build
'
).
on
(
'
resize.build
'
,
this
.
hideSidebar
);
$
(
document
).
off
(
'
click
'
,
'
.stage-item
'
).
on
(
'
click
'
,
'
.stage-item
'
,
this
.
updateDropdown
);
$
(
'
#js-build-scroll > a
'
).
off
(
'
click
'
).
on
(
'
click
'
,
this
.
stepTrace
);
this
.
updateArtifactRemoveDate
();
if
(
$
(
'
#build-trace
'
).
length
)
{
this
.
getInitialBuildTrace
();
this
.
initScrollButton
Affix
();
this
.
initScrollButton
s
();
}
if
(
this
.
build_status
===
"
running
"
||
this
.
build_status
===
"
pending
"
)
{
$
(
'
#autoscroll-button
'
).
on
(
'
click
'
,
function
()
{
...
...
@@ -106,7 +107,7 @@
}
};
Build
.
prototype
.
initScrollButton
Affix
=
function
()
{
Build
.
prototype
.
initScrollButton
s
=
function
()
{
var
$body
,
$buildScroll
,
$buildTrace
;
$buildScroll
=
$
(
'
#js-build-scroll
'
);
$body
=
$
(
'
body
'
);
...
...
@@ -165,6 +166,14 @@
this
.
populateJobs
(
stage
);
};
Build
.
prototype
.
stepTrace
=
function
(
e
)
{
e
.
preventDefault
();
$currentTarget
=
$
(
e
.
currentTarget
);
$
.
scrollTo
(
$currentTarget
.
attr
(
'
href
'
),
{
offset
:
-
(
$
(
'
.navbar-gitlab
'
).
outerHeight
()
+
$
(
'
.layout-nav
'
).
outerHeight
())
});
};
return
Build
;
})();
...
...
app/assets/javascripts/gl_dropdown.js
View file @
2872c752
...
...
@@ -607,13 +607,15 @@
selectedObject
=
this
.
renderedData
[
selectedIndex
];
}
}
field
=
[];
fieldName
=
typeof
this
.
options
.
fieldName
===
'
function
'
?
this
.
options
.
fieldName
(
selectedObject
)
:
this
.
options
.
fieldName
;
value
=
this
.
options
.
id
?
this
.
options
.
id
(
selectedObject
,
el
)
:
selectedObject
.
id
;
if
(
isInput
)
{
field
=
$
(
this
.
el
);
}
else
{
field
=
this
.
dropdown
.
parent
().
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
escape
(
value
)
+
"
']
"
);
}
else
if
(
value
)
{
field
=
this
.
dropdown
.
parent
().
find
(
"
input[name='
"
+
fieldName
+
"
'][value='
"
+
value
.
toString
().
replace
(
/'/g
,
'
\\\'
'
)
+
"
']
"
);
}
if
(
el
.
hasClass
(
ACTIVE_CLASS
))
{
if
(
field
.
length
&&
el
.
hasClass
(
ACTIVE_CLASS
))
{
el
.
removeClass
(
ACTIVE_CLASS
);
if
(
isInput
)
{
field
.
val
(
''
);
...
...
@@ -623,7 +625,7 @@
}
else
if
(
el
.
hasClass
(
INDETERMINATE_CLASS
))
{
el
.
addClass
(
ACTIVE_CLASS
);
el
.
removeClass
(
INDETERMINATE_CLASS
);
if
(
value
==
null
)
{
if
(
field
.
length
&&
value
==
null
)
{
field
.
remove
();
}
if
(
!
field
.
length
&&
fieldName
)
{
...
...
@@ -636,7 +638,7 @@
this
.
dropdown
.
parent
().
find
(
"
input[name='
"
+
fieldName
+
"
']
"
).
remove
();
}
}
if
(
value
==
null
)
{
if
(
field
.
length
&&
value
==
null
)
{
field
.
remove
();
}
// Toggle active class for the tick mark
...
...
@@ -644,7 +646,7 @@
if
(
value
!=
null
)
{
if
(
!
field
.
length
&&
fieldName
)
{
this
.
addInput
(
fieldName
,
value
,
selectedObject
);
}
else
{
}
else
if
(
field
.
length
)
{
field
.
val
(
value
).
trigger
(
'
change
'
);
}
}
...
...
@@ -794,4 +796,4 @@
});
};
}).
call
(
this
);
}).
call
(
this
);
\ No newline at end of file
app/assets/javascripts/labels_select.js
View file @
2872c752
...
...
@@ -166,7 +166,7 @@
instance
.
addInput
(
this
.
fieldName
,
label
.
id
);
}
}
if
(
$form
.
find
(
"
input[type='hidden'][name='
"
+
(
$dropdown
.
data
(
'
fieldName
'
))
+
"
'][value='
"
+
escape
(
this
.
id
(
label
)
)
+
"
']
"
).
length
)
{
if
(
this
.
id
(
label
)
&&
$form
.
find
(
"
input[type='hidden'][name='
"
+
(
$dropdown
.
data
(
'
fieldName
'
))
+
"
'][value='
"
+
this
.
id
(
label
).
toString
().
replace
(
/'/g
,
'
\\\'
'
)
+
"
']
"
).
length
)
{
selectedClass
.
push
(
'
is-active
'
);
}
if
(
$dropdown
.
hasClass
(
'
js-multiselect
'
)
&&
removesAll
)
{
...
...
app/assets/stylesheets/pages/diff.scss
View file @
2872c752
...
...
@@ -68,6 +68,11 @@
border-collapse
:
separate
;
margin
:
0
;
padding
:
0
;
table-layout
:
fixed
;
.diff-line-num
{
width
:
50px
;
}
.line_holder
td
{
line-height
:
$code_line_height
;
...
...
@@ -98,10 +103,6 @@
}
tr
.line_holder.parallel
{
.old_line
,
.new_line
{
min-width
:
50px
;
}
td
.line_content.parallel
{
width
:
46%
;
}
...
...
app/controllers/projects/git_http_client_controller.rb
View file @
2872c752
...
...
@@ -127,9 +127,11 @@ class Projects::GitHttpClientController < Projects::ApplicationController
end
def
ci?
authentication_result
.
ci?
&&
authentication_project
&&
authentication_project
==
project
authentication_result
.
ci?
(
project
)
end
def
lfs_deploy_token?
authentication_result
.
lfs_deploy_token?
(
project
)
end
def
authentication_has_download_access?
...
...
app/helpers/lfs_helper.rb
View file @
2872c752
...
...
@@ -25,7 +25,7 @@ module LfsHelper
def
lfs_download_access?
return
false
unless
project
.
lfs_enabled?
project
.
public?
||
ci?
||
user_can_download_code?
||
build_can_download_code?
project
.
public?
||
ci?
||
lfs_deploy_token?
||
user_can_download_code?
||
build_can_download_code?
end
def
user_can_download_code?
...
...
app/models/event.rb
View file @
2872c752
...
...
@@ -330,13 +330,23 @@ class Event < ActiveRecord::Base
# Don't even bother obtaining a lock if the last update happened less than
# 60 minutes ago.
return
if
project
.
last_activity_at
>
RESET_PROJECT_ACTIVITY_INTERVAL
.
ago
return
if
recent_update?
return
unless
Gitlab
::
ExclusiveLease
.
return
unless
try_obtain_lease
project
.
update_column
(
:last_activity_at
,
created_at
)
end
private
def
recent_update?
project
.
last_activity_at
>
RESET_PROJECT_ACTIVITY_INTERVAL
.
ago
end
def
try_obtain_lease
Gitlab
::
ExclusiveLease
.
new
(
"project:update_last_activity_at:
#{
project
.
id
}
"
,
timeout:
RESET_PROJECT_ACTIVITY_INTERVAL
.
to_i
).
try_obtain
project
.
update_column
(
:last_activity_at
,
created_at
)
end
end
app/views/projects/buttons/_download.html.haml
View file @
2872c752
...
...
@@ -37,6 +37,6 @@
%li
.dropdown-header
Previous Artifacts
-
artifacts
.
each
do
|
job
|
%li
=
link_to
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
ref
,
'download'
,
job:
job
.
name
),
rel:
'nofollow'
do
=
link_to
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
"
#{
ref
}
/download"
,
job:
job
.
name
),
rel:
'nofollow'
do
%i
.fa.fa-download
%span
Download '
#{
job
.
name
}
'
app/views/shared/issuable/_label_dropdown.html.haml
View file @
2872c752
...
...
@@ -12,7 +12,7 @@
-
if
params
[
:label_name
].
present?
-
if
params
[
:label_name
].
respond_to?
(
'any?'
)
-
params
[
:label_name
].
each
do
|
label
|
=
hidden_field_tag
"label_name[]"
,
u
(
label
)
,
id:
nil
=
hidden_field_tag
"label_name[]"
,
label
,
id:
nil
.dropdown
%button
.dropdown-menu-toggle.js-label-select.js-multiselect
{
class:
classes
.
join
(
' '
),
type:
"button"
,
data:
dropdown_data
}
%span
.dropdown-toggle-text
...
...
doc/install/installation.md
View file @
2872c752
...
...
@@ -400,7 +400,7 @@ If you are not using Linux you may have to run `gmake` instead of
cd /home/git
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git
cd gitlab-workhorse
sudo -u git -H git checkout v0.8.
1
sudo -u git -H git checkout v0.8.
2
sudo -u git -H make
### Initialize Database and Activate Advanced Features
...
...
doc/update/8.11-to-8.12.md
View file @
2872c752
...
...
@@ -82,7 +82,7 @@ GitLab 8.1.
```
bash
cd
/home/git/gitlab-workhorse
sudo
-u
git
-H
git fetch
--all
sudo
-u
git
-H
git checkout v0.8.
1
sudo
-u
git
-H
git checkout v0.8.
2
sudo
-u
git
-H
make
```
...
...
doc/workflow/lfs/lfs_administration.md
View file @
2872c752
...
...
@@ -45,5 +45,5 @@ In `config/gitlab.yml`:
*
Currently, storing GitLab Git LFS objects on a non-local storage (like S3 buckets)
is not supported
*
Currently, removing LFS objects from GitLab Git LFS storage is not supported
*
LFS authentications via SSH
is not supported for the time being
*
Only compatible with the GitLFS client versions 1.1.0 or 1.0.2.
*
LFS authentications via SSH
was added with GitLab 8.12
*
Only compatible with the GitLFS client versions 1.1.0
and up,
or 1.0.2.
doc/workflow/lfs/manage_large_binaries_with_git_lfs.md
View file @
2872c752
...
...
@@ -35,6 +35,10 @@ Documentation for GitLab instance administrators is under [LFS administration do
credentials store is recommended
*
Git LFS always assumes HTTPS so if you have GitLab server on HTTP you will have
to add the URL to Git config manually (see #troubleshooting)
>**Note**: With 8.12 GitLab added LFS support to SSH. The Git LFS communication
still goes over HTTP, but now the SSH client passes the correct credentials
to the Git LFS client, so no action is required by the user.
## Using Git LFS
...
...
@@ -132,6 +136,10 @@ git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
### Credentials are always required when pushing an object
>**Note**: With 8.12 GitLab added LFS support to SSH. The Git LFS communication
still goes over HTTP, but now the SSH client passes the correct credentials
to the Git LFS client, so no action is required by the user.
Given that Git LFS uses HTTP Basic Authentication to authenticate the user pushing
the LFS object on every push for every object, user HTTPS credentials are required.
...
...
lib/api/access_requests.rb
View file @
2872c752
...
...
@@ -20,7 +20,7 @@ module API
access_requesters
=
paginate
(
source
.
requesters
.
includes
(
:user
))
present
access_requesters
.
map
(
&
:user
),
with:
Entities
::
AccessRequester
,
access_requesters:
access_requesters
present
access_requesters
.
map
(
&
:user
),
with:
Entities
::
AccessRequester
,
source:
source
end
# Request access to the group/project
...
...
lib/api/entities.rb
View file @
2872c752
...
...
@@ -105,18 +105,18 @@ module API
class
Member
<
UserBasic
expose
:access_level
do
|
user
,
options
|
member
=
options
[
:member
]
||
options
[
:
members
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
member
=
options
[
:member
]
||
options
[
:
source
].
members
.
find_by
(
user_id:
user
.
id
)
member
.
access_level
end
expose
:expires_at
do
|
user
,
options
|
member
=
options
[
:member
]
||
options
[
:
members
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
member
=
options
[
:member
]
||
options
[
:
source
].
members
.
find_by
(
user_id:
user
.
id
)
member
.
expires_at
end
end
class
AccessRequester
<
UserBasic
expose
:requested_at
do
|
user
,
options
|
access_requester
=
options
[
:access_requester
]
||
options
[
:
access_requesters
].
find
{
|
m
|
m
.
user_id
==
user
.
id
}
access_requester
=
options
[
:access_requester
]
||
options
[
:
source
].
requesters
.
find_by
(
user_id:
user
.
id
)
access_requester
.
requested_at
end
end
...
...
lib/api/internal.rb
View file @
2872c752
...
...
@@ -82,6 +82,19 @@ module API
response
end
post
"/lfs_authenticate"
do
status
200
key
=
Key
.
find
(
params
[
:key_id
])
token_handler
=
Gitlab
::
LfsToken
.
new
(
key
)
{
username:
token_handler
.
actor_name
,
lfs_token:
token_handler
.
generate
,
repository_http_path:
project
.
http_url_to_repo
}
end
get
"/merge_request_urls"
do
::
MergeRequests
::
GetUrlsService
.
new
(
project
).
execute
(
params
[
:changes
])
end
...
...
lib/api/members.rb
View file @
2872c752
...
...
@@ -18,11 +18,11 @@ module API
get
":id/members"
do
source
=
find_source
(
source_type
,
params
[
:id
])
members
=
source
.
members
.
includes
(
:user
)
members
=
members
.
joins
(
:user
)
.
merge
(
User
.
search
(
params
[
:query
]))
if
params
[
:query
]
members
=
paginate
(
memb
ers
)
users
=
source
.
users
users
=
users
.
merge
(
User
.
search
(
params
[
:query
]))
if
params
[
:query
]
users
=
paginate
(
us
ers
)
present
members
.
map
(
&
:user
),
with:
Entities
::
Member
,
members:
members
present
users
,
with:
Entities
::
Member
,
source:
source
end
# Get a group/project member
...
...
lib/gitlab/auth.rb
View file @
2872c752
...
...
@@ -11,6 +11,7 @@ module Gitlab
build_access_token_check
(
login
,
password
)
||
user_with_password_for_git
(
login
,
password
)
||
oauth_access_token_check
(
login
,
password
)
||
lfs_token_check
(
login
,
password
)
||
personal_access_token_check
(
login
,
password
)
||
Gitlab
::
Auth
::
Result
.
new
...
...
@@ -102,6 +103,30 @@ module Gitlab
end
end
def
lfs_token_check
(
login
,
password
)
deploy_key_matches
=
login
.
match
(
/\Alfs\+deploy-key-(\d+)\z/
)
actor
=
if
deploy_key_matches
DeployKey
.
find
(
deploy_key_matches
[
1
])
else
User
.
by_login
(
login
)
end
return
unless
actor
token_handler
=
Gitlab
::
LfsToken
.
new
(
actor
)
authentication_abilities
=
if
token_handler
.
user?
full_authentication_abilities
else
read_authentication_abilities
end
Result
.
new
(
actor
,
nil
,
token_handler
.
type
,
authentication_abilities
)
if
Devise
.
secure_compare
(
token_handler
.
value
,
password
)
end
def
build_access_token_check
(
login
,
password
)
return
unless
login
==
'gitlab-ci-token'
return
unless
password
...
...
lib/gitlab/auth/result.rb
View file @
2872c752
module
Gitlab
module
Auth
Result
=
Struct
.
new
(
:actor
,
:project
,
:type
,
:authentication_abilities
)
do
def
ci?
type
==
:ci
def
ci?
(
for_project
)
type
==
:ci
&&
project
&&
project
==
for_project
end
def
lfs_deploy_token?
(
for_project
)
type
==
:lfs_deploy_token
&&
actor
&&
actor
.
projects
.
include?
(
for_project
)
end
def
success?
...
...
lib/gitlab/backend/shell.rb
View file @
2872c752
...
...
@@ -6,7 +6,12 @@ module Gitlab
KeyAdder
=
Struct
.
new
(
:io
)
do
def
add_key
(
id
,
key
)
key
.
gsub!
(
/[[:space:]]+/
,
' '
).
strip!
key
=
Gitlab
::
Shell
.
strip_key
(
key
)
# Newline and tab are part of the 'protocol' used to transmit id+key to the other end
if
key
.
include?
(
"
\t
"
)
||
key
.
include?
(
"
\n
"
)
raise
Error
.
new
(
"Invalid key:
#{
key
.
inspect
}
"
)
end
io
.
puts
(
"
#{
id
}
\t
#{
key
}
"
)
end
end
...
...
@@ -16,6 +21,10 @@ module Gitlab
@version_required
||=
File
.
read
(
Rails
.
root
.
join
(
'GITLAB_SHELL_VERSION'
)).
strip
end
def
strip_key
(
key
)
key
.
split
(
/ /
)[
0
,
2
].
join
(
' '
)
end
end
# Init new repository
...
...
@@ -107,7 +116,7 @@ module Gitlab
#
def
add_key
(
key_id
,
key_content
)
Gitlab
::
Utils
.
system_silent
([
gitlab_shell_keys_path
,
'add-key'
,
key_id
,
key_content
])
'add-key'
,
key_id
,
self
.
class
.
strip_key
(
key_content
)
])
end
# Batch-add keys to authorized_keys
...
...
lib/gitlab/ldap/adapter.rb
View file @
2872c752
...
...
@@ -70,7 +70,7 @@ module Gitlab
private
def
user_options
(
field
,
value
,
limit
)
options
=
{
attributes:
%W(
#{
config
.
uid
}
cn mail dn)
}
options
=
{
attributes:
user_attributes
}
options
[
:size
]
=
limit
if
limit
if
field
.
to_sym
==
:dn
...
...
@@ -98,6 +98,10 @@ module Gitlab
filter
end
end
def
user_attributes
%W(
#{
config
.
uid
}
cn mail dn)
end
end
end
end
lib/gitlab/lfs_token.rb
0 → 100644
View file @
2872c752
module
Gitlab
class
LfsToken
attr_accessor
:actor
TOKEN_LENGTH
=
50
EXPIRY_TIME
=
1800
def
initialize
(
actor
)
@actor
=
case
actor
when
DeployKey
,
User
actor
when
Key
actor
.
user
else
raise
'Bad Actor'
end
end
def
generate
token
=
Devise
.
friendly_token
(
TOKEN_LENGTH
)
Gitlab
::
Redis
.
with
do
|
redis
|
redis
.
set
(
redis_key
,
token
,
ex:
EXPIRY_TIME
)
end
token
end
def
value
Gitlab
::
Redis
.
with
do
|
redis
|
redis
.
get
(
redis_key
)
end
end
def
user?
actor
.
is_a?
(
User
)
end
def
type
actor
.
is_a?
(
User
)
?
:lfs_token
:
:lfs_deploy_token
end
def
actor_name
actor
.
is_a?
(
User
)
?
actor
.
username
:
"lfs+deploy-key-
#{
actor
.
id
}
"
end
private
def
redis_key
"gitlab:lfs_token:
#{
actor
.
class
.
name
.
underscore
}
_
#{
actor
.
id
}
"
if
actor
end
end
end
lib/gitlab/regex.rb
View file @
2872c752
...
...
@@ -44,7 +44,7 @@ module Gitlab
end
def
file_name_regex_message
"can contain only letters, digits, '_', '-', '@' and '.'.
"
"can contain only letters, digits, '_', '-', '@' and '.'."
end
def
file_path_regex
...
...
@@ -52,7 +52,7 @@ module Gitlab
end
def
file_path_regex_message
"can contain only letters, digits, '_', '-', '@' and '.'. Separate directories with a '/'.
"
"can contain only letters, digits, '_', '-', '@' and '.'. Separate directories with a '/'."
end
def
directory_traversal_regex
...
...
@@ -60,7 +60,7 @@ module Gitlab
end
def
directory_traversal_regex_message
"cannot include directory traversal.
"
"cannot include directory traversal."
end
def
archive_formats_regex
...
...
scripts/lint-doc.sh
View file @
2872c752
...
...
@@ -10,6 +10,15 @@ then
exit
1
fi
# Ensure that the CHANGELOG does not contain duplicate versions
DUPLICATE_CHANGELOG_VERSIONS
=
$(
grep
--extended-regexp
'^v [0-9.]+'
CHANGELOG |
sed
's| (unreleased)||'
|
sort
|
uniq
-d
)
if
[
"
${
DUPLICATE_CHANGELOG_VERSIONS
}
"
!=
""
]
then
echo
'✖ ERROR: Duplicate versions in CHANGELOG:'
>
&2
echo
"
${
DUPLICATE_CHANGELOG_VERSIONS
}
"
>
&2
exit
1
fi
echo
"✔ Linting passed"
exit
0
spec/factories/events.rb
View file @
2872c752
FactoryGirl
.
define
do
factory
:event
do
project
author
factory: :user
factory
:closed_issue_event
do
project
action
{
Event
::
CLOSED
}
target
factory: :closed_issue
author
factory: :user
end
end
end
spec/features/issues/filter_issues_spec.rb
View file @
2872c752
...
...
@@ -101,7 +101,7 @@ describe 'Filter issues', feature: true do
expect
(
find
(
'.js-label-select .dropdown-toggle-text'
)).
to
have_content
(
'No Label'
)
end
it
'filters by
no
label'
do
it
'filters by
a
label'
do
find
(
'.dropdown-menu-labels a'
,
text:
label
.
title
).
click
page
.
within
'.labels-filter'
do
expect
(
page
).
to
have_content
label
.
title
...
...
@@ -109,7 +109,7 @@ describe 'Filter issues', feature: true do
expect
(
find
(
'.js-label-select .dropdown-toggle-text'
)).
to
have_content
(
label
.
title
)
end
it
'filters by wont fix labels'
do
it
"filters by `won't fix` and another label"
do
find
(
'.dropdown-menu-labels a'
,
text:
label
.
title
).
click
page
.
within
'.labels-filter'
do
expect
(
page
).
to
have_content
wontfix
.
title
...
...
@@ -117,6 +117,33 @@ describe 'Filter issues', feature: true do
end
expect
(
find
(
'.js-label-select .dropdown-toggle-text'
)).
to
have_content
(
wontfix
.
title
)
end
it
"filters by `won't fix` label followed by another label after page load"
do
find
(
'.dropdown-menu-labels a'
,
text:
wontfix
.
title
).
click
# Close label dropdown to load
find
(
'body'
).
click
expect
(
find
(
'.filtered-labels'
)).
to
have_content
(
wontfix
.
title
)
find
(
'.js-label-select'
).
click
wait_for_ajax
find
(
'.dropdown-menu-labels a'
,
text:
label
.
title
).
click
# Close label dropdown to load
find
(
'body'
).
click
expect
(
find
(
'.filtered-labels'
)).
to
have_content
(
label
.
title
)
find
(
'.js-label-select'
).
click
wait_for_ajax
expect
(
find
(
'.dropdown-menu-labels li'
,
text:
wontfix
.
title
)).
to
have_css
(
'.is-active'
)
expect
(
find
(
'.dropdown-menu-labels li'
,
text:
label
.
title
)).
to
have_css
(
'.is-active'
)
end
it
"selects and unselects `won't fix`"
do
find
(
'.dropdown-menu-labels a'
,
text:
wontfix
.
title
).
click
find
(
'.dropdown-menu-labels a'
,
text:
wontfix
.
title
).
click
# Close label dropdown to load
find
(
'body'
).
click
expect
(
page
).
not_to
have_css
(
'.filtered-labels'
)
end
end
describe
'Filter issues for assignee and label from issues#index'
do
...
...
spec/features/projects/branches/download_buttons_spec.rb
View file @
2872c752
...
...
@@ -33,7 +33,11 @@ feature 'Download buttons in branches page', feature: true do
end
scenario
'shows download artifacts button'
do
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
href
=
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
'binary-encoding/download'
,
job:
'build'
)
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
,
href:
href
end
end
end
...
...
spec/features/projects/files/download_buttons_spec.rb
View file @
2872c752
...
...
@@ -34,7 +34,11 @@ feature 'Download buttons in files tree', feature: true do
end
scenario
'shows download artifacts button'
do
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
href
=
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
"
#{
project
.
default_branch
}
/download"
,
job:
'build'
)
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
,
href:
href
end
end
end
...
...
spec/features/projects/main/download_buttons_spec.rb
View file @
2872c752
...
...
@@ -33,7 +33,11 @@ feature 'Download buttons in project main page', feature: true do
end
scenario
'shows download artifacts button'
do
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
href
=
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
"
#{
project
.
default_branch
}
/download"
,
job:
'build'
)
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
,
href:
href
end
end
end
...
...
spec/features/projects/tags/download_buttons_spec.rb
View file @
2872c752
...
...
@@ -34,7 +34,11 @@ feature 'Download buttons in tags page', feature: true do
end
scenario
'shows download artifacts button'
do
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
href
=
latest_succeeded_namespace_project_artifacts_path
(
project
.
namespace
,
project
,
"
#{
tag
}
/download"
,
job:
'build'
)
expect
(
page
).
to
have_link
"Download '
#{
build
.
name
}
'"
,
href:
href
end
end
end
...
...
spec/lib/gitlab/auth_spec.rb
View file @
2872c752
...
...
@@ -61,6 +61,24 @@ describe Gitlab::Auth, lib: true do
expect
(
gl_auth
.
find_for_git_client
(
user
.
username
,
'password'
,
project:
nil
,
ip:
ip
)).
to
eq
(
Gitlab
::
Auth
::
Result
.
new
(
user
,
nil
,
:gitlab_or_ldap
,
full_authentication_abilities
))
end
it
'recognizes user lfs tokens'
do
user
=
create
(
:user
)
ip
=
'ip'
token
=
Gitlab
::
LfsToken
.
new
(
user
).
generate
expect
(
gl_auth
).
to
receive
(
:rate_limit!
).
with
(
ip
,
success:
true
,
login:
user
.
username
)
expect
(
gl_auth
.
find_for_git_client
(
user
.
username
,
token
,
project:
nil
,
ip:
ip
)).
to
eq
(
Gitlab
::
Auth
::
Result
.
new
(
user
,
nil
,
:lfs_token
,
full_authentication_abilities
))
end
it
'recognizes deploy key lfs tokens'
do
key
=
create
(
:deploy_key
)
ip
=
'ip'
token
=
Gitlab
::
LfsToken
.
new
(
key
).
generate
expect
(
gl_auth
).
to
receive
(
:rate_limit!
).
with
(
ip
,
success:
true
,
login:
"lfs+deploy-key-
#{
key
.
id
}
"
)
expect
(
gl_auth
.
find_for_git_client
(
"lfs+deploy-key-
#{
key
.
id
}
"
,
token
,
project:
nil
,
ip:
ip
)).
to
eq
(
Gitlab
::
Auth
::
Result
.
new
(
key
,
nil
,
:lfs_deploy_token
,
read_authentication_abilities
))
end
it
'recognizes OAuth tokens'
do
user
=
create
(
:user
)
application
=
Doorkeeper
::
Application
.
create!
(
name:
"MyApp"
,
redirect_uri:
"https://app.com"
,
owner:
user
)
...
...
spec/lib/gitlab/backend/shell_spec.rb
View file @
2872c752
require
'spec_helper'
require
'stringio'
describe
Gitlab
::
Shell
,
lib:
true
do
let
(
:project
)
{
double
(
'Project'
,
id:
7
,
path:
'diaspora'
)
}
...
...
@@ -44,15 +45,38 @@ describe Gitlab::Shell, lib: true do
end
end
describe
'#add_key'
do
it
'removes trailing garbage'
do
allow
(
gitlab_shell
).
to
receive
(
:gitlab_shell_keys_path
).
and_return
(
:gitlab_shell_keys_path
)
expect
(
Gitlab
::
Utils
).
to
receive
(
:system_silent
).
with
(
[
:gitlab_shell_keys_path
,
'add-key'
,
'key-123'
,
'ssh-rsa foobar'
]
)
gitlab_shell
.
add_key
(
'key-123'
,
'ssh-rsa foobar trailing garbage'
)
end
end
describe
Gitlab
::
Shell
::
KeyAdder
,
lib:
true
do
describe
'#add_key'
do
it
'
normalizes space characters in the key
'
do
io
=
spy
it
'
removes trailing garbage
'
do
io
=
spy
(
:io
)
adder
=
described_class
.
new
(
io
)
adder
.
add_key
(
'key-42'
,
"sha-rsa foo
\t
bar
\t
baz"
)
adder
.
add_key
(
'key-42'
,
"ssh-rsa foo bar
\t
baz"
)
expect
(
io
).
to
have_received
(
:puts
).
with
(
"key-42
\t
ssh-rsa foo"
)
end
it
'raises an exception if the key contains a tab'
do
expect
do
described_class
.
new
(
StringIO
.
new
).
add_key
(
'key-42'
,
"ssh-rsa
\t
foobar"
)
end
.
to
raise_error
(
Gitlab
::
Shell
::
Error
)
end
expect
(
io
).
to
have_received
(
:puts
).
with
(
"key-42
\t
sha-rsa foo bar baz"
)
it
'raises an exception if the key contains a newline'
do
expect
do
described_class
.
new
(
StringIO
.
new
).
add_key
(
'key-42'
,
"ssh-rsa foobar
\n
ssh-rsa pawned"
)
end
.
to
raise_error
(
Gitlab
::
Shell
::
Error
)
end
end
end
...
...
spec/lib/gitlab/lfs_token_spec.rb
0 → 100644
View file @
2872c752
require
'spec_helper'
describe
Gitlab
::
LfsToken
,
lib:
true
do
describe
'#generate and #value'
do
shared_examples
'an LFS token generator'
do
it
'returns a randomly generated token'
do
token
=
handler
.
generate
expect
(
token
).
not_to
be_nil
expect
(
token
).
to
be_a
String
expect
(
token
.
length
).
to
eq
50
end
it
'returns the correct token based on the key'
do
token
=
handler
.
generate
expect
(
handler
.
value
).
to
eq
(
token
)
end
end
context
'when the actor is a user'
do
let
(
:actor
)
{
create
(
:user
)
}
let
(
:handler
)
{
described_class
.
new
(
actor
)
}
it_behaves_like
'an LFS token generator'
it
'returns the correct username'
do
expect
(
handler
.
actor_name
).
to
eq
(
actor
.
username
)
end
it
'returns the correct token type'
do
expect
(
handler
.
type
).
to
eq
(
:lfs_token
)
end
end
context
'when the actor is a deploy key'
do
let
(
:actor
)
{
create
(
:deploy_key
)
}
let
(
:handler
)
{
described_class
.
new
(
actor
)
}
it_behaves_like
'an LFS token generator'
it
'returns the correct username'
do
expect
(
handler
.
actor_name
).
to
eq
(
"lfs+deploy-key-
#{
actor
.
id
}
"
)
end
it
'returns the correct token type'
do
expect
(
handler
.
type
).
to
eq
(
:lfs_deploy_token
)
end
end
end
end
spec/models/project_spec.rb
View file @
2872c752
...
...
@@ -308,20 +308,23 @@ describe Project, models: true do
end
describe
'last_activity methods'
do
let
(
:
project
)
{
create
(
:project
)
}
let
(
:
last_event
)
{
double
(
created_at:
Time
.
now
)
}
let
(
:
timestamp
)
{
Time
.
now
-
2
.
hours
}
let
(
:
project
)
{
create
(
:project
,
created_at:
timestamp
,
updated_at:
timestamp
)
}
describe
'last_activity'
do
it
'alias last_activity to last_event'
do
allow
(
project
).
to
receive
(
:last_event
).
and_return
(
last_event
)
last_event
=
create
(
:event
,
project:
project
)
expect
(
project
.
last_activity
).
to
eq
(
last_event
)
end
end
describe
'last_activity_date'
do
it
'returns the creation date of the project\'s last event if present'
do
create
(
:event
,
project:
project
)
expect
(
project
.
last_activity_at
.
to_i
).
to
eq
(
last_event
.
created_at
.
to_i
)
expect_any_instance_of
(
Event
).
to
receive
(
:try_obtain_lease
).
and_return
(
true
)
new_event
=
create
(
:event
,
project:
project
,
created_at:
Time
.
now
)
expect
(
project
.
last_activity_at
.
to_i
).
to
eq
(
new_event
.
created_at
.
to_i
)
end
it
'returns the project\'s last update date if it has no events'
do
...
...
spec/requests/api/internal_spec.rb
View file @
2872c752
...
...
@@ -100,6 +100,43 @@ describe API::API, api: true do
end
end
describe
"POST /internal/lfs_authenticate"
do
before
do
project
.
team
<<
[
user
,
:developer
]
end
context
'user key'
do
it
'returns the correct information about the key'
do
lfs_auth
(
key
.
id
,
project
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'username'
]).
to
eq
(
user
.
username
)
expect
(
json_response
[
'lfs_token'
]).
to
eq
(
Gitlab
::
LfsToken
.
new
(
key
).
value
)
expect
(
json_response
[
'repository_http_path'
]).
to
eq
(
project
.
http_url_to_repo
)
end
it
'returns a 404 when the wrong key is provided'
do
lfs_auth
(
nil
,
project
)
expect
(
response
).
to
have_http_status
(
404
)
end
end
context
'deploy key'
do
let
(
:key
)
{
create
(
:deploy_key
)
}
it
'returns the correct information about the key'
do
lfs_auth
(
key
.
id
,
project
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
[
'username'
]).
to
eq
(
"lfs+deploy-key-
#{
key
.
id
}
"
)
expect
(
json_response
[
'lfs_token'
]).
to
eq
(
Gitlab
::
LfsToken
.
new
(
key
).
value
)
expect
(
json_response
[
'repository_http_path'
]).
to
eq
(
project
.
http_url_to_repo
)
end
end
end
describe
"GET /internal/discover"
do
it
do
get
(
api
(
"/internal/discover"
),
key_id:
key
.
id
,
secret_token:
secret_token
)
...
...
@@ -389,4 +426,13 @@ describe API::API, api: true do
protocol:
'ssh'
)
end
def
lfs_auth
(
key_id
,
project
)
post
(
api
(
"/internal/lfs_authenticate"
),
key_id:
key_id
,
secret_token:
secret_token
,
project:
project
.
path_with_namespace
)
end
end
spec/requests/api/members_spec.rb
View file @
2872c752
...
...
@@ -30,20 +30,29 @@ describe API::Members, api: true do
let
(
:route
)
{
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
stranger
)
}
end
context
'when authenticated as a non-member'
do
%i[access_requester stranger]
.
each
do
|
type
|
context
"as a
#{
type
}
"
do
it
'returns 200'
do
user
=
public_send
(
type
)
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
user
)
%i[master developer access_requester stranger]
.
each
do
|
type
|
context
"when authenticated as a
#{
type
}
"
do
it
'returns 200'
do
user
=
public_send
(
type
)
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
user
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
.
size
).
to
eq
(
2
)
e
nd
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
.
size
).
to
eq
(
2
)
e
xpect
(
json_response
.
map
{
|
u
|
u
[
'id'
]
}).
to
match_array
[
master
.
id
,
developer
.
id
]
end
end
end
it
'does not return invitees'
do
create
(
:"
#{
source_type
}
_member"
,
invite_token:
'123'
,
invite_email:
'test@abc.com'
,
source:
source
,
user:
nil
)
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
developer
)
expect
(
response
).
to
have_http_status
(
200
)
expect
(
json_response
.
size
).
to
eq
(
2
)
expect
(
json_response
.
map
{
|
u
|
u
[
'id'
]
}).
to
match_array
[
master
.
id
,
developer
.
id
]
end
it
'finds members with query string'
do
get
api
(
"/
#{
source_type
.
pluralize
}
/
#{
source
.
id
}
/members"
,
developer
),
query:
master
.
username
...
...
spec/requests/lfs_http_spec.rb
View file @
2872c752
...
...
@@ -245,6 +245,18 @@ describe 'Git LFS API and storage' do
end
end
context
'when deploy key is authorized'
do
let
(
:key
)
{
create
(
:deploy_key
)
}
let
(
:authorization
)
{
authorize_deploy_key
}
let
(
:update_permissions
)
do
project
.
deploy_keys
<<
key
project
.
lfs_objects
<<
lfs_object
end
it_behaves_like
'responds with a file'
end
context
'when build is authorized as'
do
let
(
:authorization
)
{
authorize_ci_project
}
...
...
@@ -1097,6 +1109,10 @@ describe 'Git LFS API and storage' do
ActionController
::
HttpAuthentication
::
Basic
.
encode_credentials
(
user
.
username
,
user
.
password
)
end
def
authorize_deploy_key
ActionController
::
HttpAuthentication
::
Basic
.
encode_credentials
(
"lfs+deploy-key-
#{
key
.
id
}
"
,
Gitlab
::
LfsToken
.
new
(
key
).
generate
)
end
def
fork_project
(
project
,
user
,
object
=
nil
)
allow
(
RepositoryForkWorker
).
to
receive
(
:perform_async
).
and_return
(
true
)
Projects
::
ForkService
.
new
(
project
,
user
,
{}).
execute
...
...
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