# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.

use strict;
use warnings;
use lib qw(lib ../../lib ../../local/lib/perl5);

use Test::More "no_plan";

use QA::Util;

my ($sel, $config) = get_selenium(CHROME_MODE);
my $admin_user = $config->{admin_user_login};

# Let's create a bug and attachment to play with.

log_in($sel, $config, 'admin');
file_bug_in_product($sel, "TestProduct");
my $bug_summary = "Security checks";
$sel->type_ok("short_desc", $bug_summary);
$sel->type_ok("comment",    "This bug will be used to test security fixes.");
$sel->click_ok('//input[@value="Add an attachment"]');
$sel->attach_file('//input[@name="data"]', $config->{attachment_file});
$sel->type_ok('//input[@name="description"]', "simple patch, v1");
my $bug1_id = create_bug($sel, $bug_summary);


#######################################################################
# Security bug 38862.
#######################################################################

# No alternate host for attachments; cookies will be accessible.

set_parameters($sel,
  {"Attachments" => {"allow_attachment_display-on" => undef}});

go_to_bug($sel, $bug1_id);
$sel->click_ok("link=simple patch, v1");
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_is("");
my $cookies    = $sel->get_all_cookies();
my $nb_cookies = scalar @$cookies;
ok($nb_cookies, "Found $nb_cookies cookies");
my %cookies = map { $_->{name} => $_->{value} } @$cookies;
ok(exists $cookies{Bugzilla_login},       "Bugzilla_login is accessible");
ok(exists $cookies{Bugzilla_logincookie}, "Bugzilla_logincookie is accessible");
$sel->go_back_ok();
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_like(qr/^$bug1_id /);

# Alternate host for attachments; no cookie should be accessible.
# FIXME: Figure out how to do this properly in a CI environment.
# Bugzilla->process_cache->{localconfig}->{attachment_base} = 'http://bmo.attachment/';

# go_to_bug($sel, $bug1_id);
# $sel->click_ok("link=simple patch, v1");
# $sel->wait_for_page_to_load_ok(WAIT_TIME);
# $sel->title_is("");
# $cookies = $sel->get_all_cookies();
# $nb_cookies = scalar @$cookies;
# ok(!$nb_cookies, "No cookies found");
# my %cookies = map { $_->{name} => $_->{value} } @$cookies;
# ok(!exists $cookies{Bugzilla_login}, "Bugzilla_login not accessible");
# ok(!exists $cookies{Bugzilla_logincookie},
#   "Bugzilla_logincookie not accessible");
# $sel->go_back_ok();
# $sel->wait_for_page_to_load_ok(WAIT_TIME);
# $sel->title_like(qr/^$bug1_id /);

#######################################################################
# Security bug 472362.
#######################################################################

$sel->click_ok('header-account-menu-button');
$sel->click_ok("link=Preferences");
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_is("User Preferences");
my $admin_cookie = $sel->get_value("token");
logout($sel);

log_in($sel, $config, 'editbugs');
$sel->click_ok('header-account-menu-button');
$sel->click_ok("link=Preferences");
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_is("User Preferences");
my $editbugs_cookie = $sel->get_value("token");

# Using our own unused token is fine.

$sel->open_ok(
  "/userprefs.cgi?tab=settings&dosave=1&display_quips=off&token=$editbugs_cookie"
);
$sel->title_is("User Preferences");
$sel->is_text_present_ok(
  "The changes to your general preferences have been saved");

# Reusing a token must fail. They must all trigger the Suspicious Action warning.

my @args = ("", "token=", "token=i123x", "token=$admin_cookie",
  "token=$editbugs_cookie");

foreach my $arg (@args) {
  $sel->open_ok("/userprefs.cgi?tab=settings&dosave=1&display_quips=off&$arg");
  $sel->title_is("Suspicious Action");

  if ($arg eq "token=$admin_cookie") {
    $sel->is_text_present_ok("Generated by: QA Admin <$admin_user>");
    $sel->is_text_present_ok("This token has not been generated by you");
  }
  else {
    $sel->is_text_present_ok("It looks like you didn't come from the right page");
  }
}
logout($sel);

#######################################################################
# Security bug 529416.
#######################################################################

log_in($sel, $config, 'admin');
file_bug_in_product($sel, "TestProduct");
$sel->type_ok("alias", "secret_qa_bug_" . ($bug1_id + 1));
my $bug_summary2 = "Private QA Bug";
$sel->type_ok("short_desc", $bug_summary2);
$sel->type_ok("comment",    "This private bug is used to test security fixes.");
$sel->type_ok("dependson",  $bug1_id);
$sel->check_ok('//input[@name="groups" and @value="Master"]');
my $bug2_id = create_bug($sel, $bug_summary2);

go_to_bug($sel, $bug1_id);
$sel->is_text_present_ok("secret_qa_bug_$bug2_id");
logout($sel);

log_in($sel, $config, 'editbugs');
go_to_bug($sel, $bug1_id);
ok(!$sel->is_text_present("secret_qa_bug_$bug2_id"),
  "The alias 'secret_qa_bug_$bug2_id' is not visible for unauthorized users");
ok(!$sel->is_text_present($bug2_id),
  "Even the bug ID is not visible for unauthorized users");
logout($sel);

go_to_bug($sel, $bug1_id, 1);
ok(!$sel->is_text_present("secret_qa_bug_$bug2_id"),
  "The alias 'secret_qa_bug_$bug2_id' is not visible for logged out users");
ok(!$sel->is_text_present($bug2_id),
  "Even the bug ID is not visible for logged out users");

#######################################################################
# Security bug 472206.
# Keep this test as the very last one as the File Saver will remain
# open till the end of the script. Selenium is currently* unable
# to interact with it and close it (* = 2.6.0).
#######################################################################

log_in($sel, $config, 'admin');
set_parameters($sel,
  {"Attachments" => {"allow_attachment_display-off" => undef}});

# Attachments are not viewable.

go_to_bug($sel, $bug1_id);
$sel->click_ok("link=Details");
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_like(qr/Attachment \d+ Details for Bug $bug1_id/);
$sel->is_text_present_ok(
  "The attachment is not viewable in your browser due to security restrictions");
$sel->click_ok("link=View");

# Wait 1 second to give the browser a chance to display the attachment.
# Do not use wait_for_page_to_load_ok() as the File Saver will never go away.
sleep(1);
$sel->title_like(qr/Attachment \d+ Details for Bug $bug1_id/);
ok(!$sel->is_text_present('@@'), "Patch not displayed");

# Enable viewing attachments.

set_parameters($sel,
  {"Attachments" => {"allow_attachment_display-on" => undef}});

go_to_bug($sel, $bug1_id);
$sel->click_ok('link=simple patch, v1');
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_is("");
$sel->is_text_present_ok('@@');
$sel->go_back_ok();
$sel->wait_for_page_to_load_ok(WAIT_TIME);
$sel->title_like(qr/$bug1_id /);
logout($sel);
