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
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
1935b494
Commit
1935b494
authored
Oct 10, 2013
by
Dmitriy Zaporozhets
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'refactor/profile_account' of /home/git/repositories/gitlab/gitlabhq
parents
f89a7471
dd68e37d
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
187 additions
and
194 deletions
+187
-194
app/assets/stylesheets/common.scss
app/assets/stylesheets/common.scss
+0
-1
app/controllers/profiles/accounts_controller.rb
app/controllers/profiles/accounts_controller.rb
+7
-0
app/controllers/profiles/passwords_controller.rb
app/controllers/profiles/passwords_controller.rb
+41
-2
app/controllers/profiles_controller.rb
app/controllers/profiles_controller.rb
+1
-30
app/views/layouts/nav/_profile.html.haml
app/views/layouts/nav/_profile.html.haml
+5
-2
app/views/profiles/account.html.haml
app/views/profiles/account.html.haml
+0
-141
app/views/profiles/accounts/show.html.haml
app/views/profiles/accounts/show.html.haml
+73
-0
app/views/profiles/passwords/edit.html.haml
app/views/profiles/passwords/edit.html.haml
+32
-0
app/views/profiles/update_username.js.haml
app/views/profiles/update_username.js.haml
+2
-2
config/routes.rb
config/routes.rb
+6
-4
features/profile/profile.feature
features/profile/profile.feature
+5
-5
features/steps/profile/profile.rb
features/steps/profile/profile.rb
+5
-1
features/steps/shared/paths.rb
features/steps/shared/paths.rb
+5
-1
spec/features/profile_spec.rb
spec/features/profile_spec.rb
+3
-3
spec/features/security/profile_access_spec.rb
spec/features/security/profile_access_spec.rb
+1
-1
spec/routing/routing_spec.rb
spec/routing/routing_spec.rb
+1
-1
No files found.
app/assets/stylesheets/common.scss
View file @
1935b494
...
@@ -271,7 +271,6 @@ li.note {
...
@@ -271,7 +271,6 @@ li.note {
}
}
.oauth_select_holder
{
.oauth_select_holder
{
padding
:
20px
;
img
{
img
{
padding
:
5px
;
padding
:
5px
;
margin-right
:
10px
;
margin-right
:
10px
;
...
...
app/controllers/profiles/accounts_controller.rb
0 → 100644
View file @
1935b494
class
Profiles::AccountsController
<
ApplicationController
layout
"profile"
def
show
@user
=
current_user
end
end
app/controllers/profiles/passwords_controller.rb
View file @
1935b494
class
Profiles::PasswordsController
<
ApplicationController
class
Profiles::PasswordsController
<
ApplicationController
layout
'navless'
layout
:determine_layout
skip_before_filter
:check_password_expiration
skip_before_filter
:check_password_expiration
,
only:
[
:new
,
:create
]
before_filter
:set_user
before_filter
:set_user
before_filter
:set_title
before_filter
:set_title
before_filter
:authorize_change_password!
def
new
def
new
end
end
...
@@ -26,6 +27,32 @@ class Profiles::PasswordsController < ApplicationController
...
@@ -26,6 +27,32 @@ class Profiles::PasswordsController < ApplicationController
end
end
end
end
def
edit
end
def
update
password_attributes
=
params
[
:user
].
select
do
|
key
,
value
|
%w(password password_confirmation)
.
include?
(
key
.
to_s
)
end
unless
@user
.
valid_password?
(
params
[
:user
][
:current_password
])
redirect_to
edit_profile_password_path
,
alert:
'You must provide a valid current password'
return
end
if
@user
.
update_attributes
(
password_attributes
)
flash
[
:notice
]
=
"Password was successfully updated. Please login with it"
redirect_to
new_user_session_path
else
render
'edit'
end
end
def
reset
current_user
.
send_reset_password_instructions
redirect_to
edit_profile_password_path
,
notice:
'We sent you an email with reset password instructions'
end
private
private
def
set_user
def
set_user
...
@@ -35,4 +62,16 @@ class Profiles::PasswordsController < ApplicationController
...
@@ -35,4 +62,16 @@ class Profiles::PasswordsController < ApplicationController
def
set_title
def
set_title
@title
=
"New password"
@title
=
"New password"
end
end
def
determine_layout
if
[
:new
,
:create
].
include?
(
action_name
.
to_sym
)
'navless'
else
'profile'
end
end
def
authorize_change_password!
return
render_404
if
@user
.
ldap_user?
end
end
end
app/controllers/profiles_controller.rb
View file @
1935b494
...
@@ -2,7 +2,6 @@ class ProfilesController < ApplicationController
...
@@ -2,7 +2,6 @@ class ProfilesController < ApplicationController
include
ActionView
::
Helpers
::
SanitizeHelper
include
ActionView
::
Helpers
::
SanitizeHelper
before_filter
:user
before_filter
:user
before_filter
:authorize_change_password!
,
only: :update_password
before_filter
:authorize_change_username!
,
only: :update_username
before_filter
:authorize_change_username!
,
only: :update_username
layout
'profile'
layout
'profile'
...
@@ -13,9 +12,6 @@ class ProfilesController < ApplicationController
...
@@ -13,9 +12,6 @@ class ProfilesController < ApplicationController
def
design
def
design
end
end
def
account
end
def
update
def
update
if
@user
.
update_attributes
(
params
[
:user
])
if
@user
.
update_attributes
(
params
[
:user
])
flash
[
:notice
]
=
"Profile was successfully updated"
flash
[
:notice
]
=
"Profile was successfully updated"
...
@@ -29,33 +25,12 @@ class ProfilesController < ApplicationController
...
@@ -29,33 +25,12 @@ class ProfilesController < ApplicationController
end
end
end
end
def
token
end
def
update_password
password_attributes
=
params
[
:user
].
select
do
|
key
,
value
|
%w(password password_confirmation)
.
include?
(
key
.
to_s
)
end
unless
@user
.
valid_password?
(
params
[
:user
][
:current_password
])
redirect_to
account_profile_path
,
alert:
'You must provide a valid current password'
return
end
if
@user
.
update_attributes
(
password_attributes
)
flash
[
:notice
]
=
"Password was successfully updated. Please login with it"
redirect_to
new_user_session_path
else
render
'account'
end
end
def
reset_private_token
def
reset_private_token
if
current_user
.
reset_authentication_token!
if
current_user
.
reset_authentication_token!
flash
[
:notice
]
=
"Token was successfully updated"
flash
[
:notice
]
=
"Token was successfully updated"
end
end
redirect_to
account_profile
_path
redirect_to
profile_account
_path
end
end
def
history
def
history
...
@@ -76,10 +51,6 @@ class ProfilesController < ApplicationController
...
@@ -76,10 +51,6 @@ class ProfilesController < ApplicationController
@user
=
current_user
@user
=
current_user
end
end
def
authorize_change_password!
return
render_404
if
@user
.
ldap_user?
end
def
authorize_change_username!
def
authorize_change_username!
return
render_404
unless
@user
.
can_change_username?
return
render_404
unless
@user
.
can_change_username?
end
end
...
...
app/views/layouts/nav/_profile.html.haml
View file @
1935b494
...
@@ -2,8 +2,11 @@
...
@@ -2,8 +2,11 @@
=
nav_link
(
path:
'profiles#show'
,
html_options:
{
class:
'home'
})
do
=
nav_link
(
path:
'profiles#show'
,
html_options:
{
class:
'home'
})
do
=
link_to
profile_path
,
title:
"Profile"
do
=
link_to
profile_path
,
title:
"Profile"
do
%i
.icon-home
%i
.icon-home
=
nav_link
(
path:
'profiles#account'
)
do
=
nav_link
(
controller: :accounts
)
do
=
link_to
"Account"
,
account_profile_path
=
link_to
"Account"
,
profile_account_path
-
unless
current_user
.
ldap_user?
=
nav_link
(
controller: :passwords
)
do
=
link_to
"Password"
,
edit_profile_password_path
=
nav_link
(
controller: :notifications
)
do
=
nav_link
(
controller: :notifications
)
do
=
link_to
"Notifications"
,
profile_notifications_path
=
link_to
"Notifications"
,
profile_notifications_path
=
nav_link
(
controller: :keys
)
do
=
nav_link
(
controller: :keys
)
do
...
...
app/views/profiles/account.html.haml
deleted
100644 → 0
View file @
f89a7471
%h3
.page-title
Account settings
%p
.light
You can change your password, username and private token here.
-
if
current_user
.
ldap_user?
Some options are unavailable for LDAP accounts
%hr
.row
.span2
%ul
.nav.nav-pills.nav-stacked.nav-stacked-menu
%li
.active
=
link_to
'#tab-token'
,
'data-toggle'
=>
'tab'
do
Private Token
%li
=
link_to
'#tab-password'
,
'data-toggle'
=>
'tab'
do
Password
-
if
show_profile_social_tab?
%li
=
link_to
'#tab-social'
,
'data-toggle'
=>
'tab'
do
Social Accounts
-
if
show_profile_username_tab?
%li
=
link_to
'#tab-username'
,
'data-toggle'
=>
'tab'
do
Change Username
-
if
show_profile_remove_tab?
%li
=
link_to
'#tab-remove'
,
'data-toggle'
=>
'tab'
do
Remove Account
.span10
.tab-content
.tab-pane.active
#tab-token
%fieldset
.update-token
%legend
Private token
%span
.cred.pull-right
keep it secret!
%div
=
form_for
@user
,
url:
reset_private_token_profile_path
,
method: :put
do
|
f
|
.data
%p
.slead
Your private token is used to access application resources without authentication.
%br
It can be used for atom feeds or the API.
%p
.cgray
-
if
current_user
.
private_token
=
text_field_tag
"token"
,
current_user
.
private_token
,
class:
"input-xxlarge large_text input-xpadding"
=
f
.
submit
'Reset'
,
confirm:
"Are you sure?"
,
class:
"btn btn-primary btn-build-token"
-
else
%span
You don`t have one yet. Click generate to fix it.
=
f
.
submit
'Generate'
,
class:
"btn success btn-build-token"
.tab-pane
#tab-password
%fieldset
.update-password
%legend
Password
-
if
current_user
.
ldap_user?
%h3
.nothing_here_message
Not available for LDAP user
-
else
=
form_for
@user
,
url:
update_password_profile_path
,
method: :put
do
|
f
|
%div
%p
.slead
You must provide current password in order to change it.
%br
After a successful password update you will be redirected to login page where you should login with your new password
-
if
@user
.
errors
.
any?
.alert.alert-error
%ul
-
@user
.
errors
.
full_messages
.
each
do
|
msg
|
%li
=
msg
.control-group
=
f
.
label
:current_password
,
class:
'cgreen'
.controls
=
f
.
password_field
:current_password
,
required:
true
.control-group
=
f
.
label
:password
,
'New password'
.controls
=
f
.
password_field
:password
,
required:
true
.control-group
=
f
.
label
:password_confirmation
.controls
=
f
.
password_field
:password_confirmation
,
required:
true
.control-group
.controls
=
f
.
submit
'Save password'
,
class:
"btn btn-save"
-
if
show_profile_social_tab?
.tab-pane
#tab-social
%fieldset
%legend
Social Accounts
.oauth_select_holder
%p
.hint
Tip: Click on icon to activate signin with one of the following services
-
enabled_social_providers
.
each
do
|
provider
|
%span
{
class:
oauth_active_class
(
provider
)
}
=
link_to
authbutton
(
provider
,
32
),
omniauth_authorize_path
(
User
,
provider
)
-
if
show_profile_username_tab?
.tab-pane
#tab-username
%fieldset
.update-username
%legend
Username
%small
.cred.pull-right
Changing your username can have unintended side effects!
=
form_for
@user
,
url:
update_username_profile_path
,
method: :put
,
remote:
true
do
|
f
|
%div
.control-group
=
f
.
label
:username
.controls
=
f
.
text_field
:username
,
required:
true
%span
.loading-gif.hide
=
image_tag
"ajax_loader.gif"
%span
.update-success.cgreen.hide
%i
.icon-ok
Saved
%span
.update-failed.cred.hide
%i
.icon-remove
Failed
%ul
.cred
%li
This will change the web URL for personal projects.
%li
This will change the git path to repositories for personal projects.
.controls
=
f
.
submit
'Save username'
,
class:
"btn btn-save"
-
if
show_profile_remove_tab?
.tab-pane
#tab-remove
%fieldset
.remove-account
%legend
Remove account
%div
%p
Deleting an account has the following effects:
%ul
%li
All user content like authored issues, snippets, comments will be removed
-
rp
=
current_user
.
personal_projects
.
count
-
unless
rp
.
zero?
%li
#{
pluralize
rp
,
'personal project'
}
will be removed and cannot be restored
-
if
current_user
.
solo_owned_groups
.
present?
%li
Next groups will be abandoned. You should transfer or remove them:
%strong
#{
current_user
.
solo_owned_groups
.
map
(
&
:name
).
join
(
', '
)
}
=
link_to
'Delete account'
,
user_registration_path
,
confirm:
"REMOVE
#{
current_user
.
name
}
? Are you sure?"
,
method: :delete
,
class:
"btn btn-remove"
app/views/profiles/accounts/show.html.haml
0 → 100644
View file @
1935b494
%h3
.page-title
Account settings
%p
.light
You can change your username and private token here.
-
if
current_user
.
ldap_user?
Some options are unavailable for LDAP accounts
%hr
%div
%fieldset
.update-token
%legend
Private token
%div
=
form_for
@user
,
url:
reset_private_token_profile_path
,
method: :put
do
|
f
|
.data
%p
Your private token is used to access application resources without authentication.
%br
It can be used for atom feeds or the API.
%span
.cred
Keep it secret!
%p
.cgray
-
if
current_user
.
private_token
=
text_field_tag
"token"
,
current_user
.
private_token
,
class:
"input-xlarge input-xpadding pull-left"
=
f
.
submit
'Reset'
,
confirm:
"Are you sure?"
,
class:
"btn btn-primary btn-build-token prepend-left-10"
-
else
%span
You don`t have one yet. Click generate to fix it.
=
f
.
submit
'Generate'
,
class:
"btn success btn-build-token"
-
if
show_profile_social_tab?
%fieldset
%legend
Social Accounts
.oauth_select_holder
%p
Click on icon to activate signin with one of the following services
-
enabled_social_providers
.
each
do
|
provider
|
%span
{
class:
oauth_active_class
(
provider
)
}
=
link_to
authbutton
(
provider
,
32
),
omniauth_authorize_path
(
User
,
provider
)
-
if
show_profile_username_tab?
%fieldset
.update-username
%legend
Username
=
form_for
@user
,
url:
update_username_profile_path
,
method: :put
,
remote:
true
do
|
f
|
%p
Changing your username will change path to all personl projects!
%div
=
f
.
text_field
:username
,
required:
true
,
class:
'input-xlarge input-xpadding'
%span
.loading-gif.hide
=
image_tag
"ajax_loader.gif"
%p
.light
=
user_url
(
@user
)
%div
=
f
.
submit
'Save username'
,
class:
"btn btn-save"
-
if
show_profile_remove_tab?
%fieldset
.remove-account
%legend
Remove account
%div
%p
Deleting an account has the following effects:
%ul
%li
All user content like authored issues, snippets, comments will be removed
-
rp
=
current_user
.
personal_projects
.
count
-
unless
rp
.
zero?
%li
#{
pluralize
rp
,
'personal project'
}
will be removed and cannot be restored
-
if
current_user
.
solo_owned_groups
.
present?
%li
Next groups will be abandoned. You should transfer or remove them:
%strong
#{
current_user
.
solo_owned_groups
.
map
(
&
:name
).
join
(
', '
)
}
=
link_to
'Delete account'
,
user_registration_path
,
confirm:
"REMOVE
#{
current_user
.
name
}
? Are you sure?"
,
method: :delete
,
class:
"btn btn-remove"
app/views/profiles/passwords/edit.html.haml
0 → 100644
View file @
1935b494
%h3
.page-title
Password
%p
.light
Change your password or recover your current one.
%hr
.update-password
=
form_for
@user
,
url:
profile_password_path
,
method: :put
do
|
f
|
%div
%p
.slead
You must provide current password in order to change it.
%br
After a successful password update you will be redirected to login page where you should login with your new password
-
if
@user
.
errors
.
any?
.alert.alert-error
%ul
-
@user
.
errors
.
full_messages
.
each
do
|
msg
|
%li
=
msg
.control-group
=
f
.
label
:current_password
.controls
=
f
.
password_field
:current_password
,
required:
true
%div
=
link_to
"Forgot your password?"
,
reset_profile_password_path
,
method: :put
.control-group
=
f
.
label
:password
,
'New password'
.controls
=
f
.
password_field
:password
,
required:
true
.control-group
=
f
.
label
:password_confirmation
.controls
=
f
.
password_field
:password_confirmation
,
required:
true
.form-actions
=
f
.
submit
'Save password'
,
class:
"btn btn-save"
app/views/profiles/update_username.js.haml
View file @
1935b494
-
if
@user
.
valid?
-
if
@user
.
valid?
:plain
:plain
$('.update-username .update-success').show();
new Flash("Username sucessfully changed", "notice")
-
else
-
else
:plain
:plain
$('.update-username .update-failed').show();
new Flash("Username change failed -
#{
@user
.
errors
.
full_messages
.
first
}
", "alert")
config/routes.rb
View file @
1935b494
...
@@ -99,19 +99,21 @@ Gitlab::Application.routes.draw do
...
@@ -99,19 +99,21 @@ Gitlab::Application.routes.draw do
#
#
resource
:profile
,
only:
[
:show
,
:update
]
do
resource
:profile
,
only:
[
:show
,
:update
]
do
member
do
member
do
get
:account
get
:history
get
:history
get
:token
get
:design
get
:design
put
:update_password
put
:reset_private_token
put
:reset_private_token
put
:update_username
put
:update_username
end
end
scope
module: :profiles
do
scope
module: :profiles
do
resource
:account
,
only:
[
:show
,
:update
]
resource
:notifications
,
only:
[
:show
,
:update
]
resource
:notifications
,
only:
[
:show
,
:update
]
resource
:password
,
only:
[
:new
,
:create
]
resource
:password
,
only:
[
:new
,
:create
,
:edit
,
:update
]
do
member
do
put
:reset
end
end
resources
:keys
resources
:keys
resources
:groups
,
only:
[
:index
]
do
resources
:groups
,
only:
[
:index
]
do
member
do
member
do
...
...
features/profile/profile.feature
View file @
1935b494
...
@@ -12,13 +12,13 @@ Feature: Profile
...
@@ -12,13 +12,13 @@ Feature: Profile
And
I should see new contact info
And
I should see new contact info
Scenario
:
I
change my password without old one
Scenario
:
I
change my password without old one
Given
I visit profile
account
page
Given
I visit profile
password
page
When
I try change my password w/o old one
When
I try change my password w/o old one
Then
I should see a missing password error message
Then
I should see a missing password error message
And
I should be redirected to
account
page
And
I should be redirected to
password
page
Scenario
:
I
change my password
Scenario
:
I
change my password
Given
I visit profile
account
page
Given
I visit profile
password
page
Then
I change my password
Then
I change my password
And
I should be redirected to sign in page
And
I should be redirected to sign in page
...
@@ -30,13 +30,13 @@ Feature: Profile
...
@@ -30,13 +30,13 @@ Feature: Profile
Scenario
:
My password is expired
Scenario
:
My password is expired
Given
my password is expired
Given
my password is expired
And
I am not an ldap user
And
I am not an ldap user
And
I visit profile account
page
Given
I visit profile password
page
Then
I redirected to expired password page
Then
I redirected to expired password page
And
I submit new password
And
I submit new password
And
I redirected to sign in page
And
I redirected to sign in page
Scenario
:
I
unsuccessfully change my password
Scenario
:
I
unsuccessfully change my password
Given
I visit profile
account
page
Given
I visit profile
password
page
When
I unsuccessfully change my password
When
I unsuccessfully change my password
Then
I should see a password error message
Then
I should see a password error message
...
...
features/steps/profile/profile.rb
View file @
1935b494
...
@@ -133,8 +133,12 @@ class Profile < Spinach::FeatureSteps
...
@@ -133,8 +133,12 @@ class Profile < Spinach::FeatureSteps
current_path
.
should
==
new_user_session_path
current_path
.
should
==
new_user_session_path
end
end
step
'I should be redirected to password page'
do
current_path
.
should
==
edit_profile_password_path
end
step
'I should be redirected to account page'
do
step
'I should be redirected to account page'
do
current_path
.
should
==
account_profile
_path
current_path
.
should
==
profile_account
_path
end
end
step
'I click on my profile picture'
do
step
'I click on my profile picture'
do
...
...
features/steps/shared/paths.rb
View file @
1935b494
...
@@ -65,8 +65,12 @@ module SharedPaths
...
@@ -65,8 +65,12 @@ module SharedPaths
visit
profile_path
visit
profile_path
end
end
step
'I visit profile password page'
do
visit
edit_profile_password_path
end
step
'I visit profile account page'
do
step
'I visit profile account page'
do
visit
account_profile
_path
visit
profile_account
_path
end
end
step
'I visit profile SSH keys page'
do
step
'I visit profile SSH keys page'
do
...
...
spec/features/profile_spec.rb
View file @
1935b494
...
@@ -12,7 +12,7 @@ describe "Profile account page" do
...
@@ -12,7 +12,7 @@ describe "Profile account page" do
describe
"when signup is enabled"
do
describe
"when signup is enabled"
do
before
do
before
do
Gitlab
.
config
.
gitlab
.
stub
(
:signup_enabled
).
and_return
(
true
)
Gitlab
.
config
.
gitlab
.
stub
(
:signup_enabled
).
and_return
(
true
)
visit
account_profile
_path
visit
profile_account
_path
end
end
it
{
page
.
should
have_content
(
"Remove account"
)
}
it
{
page
.
should
have_content
(
"Remove account"
)
}
...
@@ -26,12 +26,12 @@ describe "Profile account page" do
...
@@ -26,12 +26,12 @@ describe "Profile account page" do
describe
"when signup is disabled"
do
describe
"when signup is disabled"
do
before
do
before
do
Gitlab
.
config
.
gitlab
.
stub
(
:signup_enabled
).
and_return
(
false
)
Gitlab
.
config
.
gitlab
.
stub
(
:signup_enabled
).
and_return
(
false
)
visit
account_profile
_path
visit
profile_account
_path
end
end
it
"should not have option to remove account"
do
it
"should not have option to remove account"
do
page
.
should_not
have_content
(
"Remove account"
)
page
.
should_not
have_content
(
"Remove account"
)
current_path
.
should
==
account_profile
_path
current_path
.
should
==
profile_account
_path
end
end
end
end
end
end
spec/features/security/profile_access_spec.rb
View file @
1935b494
...
@@ -29,7 +29,7 @@ describe "Users Security" do
...
@@ -29,7 +29,7 @@ describe "Users Security" do
end
end
describe
"GET /profile/account"
do
describe
"GET /profile/account"
do
subject
{
account_profile
_path
}
subject
{
profile_account
_path
}
it
{
should
be_allowed_for
@u1
}
it
{
should
be_allowed_for
@u1
}
it
{
should
be_allowed_for
:admin
}
it
{
should
be_allowed_for
:admin
}
...
...
spec/routing/routing_spec.rb
View file @
1935b494
...
@@ -128,7 +128,7 @@ end
...
@@ -128,7 +128,7 @@ end
# profile_update PUT /profile/update(.:format) profile#update
# profile_update PUT /profile/update(.:format) profile#update
describe
ProfilesController
,
"routing"
do
describe
ProfilesController
,
"routing"
do
it
"to #account"
do
it
"to #account"
do
get
(
"/profile/account"
).
should
route_to
(
'profiles
#account
'
)
get
(
"/profile/account"
).
should
route_to
(
'profiles
/accounts#show
'
)
end
end
it
"to #history"
do
it
"to #history"
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