Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
eduGAIN Access Check - Account manager
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
edugain
eduGAIN Access Check - Account manager
Commits
1b530f35
Commit
1b530f35
authored
7 years ago
by
Guillaume ROUSSE
Browse files
Options
Downloads
Patches
Plain Diff
shorter variable name
parent
a87808f1
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lib/IdPAccountManager/WebRequest.pm
+74
-74
74 additions, 74 deletions
lib/IdPAccountManager/WebRequest.pm
with
74 additions
and
74 deletions
lib/IdPAccountManager/WebRequest.pm
+
74
−
74
View file @
1b530f35
...
...
@@ -78,7 +78,7 @@ sub execute {
my
$status
;
# initialize output parameters
$self
->
{
param_
out
}
=
{
$self
->
{
out
}
=
{
url_cgi
=>
$ENV
{
SCRIPT_NAME
},
env
=>
\
%ENV
,
actions
=>
\
%actions
,
...
...
@@ -99,7 +99,7 @@ sub execute {
if
(
defined
$format
{
$parameter
}
&&
!
ref
(
$format
{
$parameter
}))
{
if
(
$parameters
{
$parameter
}
!~
/^$format{$parameter}$/
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
format_
$parameter
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
format_
$parameter
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Incorrect parameter format :
$parameter
"
...
...
@@ -114,7 +114,7 @@ sub execute {
}
# register needed parameters
$self
->
{
param_
in
}
=
{
$self
->
{
in
}
=
{
email_adress
=>
$parameters
{
action
},
style
=>
$parameters
{
style
},
sp_entityid
=>
$parameters
{
sp_entityid
},
...
...
@@ -130,7 +130,7 @@ sub execute {
$status
=
$self
->
$method
();
}
else
{
## inknown action
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
unknown_action
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
unknown_action
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Unknown action '
$action
'
"
...
...
@@ -149,8 +149,8 @@ sub respond {
## Automatic pass object entries to the output hash
foreach
my
$key
(
keys
%
{
$self
})
{
$self
->
{
param_
out
}{
$key
}
||=
$self
->
{
$key
}
unless
(
$key
eq
'
param_
out
');
$self
->
{
out
}{
$key
}
||=
$self
->
{
$key
}
unless
(
$key
eq
'
out
');
}
## An action may redirect to an external URL
...
...
@@ -183,13 +183,13 @@ sub respond {
my
$template
;
## nobanner is used to do AJAX to get only pieces of HTML to load in the web client
if
(
$self
->
{
param_
in
}
->
{
style
}
eq
'
nobanner
')
{
if
(
$self
->
{
in
}
->
{
style
}
eq
'
nobanner
')
{
$template
=
'
templates/web/index-nobanner.tt2.html
';
}
else
{
$template
=
'
templates/web/index.tt2.html
';
}
unless
(
$tt2
->
process
(
$template
,
$self
->
{
param_
out
},
\
*STDOUT
))
{
unless
(
$tt2
->
process
(
$template
,
$self
->
{
out
},
\
*STDOUT
))
{
printf
"
Content-type: text/plain
\n\n
Error: %s
",
$tt2
->
error
();
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
...
...
@@ -200,7 +200,7 @@ sub respond {
## Ignore some type of errors
my
@errors_admin
;
foreach
my
$id_error
(
@
{
$self
->
{
param_
out
}
->
{
errors
}
})
{
foreach
my
$id_error
(
@
{
$self
->
{
out
}
->
{
errors
}
})
{
unless
(
$id_error
=~
/^(error_x)$/
)
{
push
@errors_admin
,
$id_error
;
}
...
...
@@ -208,10 +208,10 @@ sub respond {
## Mail notification of admins about the error
if
(
@errors_admin
)
{
$self
->
{
param_
out
}
->
{
subject
}
=
'
Error notification - web interface
';
$self
->
{
out
}
->
{
subject
}
=
'
Error notification - web interface
';
IdPAccountManager::Tools::
mail_notice
(
template
=>
'
templates/mail/notification_generic_error.tt2.eml
',
data
=>
$self
->
{
param_
out
},
data
=>
$self
->
{
out
},
logger
=>
$self
->
{
logger
},
conf
=>
$self
->
{
configuration
},
admin_email
=>
$self
->
{
configuration
}
->
{
admin_email
},
...
...
@@ -236,7 +236,7 @@ sub req_account_wizard {
);
};
if
(
$EVAL_ERROR
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to load federation metadata:
$EVAL_ERROR
"
...
...
@@ -245,10 +245,10 @@ sub req_account_wizard {
}
eval
{
$self
->
{
param_
out
}
=
$federation_metadata
->
parse
();
$self
->
{
out
}
=
$federation_metadata
->
parse
();
};
if
(
$EVAL_ERROR
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to parse federation metadata:
$EVAL_ERROR
"
...
...
@@ -265,8 +265,8 @@ sub req_select_sp {
my
(
$self
)
=
@_
;
$self
->
{
logger
}
->
log
(
level
=>
LOG_INFO
,
message
=>
"");
unless
(
$self
->
{
param_
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
unless
(
$self
->
{
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Missing parameter sp_entityid
");
return
undef
;
...
...
@@ -280,7 +280,7 @@ sub req_select_sp {
);
};
if
(
$EVAL_ERROR
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to load federation metadata:
$EVAL_ERROR
"
...
...
@@ -290,11 +290,11 @@ sub req_select_sp {
eval
{
$federation_metadata
->
parse
(
filter_entity_id
=>
$self
->
{
param_
in
}
->
{
sp_entityid
}
filter_entity_id
=>
$self
->
{
in
}
->
{
sp_entityid
}
);
};
if
(
$EVAL_ERROR
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to parse federation metadata:
$EVAL_ERROR
"
...
...
@@ -305,7 +305,7 @@ sub req_select_sp {
## Create a serviceprovider object to store major parameters for this SP in DB
my
$service_provider
=
IdPAccountManager::Data::
ServiceProvider
->
new
(
db
=>
$self
->
{
db
},
entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
},
entityid
=>
$self
->
{
in
}
->
{
sp_entityid
},
dev_sp_contact
=>
$self
->
{
configuration
}
->
{
dev_sp_contact
}
);
...
...
@@ -346,13 +346,13 @@ sub req_select_sp {
$service_provider
=
IdPAccountManager::Data::
ServiceProvider
->
new
(
db
=>
$self
->
{
db
},
entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
},
entityid
=>
$self
->
{
in
}
->
{
sp_entityid
},
contacts
=>
join
('
,
',
@contacts
),
displayname
=>
$display_name
,
dev_sp_contact
=>
$self
->
{
configuration
}
->
{
dev_sp_contact
}
);
unless
(
defined
$service_provider
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to create serviceprovider object
"
...
...
@@ -362,7 +362,7 @@ sub req_select_sp {
}
unless
(
$service_provider
->
save
())
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to save serviceprovider object
"
...
...
@@ -370,9 +370,9 @@ sub req_select_sp {
return
undef
;
}
$self
->
{
param_
out
}
->
{
sp_metadata_as_hashref
}
=
$self
->
{
out
}
->
{
sp_metadata_as_hashref
}
=
$federation_metadata
->
{
federation_metadata_as_hashref
}
->
[
0
];
$self
->
{
param_
out
}
->
{
serviceprovider
}
=
$service_provider
;
$self
->
{
out
}
->
{
serviceprovider
}
=
$service_provider
;
return
1
;
}
...
...
@@ -383,15 +383,15 @@ sub req_generate_token {
my
(
$self
)
=
@_
;
$self
->
{
logger
}
->
log
(
level
=>
LOG_INFO
,
message
=>
"");
unless
(
$self
->
{
param_
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
unless
(
$self
->
{
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Missing parameter sp_entityid
");
return
undef
;
}
unless
(
$self
->
{
param_
in
}
->
{
email_address
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
email_address
";
unless
(
$self
->
{
in
}
->
{
email_address
})
{
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
email_address
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Missing parameter email_address
"
...
...
@@ -402,42 +402,42 @@ sub req_generate_token {
## Create a serviceprovider object to load parameters for this SP from DB
my
$service_provider
=
IdPAccountManager::Data::
ServiceProvider
->
new
(
db
=>
$self
->
{
db
},
entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
},
entityid
=>
$self
->
{
in
}
->
{
sp_entityid
},
dev_sp_contact
=>
$self
->
{
configuration
}
->
{
dev_sp_contact
}
);
# Try loading DB object first
unless
(
$service_provider
->
load
(
speculative
=>
1
))
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to load SP with entityid '%s'
",
$self
->
{
param_
in
}
->
{
sp_entityid
}
$self
->
{
in
}
->
{
sp_entityid
}
);
return
undef
;
}
## Check that email_address is a known contact for this SP
unless
(
$service_provider
->
is_contact
(
$self
->
{
param_
in
}
->
{
email_address
}))
unless
(
$service_provider
->
is_contact
(
$self
->
{
in
}
->
{
email_address
}))
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Requested a token for %s for an unautorized address '%s'
",
$self
->
{
param_
in
}
->
{
sp_entityid
},
$self
->
{
param_
in
}
->
{
email_address
}
$self
->
{
in
}
->
{
sp_entityid
},
$self
->
{
in
}
->
{
email_address
}
);
return
undef
;
}
my
$authentication_token
=
IdPAccountManager::Data::
AuthenticationToken
->
new
(
db
=>
$self
->
{
db
},
email_address
=>
$self
->
{
param_
in
}
->
{
email_address
},
sp_entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
}
email_address
=>
$self
->
{
in
}
->
{
email_address
},
sp_entityid
=>
$self
->
{
in
}
->
{
sp_entityid
}
);
unless
(
defined
$authentication_token
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to create authentication token
"
...
...
@@ -448,7 +448,7 @@ sub req_generate_token {
## First remove token if one exist for this email+SP
if
(
$authentication_token
->
load
(
speculative
=>
1
))
{
unless
(
$authentication_token
->
delete
())
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
sprintf
(
...
...
@@ -461,11 +461,11 @@ sub req_generate_token {
$authentication_token
=
IdPAccountManager::Data::
AuthenticationToken
->
new
(
db
=>
$self
->
{
db
},
email_address
=>
$self
->
{
param_
in
}
->
{
email_address
},
sp_entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
}
email_address
=>
$self
->
{
in
}
->
{
email_address
},
sp_entityid
=>
$self
->
{
in
}
->
{
sp_entityid
}
);
unless
(
defined
$authentication_token
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to create authentication token
"
...
...
@@ -475,7 +475,7 @@ sub req_generate_token {
}
unless
(
$authentication_token
->
save
())
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
internal
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
internal
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to save authentication token
"
...
...
@@ -483,26 +483,26 @@ sub req_generate_token {
return
undef
;
}
$self
->
{
param_
out
}
->
{
email_address
}
=
$self
->
{
param_
in
}
->
{
email_address
};
$self
->
{
param_
out
}
->
{
sp_entityid
}
=
$self
->
{
param_
in
}
->
{
sp_entityid
};
$self
->
{
param_
out
}
->
{
to
}
=
$self
->
{
param_
in
}
->
{
email_address
};
$self
->
{
param_
out
}
->
{
authentication_token
}
=
$self
->
{
out
}
->
{
email_address
}
=
$self
->
{
in
}
->
{
email_address
};
$self
->
{
out
}
->
{
sp_entityid
}
=
$self
->
{
in
}
->
{
sp_entityid
};
$self
->
{
out
}
->
{
to
}
=
$self
->
{
in
}
->
{
email_address
};
$self
->
{
out
}
->
{
authentication_token
}
=
$authentication_token
->
get
('
token
');
## Send the challenge email with the token
IdPAccountManager::Tools::
mail_notice
(
template
=>
'
templates/mail/send_authentication_token.tt2.eml
',
to
=>
$self
->
{
param_
in
}
->
{
email_address
},
data
=>
$self
->
{
param_
out
},
to
=>
$self
->
{
in
}
->
{
email_address
},
data
=>
$self
->
{
out
},
logger
=>
$self
->
{
logger
}
);
$self
->
{
logger
}
->
log
(
level
=>
LOG_INFO
,
message
=>
"
Token send to %s for sp_entityid=%s;token=%s
",
$self
->
{
param_
in
}
->
{
email_address
},
$self
->
{
param_
in
}
->
{
sp_entityid
},
$self
->
{
param_
out
}
->
{
authentication_token
}
$self
->
{
in
}
->
{
email_address
},
$self
->
{
in
}
->
{
sp_entityid
},
$self
->
{
out
}
->
{
authentication_token
}
);
return
1
;
...
...
@@ -515,16 +515,16 @@ sub req_validate_token {
my
(
$self
)
=
@_
;
$self
->
{
logger
}
->
log
(
level
=>
LOG_INFO
,
message
=>
"");
unless
(
$self
->
{
param_
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
unless
(
$self
->
{
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
missing_sp_entityid
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Missing parameter sp_entityid
"
);
return
undef
;
}
unless
(
$self
->
{
param_
in
}
->
{
authentication_token
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
unless
(
$self
->
{
in
}
->
{
authentication_token
})
{
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
missing_authentication_token
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
...
...
@@ -535,30 +535,30 @@ sub req_validate_token {
my
$authentication_token
=
IdPAccountManager::Data::
AuthenticationToken
->
new
(
db
=>
$self
->
{
db
},
token
=>
$self
->
{
param_
in
}
->
{
authentication_token
});
token
=>
$self
->
{
in
}
->
{
authentication_token
});
unless
(
$authentication_token
->
load
())
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
wrong_token
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
wrong_token
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to validate authentication token %s for sp_entityid %s
",
$self
->
{
param_
in
}
->
{
authentication_token
},
$self
->
{
param_
in
}
->
{
sp_entityid
}
$self
->
{
in
}
->
{
authentication_token
},
$self
->
{
in
}
->
{
sp_entityid
}
);
return
undef
;
}
unless
(
$authentication_token
->
get
('
sp_entityid
')
eq
$self
->
{
param_
in
}
->
{
sp_entityid
})
$self
->
{
in
}
->
{
sp_entityid
})
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
wrong_token_for_sp
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
wrong_token_for_sp
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Authentication token %s cannot be used for SP with entityid %s
",
$self
->
{
param_
in
}
->
{
authentication_token
},
$self
->
{
param_
in
}
->
{
sp_entityid
}
$self
->
{
in
}
->
{
authentication_token
},
$self
->
{
in
}
->
{
sp_entityid
}
);
return
undef
;
}
...
...
@@ -568,7 +568,7 @@ sub req_validate_token {
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to delete authentication token %s
",
$self
->
{
param_
in
}
->
{
authentication_token
}
$self
->
{
in
}
->
{
authentication_token
}
);
}
...
...
@@ -579,7 +579,7 @@ sub req_validate_token {
my
$test_account
=
IdPAccountManager::Data::
TestAccount
->
new
(
db
=>
$self
->
{
db
},
account_profile
=>
$profile
,
sp_entityid
=>
$self
->
{
param_
in
}
->
{
sp_entityid
}
sp_entityid
=>
$self
->
{
in
}
->
{
sp_entityid
}
);
next
unless
$test_account
;
next
unless
$test_account
->
save
();
...
...
@@ -587,11 +587,11 @@ sub req_validate_token {
}
unless
(
@test_accounts
)
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
accounts_creation_failed
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
accounts_creation_failed
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to create test accounts for SP with entityid %s
",
$self
->
{
param_
in
}
->
{
sp_entityid
}
$self
->
{
in
}
->
{
sp_entityid
}
);
return
undef
;
}
...
...
@@ -601,7 +601,7 @@ sub req_validate_token {
$self
->
{
configuration
}
->
{
root_manager_dir
},
$self
->
{
configuration
}
))
{
push
@
{
$self
->
{
param_
out
}
->
{
errors
}
},
"
accounts_creation_failed
";
push
@
{
$self
->
{
out
}
->
{
errors
}
},
"
accounts_creation_failed
";
$self
->
{
logger
}
->
log
(
level
=>
LOG_ERROR
,
message
=>
"
Failed to create simpleSAMLphp configuration file
"
...
...
@@ -612,12 +612,12 @@ sub req_validate_token {
$self
->
{
logger
}
->
log
(
level
=>
LOG_INFO
,
message
=>
"
Token validated for sp_entityid=%s;token=%s
",
$self
->
{
param_
in
}
->
{
sp_entityid
},
$self
->
{
param_
in
}
->
{
authentication_token
}
$self
->
{
in
}
->
{
sp_entityid
},
$self
->
{
in
}
->
{
authentication_token
}
);
$self
->
{
param_
out
}
->
{
sp_entityid
}
=
$self
->
{
param_
in
}
->
{
sp_entityid
};
$self
->
{
param_
out
}
->
{
test_accounts
}
=
\
@test_accounts
;
$self
->
{
out
}
->
{
sp_entityid
}
=
$self
->
{
in
}
->
{
sp_entityid
};
$self
->
{
out
}
->
{
test_accounts
}
=
\
@test_accounts
;
return
1
;
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment