diff options
96 files changed, 678 insertions, 1032 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 44d196efe..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,289 +0,0 @@ -# References: -# 1. https://circleci.com/blog/how-to-build-a-docker-image-on-circleci-2-0/ -# 2. https://circleci.com/docs/2.0/building-docker-images/ -# - -version: 2 - -defaults: - bmo_slim_image: &bmo_slim_image - image: mozillabteam/bmo-slim:20180801.2 - user: app - - mysql_image: &mysql_image - image: mozillabteam/bmo-mysql:5.6 - - store_log: &store_log - store_artifacts: - path: /app/bugzilla.log - destination: bugzilla.log - - main_filters: &main_filters - branches: - ignore: - - /^(?:release|test)-20\d\d\d\d\d\d\.\d+/ - - /\// - - production - - bmo_env: &bmo_env - PORT: 8000 - LOGGING_PORT: 5880 - LOCALCONFIG_ENV: 1 - LOG4PERL_CONFIG_FILE: log4perl-test.conf - BMO_db_user: bugs - BMO_db_host: 127.0.0.1 - BMO_db_pass: bugs - BMO_db_name: bugs - BMO_memcached_servers: localhost:11211 - BMO_memcached_namespace: "bugzilla:" - BMO_urlbase: AUTOMATIC - - mysql_env: &mysql_env - MYSQL_DATABASE: bugs - MYSQL_USER: bugs - MYSQL_PASSWORD: bugs - MYSQL_ALLOW_EMPTY_PASSWORD: 1 - - docker_oldtests: &docker_oldtests - - <<: *bmo_slim_image - environment: - <<: *bmo_env - BZ_QA_CONF_FILE: /app/.circleci/selenium_test.conf - BZ_QA_ANSWERS_FILE: /app/.circleci/checksetup_answers.legacy.txt - BZ_QA_LEGACY_MODE: 1 - - <<: *mysql_image - environment: *mysql_env - - image: selenium/standalone-firefox:2.53.1 - - image: memcached:latest - - default_qa_setup: &default_qa_setup - run: - name: default qa setup - command: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - mv /opt/bmo/local /app/local - perl -MSys::Hostname -i -pE 's/bmo.test/hostname() . ":$ENV{PORT}"/ges' $BZ_QA_CONF_FILE - perl checksetup.pl --no-database --default-localconfig - mkdir artifacts - -jobs: - build_info: - parallelism: 1 - working_directory: /app - docker: - - <<: *bmo_slim_image - environment: - <<: *bmo_env - steps: - - checkout - - run: - name: build push data - command: | - mv /opt/bmo/local /app/local - perl Makefile.PL - perl -I/app -I/app/local/lib/perl5 -MBugzilla -e 1 - perl checksetup.pl --no-database --no-templates --no-permissions - perl scripts/build-bmo-push-data.pl - - run: - name: only publish if tag exists - command: | - tag="$(cat build_info/tag.txt)" - git fetch --tags - if git tag | fgrep -q "$tag"; then - echo "tag $tag exists!" - else - echo "tag $tag does not exist" - echo yes > build_info/publish.txt - fi - - run: - name: check if only version changed - command: | - if git diff 'HEAD~..HEAD' --name-only | grep -qv '^Bugzilla.pm'; then - echo "more files than just Bugzilla.pm changed." - exit 0 - fi - if git diff 'HEAD~..HEAD' |grep '^[+-][^+-]' | grep -qv '^[+-]our $VERSION'; then - echo "Something other than the version number changed." - exit 0 - fi - if [[ "$CIRCLE_BRANCH" == "master" ]]; then - echo "Can't cut corners on the master branch" - exit 0 - fi - echo yes > build_info/only_version_changed.txt - - persist_to_workspace: - root: /app/build_info - paths: ["*.txt"] - - store_artifacts: - path: /app/build_info - - *store_log - - build: - working_directory: /app - docker: - - image: docker:17.06.1-ce - steps: - - setup_remote_docker - - run: - name: install git and ssh - command: apk update && apk add git openssh-client - - checkout - - run: | - docker build \ - --build-arg CI="$CI" \ - --build-arg CIRCLE_SHA1="$CIRCLE_SHA1" \ - --build-arg CIRCLE_BUILD_URL="$CIRCLE_BUILD_URL" \ - -t bmo . - - attach_workspace: - at: /app/build_info - - run: "docker run --name bmo --entrypoint true bmo" - - run: "docker cp bmo:/app/version.json build_info/version.json" - - store_artifacts: - path: /app/build_info - - *store_log - - deploy: - command: | - TAG="$(cat /app/build_info/tag.txt)" - [[ "$CIRCLE_BRANCH" == "master" ]] || exit 0 - [[ -n "$DOCKERHUB_REPO" && -n "$DOCKER_USER" && -n "$DOCKER_PASS" ]] || exit 0 - [[ -n "$GITHUB_PERSONAL_TOKEN" ]] || exit 0 - docker login -u "$DOCKER_USER" -p "$DOCKER_PASS" - if [[ -n "$TAG" && -f build_info/publish.txt ]]; then - git config credential.helper "cache --timeout 120" - git config user.email "$GITHUB_EMAIL" - git config user.name "$GITHUB_NAME" - git tag $TAG - git push https://${GITHUB_PERSONAL_TOKEN}:x-oauth-basic@github.com/$GITHUB_REPO.git $TAG - docker tag bmo "$DOCKERHUB_REPO:$TAG" - docker push "$DOCKERHUB_REPO:$TAG" - fi - docker tag bmo "$DOCKERHUB_REPO:latest" - docker push "$DOCKERHUB_REPO:latest" - - test_sanity: - parallelism: 1 - working_directory: /app - docker: - - <<: *bmo_slim_image - environment: *bmo_env - steps: - - checkout - - attach_workspace: - at: /app/build_info - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - mv /opt/bmo/local /app/local - mkdir artifacts - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - perl -I/app -I/app/local/lib/perl5 -c -E 'use Bugzilla; BEGIN { Bugzilla->extensions }' - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - perl Makefile.PL - - run: - name: run sanity tests - command: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl prove -qf $(circleci tests glob 't/*.t' | circleci tests split) | tee artifacts/$CIRCLE_JOB.txt - - store_artifacts: - path: /app/artifacts - - *store_log - - test_webservices: - parallelism: 1 - working_directory: /app - docker: *docker_oldtests - steps: - - checkout - - attach_workspace: - at: /app/build_info - - *default_qa_setup - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl load_test_data - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl test_webservices | tee artifacts/$CIRCLE_JOB.txt - - store_artifacts: - path: /app/artifacts - - *store_log - - test_selenium: - parallelism: 1 - working_directory: /app - docker: *docker_oldtests - steps: - - checkout - - attach_workspace: - at: /app/build_info - - *default_qa_setup - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl load_test_data --legacy - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl test_selenium | tee artifacts/$CIRCLE_JOB.txt - - store_artifacts: - path: /app/artifacts - - *store_log - - test_bmo: - parallelism: 1 - working_directory: /app - docker: - - <<: *bmo_slim_image - environment: - <<: *bmo_env - BZ_QA_ANSWERS_FILE: /app/.circleci/checksetup_answers.txt - TWD_HOST: localhost - TWD_PORT: 4444 - TWD_BROWSER: firefox - - <<: *mysql_image - environment: *mysql_env - - image: memcached:latest - - image: selenium/standalone-firefox:2.53.1 - steps: - - checkout - - attach_workspace: - at: /app/build_info - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - mv /opt/bmo/local /app/local - perl checksetup.pl --no-database - /app/scripts/entrypoint.pl load_test_data - mkdir artifacts - - run: | - [[ -f build_info/only_version_changed.txt ]] && exit 0 - /app/scripts/entrypoint.pl test_bmo -q -f t/bmo/*.t - - *store_log - -workflows: - version: 2 - main: - jobs: - - build_info: - filters: *main_filters - - build: - filters: *main_filters - requires: - - build_info - - test_sanity - - test_bmo - - test_webservices - - test_selenium - - test_sanity: - filters: *main_filters - requires: - - build_info - - test_bmo: - filters: *main_filters - requires: - - build_info - - test_webservices: - filters: *main_filters - requires: - - build_info - - test_selenium: - filters: *main_filters - requires: - - build_info diff --git a/.gitignore b/.gitignore index 18f2d0a17..7bf2816b9 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,9 @@ /data /localconfig /localconfig.* +/conf/env.conf /index.html +/errors/ /error_reports /.DS_Store /template_cache @@ -7,13 +7,11 @@ AddType image/x-icon .ico AddType application/font-woff .woff AddType application/font-woff2 .woff2 -Redirect permanent /queryhelp.cgi https://bugzilla.mozilla.org/query.cgi?format=advanced&help=1 -Redirect permanent /bug_status.html https://bugzilla.mozilla.org/page.cgi?id=fields.html -Redirect permanent /bugwritinghelp.html https://bugzilla.mozilla.org/page.cgi?id=bug-writing.html -Redirect permanent /etiquette.html https://bugzilla.mozilla.org/page.cgi?id=etiquette.html -Redirect permanent /duplicates.html https://bugzilla.mozilla.org/duplicates.cgi -Redirect permanent /quicksearch.html https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html -Redirect permanent /bugwritinghelp.html https://bugzilla.mozilla.org/page.cgi?id=bug-writing.html +Redirect permanent /queryhelp.cgi /query.cgi?format=advanced&help=1 +Redirect permanent /bug_status.html /page.cgi?id=fields.html +Redirect permanent /bugwritinghelp.html /page.cgi?id=bug-writing.html +Redirect permanent /etiquette.html /page.cgi?id=etiquette.html +Redirect permanent /duplicates.html /duplicates.cgi RewriteEngine On # This rewrite rule skips over the rest, which is good because the load balancers diff --git a/Bugzilla.pm b/Bugzilla.pm index 06bf2ddf0..a6f4e2b4d 100644 --- a/Bugzilla.pm +++ b/Bugzilla.pm @@ -13,7 +13,7 @@ use warnings; use Bugzilla::Logging; -our $VERSION = '20180803.1'; +our $VERSION = '5.13'; use Bugzilla::Auth; use Bugzilla::Auth::Persist::Cookie; @@ -46,6 +46,7 @@ use File::Basename; use File::Spec::Functions; use Safe; use JSON::XS qw(decode_json); +use URI; use parent qw(Bugzilla::CPAN); @@ -110,20 +111,6 @@ sub init_page { # 001compile.t test). return if $^C; - # IIS prints out warnings to the webpage, so ignore them, or log them - # to a file if the file exists. - if ($ENV{SERVER_SOFTWARE} && $ENV{SERVER_SOFTWARE} =~ /microsoft-iis/i) { - $SIG{__WARN__} = sub { - my ($msg) = @_; - my $datadir = bz_locations()->{'datadir'}; - if (-w "$datadir/errorlog") { - my $warning_log = new IO::File(">>$datadir/errorlog"); - print $warning_log $msg; - $warning_log->close(); - } - }; - } - my $script = basename($0); # Because of attachment_base, attachment.cgi handles this itself. @@ -219,6 +206,14 @@ sub template_inner { } sub extensions { + # Guard against extensions querying the extension list during initialization + # (through this method or has_extension). + # The extension list is not fully populated at that point, + # so the results would not be meaningful. + state $recursive = 0; + die "Recursive attempt to load/query extensions" if $recursive; + $recursive = 1; + my $cache = request_cache; if (!$cache->{extensions}) { my $extension_packages = Bugzilla::Extension->load_all(); @@ -231,9 +226,20 @@ sub extensions { } $cache->{extensions} = \@extensions; } + $recursive = 0; return $cache->{extensions}; } +sub has_extension { + my ($class, $name) = @_; + my $cache = $class->request_cache; + if (!$cache->{extensions_hash}) { + my %extensions = map { $_->NAME => 1 } @{ Bugzilla->extensions }; + $cache->{extensions_hash} = \%extensions; + } + return exists $cache->{extensions_hash}{$name}; +} + sub cgi { return request_cache->{cgi} ||= Bugzilla::CGI->new; } @@ -258,6 +264,13 @@ sub localconfig { return $_[0]->process_cache->{localconfig} ||= read_localconfig(); } +sub urlbase { + my ($class) = @_; + + # Since this could be modified, we have to return a new one every time. + return URI->new($class->localconfig->{urlbase}); +} + sub params { return request_cache->{params} ||= Bugzilla::Config::read_param_file(); } @@ -844,10 +857,10 @@ sub _cleanup { sub END { # Bugzilla.pm cannot compile in mod_perl.pl if this runs. - _cleanup() unless $ENV{MOD_PERL}; + _cleanup() unless BZ_PERSISTENT; } -init_page() if !$ENV{MOD_PERL}; +init_page() unless BZ_PERSISTENT; 1; diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index 1bf0dd54a..9ac01c71e 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -704,7 +704,7 @@ sub send_cookie { } # Add the default path and the domain in. - state $uri = URI->new( Bugzilla->localconfig->{urlbase} ); + state $uri = Bugzilla->urlbase; $paramhash{'-path'} = $uri->path; # we don't set the domain. $paramhash{'-secure'} = 1 diff --git a/Bugzilla/Config/BugFields.pm b/Bugzilla/Config/BugFields.pm index 94a16b7c2..c443ffe78 100644 --- a/Bugzilla/Config/BugFields.pm +++ b/Bugzilla/Config/BugFields.pm @@ -65,7 +65,7 @@ sub get_param_list { name => 'defaultpriority', type => 's', choices => \@legal_priorities, - default => $legal_priorities[-1], + default => $legal_priorities[0], checker => \&check_priority }, diff --git a/Bugzilla/Config/General.pm b/Bugzilla/Config/General.pm index c870c7376..fa7cf2d08 100644 --- a/Bugzilla/Config/General.pm +++ b/Bugzilla/Config/General.pm @@ -25,6 +25,14 @@ use constant get_param_list => ( }, { + name => 'nobody_user', + type => 't', + no_reset => '1', + default => 'nobody@mozilla.org', + checker => \&check_email + }, + + { name => 'docs_urlbase', type => 't', default => 'docs/%lang%/html/', diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index 185a30390..34e4a4cfe 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -194,6 +194,8 @@ use Memoize; EMAIL_LIMIT_EXCEPTION JOB_QUEUE_VIEW_MAX_JOBS + + BZ_PERSISTENT ); @Bugzilla::Constants::EXPORT_OK = qw(contenttypes); @@ -696,6 +698,8 @@ sub _bz_locations { }; } +use constant BZ_PERSISTENT => $main::BUGZILLA_PERSISTENT; + # This makes us not re-compute all the bz_locations data every time it's # called. BEGIN { memoize('_bz_locations') }; diff --git a/Bugzilla/DB.pm b/Bugzilla/DB.pm index 80404131a..f07bb7183 100644 --- a/Bugzilla/DB.pm +++ b/Bugzilla/DB.pm @@ -61,14 +61,12 @@ use constant ISOLATION_LEVEL => 'REPEATABLE READ'; # Bugzilla with enums. After that, they are either controlled through # the Bugzilla UI or through the DB. use constant ENUM_DEFAULTS => { - bug_severity => ['blocker', 'critical', 'major', 'normal', - 'minor', 'trivial', 'enhancement'], - priority => ["Highest", "High", "Normal", "Low", "Lowest", "---"], - op_sys => ["All","Windows","Mac OS","Linux","Other"], - rep_platform => ["All","PC","Macintosh","Other"], - bug_status => ["UNCONFIRMED","CONFIRMED","IN_PROGRESS","RESOLVED", - "VERIFIED"], - resolution => ["","FIXED","INVALID","WONTFIX", "DUPLICATE","WORKSFORME"], + bug_severity => [qw(blocker critical major normal minor trivial enhancement )], + priority => [qw(-- P1 P2 P3 P4 P5)], + op_sys => [ "Unspecified", "All", "Windows", "Mac OS", "Linux", "Other" ], + rep_platform => [ "Unspecified", "All", "PC", "Macintosh", "Other" ], + bug_status => [qw(UNCONFIRMED NEW ASSIGNED REOPENED RESOLVED VERIFIED CLOSED)], + resolution => [ "", qw(FIXED INVALID WONTFIX DUPLICATE WORKSFORME INCOMPLETE) ], }; # The character that means "OR" in a boolean fulltext search. If empty, diff --git a/Bugzilla/Elastic/Role/HasClient.pm b/Bugzilla/Elastic/Role/HasClient.pm index 8e2687880..a971392e0 100644 --- a/Bugzilla/Elastic/Role/HasClient.pm +++ b/Bugzilla/Elastic/Role/HasClient.pm @@ -8,7 +8,6 @@ package Bugzilla::Elastic::Role::HasClient; use 5.10.1; use Moo::Role; -use Search::Elasticsearch; has 'client' => (is => 'lazy'); @@ -16,6 +15,7 @@ has 'client' => (is => 'lazy'); sub _build_client { my ($self) = @_; + require Search::Elasticsearch; return Search::Elasticsearch->new( nodes => [ split(/\s+/, Bugzilla->params->{elasticsearch_nodes}) ], cxn_pool => 'Sniff', diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm index c941482f0..7f684ea15 100644 --- a/Bugzilla/Group.pm +++ b/Bugzilla/Group.pm @@ -26,17 +26,24 @@ use Scalar::Util qw(blessed); use constant IS_CONFIG => 1; -use constant DB_COLUMNS => qw( - groups.id - groups.name - groups.description - groups.isbuggroup - groups.userregexp - groups.isactive - groups.icon_url - groups.owner_user_id - groups.idle_member_removal -); +sub DB_COLUMNS { + my $class = shift; + my @columns = qw( + id + name + description + isbuggroup + userregexp + isactive + icon_url + owner_user_id + idle_member_removal + ); + my $dbh = Bugzilla->dbh; + my $table = $class->DB_TABLE; + + return map { "$table.$_" } grep { $dbh->bz_column_info($table, $_) } @columns; +} use constant DB_TABLE => 'groups'; diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm index 8bce9b5e7..14fe904eb 100644 --- a/Bugzilla/Install.pm +++ b/Bugzilla/Install.pm @@ -19,6 +19,7 @@ use 5.10.1; use strict; use warnings; +use Bugzilla::Logging; use Bugzilla::Component; use Bugzilla::Config qw(:admin); use Bugzilla::Constants; @@ -31,21 +32,31 @@ use Bugzilla::Util qw(get_text); use Bugzilla::Version; use constant STATUS_WORKFLOW => ( - [undef, 'UNCONFIRMED'], - [undef, 'CONFIRMED'], - [undef, 'IN_PROGRESS'], - ['UNCONFIRMED', 'CONFIRMED'], - ['UNCONFIRMED', 'IN_PROGRESS'], - ['UNCONFIRMED', 'RESOLVED'], - ['CONFIRMED', 'IN_PROGRESS'], - ['CONFIRMED', 'RESOLVED'], - ['IN_PROGRESS', 'CONFIRMED'], - ['IN_PROGRESS', 'RESOLVED'], - ['RESOLVED', 'UNCONFIRMED'], - ['RESOLVED', 'CONFIRMED'], - ['RESOLVED', 'VERIFIED'], - ['VERIFIED', 'UNCONFIRMED'], - ['VERIFIED', 'CONFIRMED'], + [ undef, 'UNCONFIRMED' ], + [ undef, 'NEW' ], + [ undef, 'ASSIGNED' ], + [ 'UNCONFIRMED', 'NEW' ], + [ 'UNCONFIRMED', 'ASSIGNED' ], + [ 'UNCONFIRMED', 'RESOLVED' ], + [ 'NEW', 'UNCONFIRMED' ], + [ 'NEW', 'ASSIGNED' ], + [ 'NEW', 'RESOLVED' ], + [ 'ASSIGNED', 'UNCONFIRMED' ], + [ 'ASSIGNED', 'NEW' ], + [ 'ASSIGNED', 'RESOLVED' ], + [ 'REOPENED', 'UNCONFIRMED' ], + [ 'REOPENED', 'NEW' ], + [ 'REOPENED', 'ASSIGNED' ], + [ 'REOPENED', 'RESOLVED' ], + [ 'RESOLVED', 'UNCONFIRMED' ], + [ 'RESOLVED', 'REOPENED' ], + [ 'RESOLVED', 'VERIFIED' ], + [ 'VERIFIED', 'UNCONFIRMED' ], + [ 'VERIFIED', 'REOPENED' ], + [ 'VERIFIED', 'RESOLVED' ], + [ 'CLOSED', 'UNCONFIRMED' ], + [ 'CLOSED', 'REOPENED' ], + [ 'CLOSED', 'RESOLVED' ], ); sub SETTINGS { @@ -385,6 +396,7 @@ sub init_workflow { 'SELECT value, id FROM bug_status', {Columns=>[1,2]}) }; foreach my $pair (STATUS_WORKFLOW) { + WARN("unknown bug_status: " . $pair->[1]) unless $status_ids{$pair->[1]}; my $old_id = $pair->[0] ? $status_ids{$pair->[0]} : undef; my $new_id = $status_ids{$pair->[1]}; $dbh->do('INSERT INTO status_workflow (old_status, new_status) diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm index 2e5ae5ff2..8b3d4b8cc 100644 --- a/Bugzilla/Install/DB.pm +++ b/Bugzilla/Install/DB.pm @@ -3908,7 +3908,16 @@ sub _migrate_group_owners { my $dbh = Bugzilla->dbh; return if $dbh->bz_column_info('groups', 'owner_user_id'); $dbh->bz_add_column('groups', 'owner_user_id', {TYPE => 'INT3'}); - my $nobody = Bugzilla::User->check('nobody@mozilla.org'); + my $nobody = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'}, cache => 1 }); + unless ($nobody) { + $nobody = Bugzilla::User->create( + { + login_name => Bugzilla->params->{'nobody_user'}, + realname => 'Nobody (ok to assign bugs to)', + cryptpassword => '*', + } + ); + } $dbh->do('UPDATE groups SET owner_user_id = ?', undef, $nobody->id); } diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm index f520d3d56..46e121779 100644 --- a/Bugzilla/Install/Filesystem.pm +++ b/Bugzilla/Install/Filesystem.pm @@ -72,6 +72,50 @@ sub HTTPD_ENV_CONF { return join( "\n", map { "PerlPassEnv " . $_ } @env ) . "\n"; } +sub _error_page { + my ($code, $title, $description) = @_; + + return <<EOT; +<!DOCTYPE HTML> +<html> + <head> + <title>$title</title> + <style> + body { + margin: 1em 2em; + background-color: #455372; + color: #ddd; + font-family: sans-serif; + } + h1, h3 { + color: #fff; + } + a { + color: #fff; + text-decoration: none; + } + #buggie { + float: left; + } + #content { + margin-left: 100px; + padding-top: 20px; + } + </style> + </head> + <body> + <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215"> + <div id="content"> + <h1>$title</h1> + <p>$description</p> + <h3>Error $code</h3> + <p><a href="/">this site</a></p> + </div> + </body> +</html> +EOT +} + ############### # Permissions # ############### @@ -169,6 +213,7 @@ sub FILESYSTEM { # users to be able to cron them or otherwise run # them as a secure user, like the webserver owner. '*.cgi' => { perms => WS_EXECUTE }, + '*.psgi' => { perms => CGI_READ }, 'whineatnews.pl' => { perms => WS_EXECUTE }, 'collectstats.pl' => { perms => WS_EXECUTE }, 'importxml.pl' => { perms => WS_EXECUTE }, @@ -300,7 +345,7 @@ sub FILESYSTEM { 'contrib' => { files => OWNER_EXECUTE, dirs => DIR_OWNER_WRITE, }, 'scripts' => { files => OWNER_EXECUTE, - dirs => DIR_OWNER_WRITE, }, + dirs => DIR_WS_SERVE, }, ); # --- FILES TO CREATE --- # @@ -387,6 +432,40 @@ sub FILESYSTEM { contents => \&HTTPD_ENV_CONF }, ); + # Create static error pages. + $create_dirs{"errors"} = DIR_CGI_READ; + $create_files{"errors/401.html"} = { + perms => CGI_READ, + overwrite => 1, + contents => _error_page( + 401, 'Authentication Required', + "This server could not verify that you are authorized to access + that url. you either supplied the wrong credentials (e.g., bad + password), or your browser doesn't understand how to supply the + credentials required.") + }; + $create_files{"errors/403.html"} = { + perms => CGI_READ, + overwrite => 1, + contents => _error_page( + 403, 'Access Denied', + "Access to the requested resource has been denied.") + }; + $create_files{"errors/404.html"} = { + perms => CGI_READ, + overwrite => 1, + contents => _error_page( + 404, 'Object Not Found', + "The requested URL was not found on this server.") + }; + $create_files{"errors/500.html"} = { + perms => CGI_READ, + overwrite => 1, + contents => _error_page( + 500, 'Internal Server Error', + "The server encountered an internal error and was unable to complete your request.") + }; + # Because checksetup controls the creation of index.html separately # from all other files, it gets its very own hash. my %index_html = ( @@ -472,7 +551,7 @@ sub update_filesystem { # Delete old files that no longer need to exist # 2001-04-29 jake@bugzilla.org - Remove oldemailtech - # http://bugzilla.mozilla.org/show_bugs.cgi?id=71552 + # http://bugzilla.mozilla.org/show_bug.cgi?id=71552 if (-d 'shadow') { print "Removing shadow directory...\n"; rmtree("shadow"); diff --git a/Bugzilla/Install/Localconfig.pm b/Bugzilla/Install/Localconfig.pm index e1a8e0909..39063ee63 100644 --- a/Bugzilla/Install/Localconfig.pm +++ b/Bugzilla/Install/Localconfig.pm @@ -288,7 +288,12 @@ sub read_localconfig { my ($include_deprecated) = @_; if ($ENV{LOCALCONFIG_ENV}) { - return _read_localconfig_from_env(); + my $lc = _read_localconfig_from_env(); + if ( $lc->{urlbase} eq 'AUTOMATIC' ) { + $lc->{urlbase} = sprintf 'http://%s:%d/%s', hostname(), $ENV{PORT}, $ENV{BZ_QA_LEGACY_MODE} ? 'bmo/' : ''; + $ENV{BZ_BASE_URL} = sprintf 'http://%s:%d', hostname(), $ENV{PORT}; + } + return $lc; } else { return _read_localconfig_from_file($include_deprecated); diff --git a/Bugzilla/PSGI.pm b/Bugzilla/PSGI.pm new file mode 100644 index 000000000..46352b319 --- /dev/null +++ b/Bugzilla/PSGI.pm @@ -0,0 +1,42 @@ +# 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. + +package Bugzilla::PSGI; +use 5.10.1; +use strict; +use warnings; + +use base qw(Exporter); + +use Bugzilla::Logging; +our @EXPORT_OK = qw(compile_cgi); + +sub compile_cgi { + my ($script) = @_; + require CGI::Compile; + require CGI::Emulate::PSGI; + + my $cgi = CGI::Compile->compile($script); + my $app = CGI::Emulate::PSGI->handler( + sub { + Bugzilla::init_page(); + $cgi->(); + } + ); + return sub { + my $env = shift; + if ($env->{'psgix.cleanup'}) { + push @{ $env->{'psgix.cleanup.handler'} }, \&Bugzilla::_cleanup; + } + my $res = $app->($env); + Bugzilla::_cleanup() if not $env->{'psgix.cleanup'}; + return $res; + }; +} + + +1;
\ No newline at end of file diff --git a/Bugzilla/Quantum/Plugin/Hostage.pm b/Bugzilla/Quantum/Plugin/Hostage.pm index cbde7b5ee..418b09a0c 100644 --- a/Bugzilla/Quantum/Plugin/Hostage.pm +++ b/Bugzilla/Quantum/Plugin/Hostage.pm @@ -1,20 +1,19 @@ package Bugzilla::Quantum::Plugin::Hostage; use 5.10.1; use Mojo::Base 'Mojolicious::Plugin'; -use Bugzilla::Logging; sub _attachment_root { my ($base) = @_; return undef unless $base; return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)} - ? $1 - : undef; + ? $1 + : undef; } sub _attachment_host_regex { my ($base) = @_; return undef unless $base; - my $val = $base; + my $val = $base; $val =~ s{^https?://}{}s; $val =~ s{/$}{}s; my $regex = quotemeta $val; @@ -25,11 +24,11 @@ sub _attachment_host_regex { sub register { my ( $self, $app, $conf ) = @_; - $app->hook( before_routes => \&_before_routes ); + $app->hook(before_routes => \&_before_routes); } sub _before_routes { - my ($c) = @_; + my ( $c ) = @_; state $urlbase = Bugzilla->localconfig->{urlbase}; state $urlbase_uri = URI->new($urlbase); state $urlbase_host = $urlbase_uri->host; @@ -44,40 +43,35 @@ sub _before_routes { return if $stash->{'mojo.static'}; - my $hostname = $url->host; + my $hostname = $url->host; return if $hostname eq $urlbase_host; my $path = $url->path; return if $path eq '/__lbheartbeat__'; - if ( $attachment_base && $hostname eq $attachment_root ) { - DEBUG("redirecting to $urlbase because $hostname is $attachment_root"); + if ($attachment_base && $hostname eq $attachment_root) { $c->redirect_to($urlbase); return; } - elsif ( $attachment_base && $hostname =~ $attachment_host_regex ) { - if ( $path =~ m{^/attachment\.cgi}s ) { + elsif ($attachment_base && $hostname =~ $attachment_host_regex) { + if ($path =~ m{^/attachment\.cgi}s) { return; - } - else { + } else { my $new_uri = $url->clone; - $new_uri->scheme( $urlbase_uri->scheme ); + $new_uri->scheme($urlbase_uri->scheme); $new_uri->host($urlbase_host); - DEBUG("redirecting to $new_uri because $hostname matches attachment regex"); $c->redirect_to($new_uri); return; } } - elsif ( my ($id) = $hostname =~ $urlbase_host_regex ) { + elsif (my ($id) = $hostname =~ $urlbase_host_regex) { my $new_uri = $urlbase_uri->clone; $new_uri->path('/show_bug.cgi'); - $new_uri->query_form( id => $id ); - DEBUG("redirecting to $new_uri because $hostname includes bug id"); + $new_uri->query_form(id => $id); $c->redirect_to($new_uri); return; } else { - DEBUG("redirecting to $urlbase because $hostname doesn't make sense"); $c->redirect_to($urlbase); return; } diff --git a/Bugzilla/Quantum/Template.pm b/Bugzilla/Quantum/Template.pm new file mode 100644 index 000000000..2442f1134 --- /dev/null +++ b/Bugzilla/Quantum/Template.pm @@ -0,0 +1,39 @@ +# 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. + +package Bugzilla::Quantum::Template; +use 5.10.1; +use Moo; + +has 'controller' => ( + is => 'ro', + required => 1, +); + +has 'template' => ( + is => 'ro', + required => 1, + handles => ['error', 'get_format'], +); + +sub process { + my ($self, $file, $vars, $output) = @_; + + if (@_ < 4) { + $self->controller->stash->{vars} = $vars; + $self->controller->render(template => $file, handler => 'bugzilla'); + return 1; + } + elsif (@_ == 4) { + return $self->template->process($file, $vars, $output); + } + else { + die __PACKAGE__ . '->process() called with too many arguments'; + } +} + +1;
\ No newline at end of file diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index f419955dc..e15c60f7f 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -802,18 +802,20 @@ sub data { # BMO - to avoid massive amounts of joins, if we're selecting a lot of # tracking flags, replace them with placeholders. the values will be # retrieved later and injected into the result. - my %tf_map = map { $_ => 1 } Bugzilla::Extension::TrackingFlags::Flag->get_all_names(); - my @tf_selected = grep { exists $tf_map{$_} } @orig_fields; - # mysql has a limit of 61 joins, and we want to avoid massive amounts of joins - # 30 ensures we won't hit the limit, nor generate too many joins - if (scalar @tf_selected > 30) { - foreach my $column (@tf_selected) { - $self->COLUMNS->{$column}->{name} = "'---'"; + if (Bugzilla->has_extension('TrackingFlags')) { + my %tf_map = map { $_ => 1 } Bugzilla::Extension::TrackingFlags::Flag->get_all_names(); + my @tf_selected = grep { exists $tf_map{$_} } @orig_fields; + # mysql has a limit of 61 joins, and we want to avoid massive amounts of joins + # 30 ensures we won't hit the limit, nor generate too many joins + if (scalar @tf_selected > 30) { + foreach my $column (@tf_selected) { + $self->COLUMNS->{$column}->{name} = "'---'"; + } + $self->{tracking_flags} = \@tf_selected; + } + else { + $self->{tracking_flags} = []; } - $self->{tracking_flags} = \@tf_selected; - } - else { - $self->{tracking_flags} = []; } my $start_time = [gettimeofday()]; @@ -863,7 +865,7 @@ sub data { $self->{data} = [map { $data{$_} } @$bug_ids]; # BMO - get tracking flags values, and insert into result - if (@{ $self->{tracking_flags} }) { + if (Bugzilla->has_extension('TrackingFlags') && @{ $self->{tracking_flags} }) { # read values my $values; $sql = " diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm index 39272a538..cdeb54a50 100644 --- a/Bugzilla/Template.pm +++ b/Bugzilla/Template.pm @@ -995,6 +995,8 @@ sub create { 'feature_enabled' => sub { return Bugzilla->feature(@_); }, + 'has_extension' => sub { return Bugzilla->has_extension(@_); }, + # field_descs can be somewhat slow to generate, so we generate # it only once per-language no matter how many times # $template->process() is called. diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0ac04acc6..000000000 --- a/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM mozillabteam/bmo-slim:20180801.2 - -ARG CI -ARG CIRCLE_SHA1 -ARG CIRCLE_BUILD_URL - -ENV CI=${CI} -ENV CIRCLE_BUILD_URL=${CIRCLE_BUILD_URL} -ENV CIRCLE_SHA1=${CIRCLE_SHA1} - -ENV LOG4PERL_CONFIG_FILE=log4perl-json.conf - -ENV PORT=8000 - -# we run a loopback logging server on this TCP port. -ENV LOGGING_PORT=5880 - -WORKDIR /app -COPY . . - -RUN mv /opt/bmo/local /app && \ - chown -R app:app /app && \ - perl -I/app -I/app/local/lib/perl5 -c -E 'use Bugzilla; BEGIN { Bugzilla->extensions }' && \ - perl -c /app/scripts/entrypoint.pl && \ - setcap 'cap_net_bind_service=+ep' /usr/sbin/httpd && \ - setcap 'cap_net_bind_service=+ep' /usr/bin/perl - -USER app - -RUN perl checksetup.pl --no-database --default-localconfig && \ - rm -rf /app/data /app/localconfig && \ - mkdir /app/data - -EXPOSE $PORT - -ENTRYPOINT ["/app/scripts/entrypoint.pl"] -CMD ["httpd"] diff --git a/Makefile.PL b/Makefile.PL index 3cd1dabba..b0f7e88ce 100755 --- a/Makefile.PL +++ b/Makefile.PL @@ -47,7 +47,6 @@ my %requires = ( 'Date::Format' => '2.23', 'DateTime' => '0.75', 'DateTime::TimeZone' => '2.11', - 'Devel::NYTProf' => '6.04', 'Digest::SHA' => '5.47', 'Email::MIME' => '1.904', 'Email::Send' => '1.911', @@ -75,7 +74,6 @@ my %requires = ( 'Mozilla::CA' => '20160104', 'Parse::CPAN::Meta' => '1.44', 'Role::Tiny' => '2.000003', - 'Sereal' => '4.004', 'Taint::Util' => '0.08', 'Template' => '2.24', 'Text::CSV_XS' => '1.26', @@ -445,6 +443,7 @@ META.json: Makefile.PL \tmake distmeta 2>&1 /dev/null; mv */META.json . META.yml: Makefile.PL +1: hit EOF seeking end of quote/pattern starting at line 1 ending in / \tmake distmeta 2>&1 /dev/null; mv */META.yml . MAKE } diff --git a/app.psgi b/app.psgi new file mode 100644 index 000000000..4425b3e0c --- /dev/null +++ b/app.psgi @@ -0,0 +1,115 @@ +#!/usr/bin/perl +# 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 5.10.1; +use strict; +use warnings; + +BEGIN { $main::BUGZILLA_PERSISTENT = 1 } + +use File::Basename; +use File::Spec; + +BEGIN { + require lib; + my $dir = File::Spec->rel2abs( dirname(__FILE__) ); + lib->import( + $dir, + File::Spec->catdir( $dir, 'lib' ), + File::Spec->catdir( $dir, qw(local lib perl5) ) + ); + + # disable "use lib" from now on + no warnings qw(redefine); + *lib::import = sub { }; +} + +# it is very important for CGI::Compile to be loaded first. +use CGI::Compile; +use Bugzilla::PSGI qw(compile_cgi); +use Bugzilla::Logging; +use Bugzilla (); +use Bugzilla::Constants (); +use Bugzilla::BugMail (); +use Bugzilla::CGI (); +use Bugzilla::Extension (); +use Bugzilla::Install::Requirements (); +use Bugzilla::Util (); +use Bugzilla::RNG (); + +use Plack; +use Plack::Builder; +use Plack::App::URLMap; +use Plack::App::WrapCGI; +use Plack::Response; + +# Pre-load all extensions and find their static dirs. +my @extensions = map { $_->NAME } @{ Bugzilla::Extension->load_all() }; +my @static_dirs = qw( data/webdot docs graphs images js skins static ); +foreach my $name (@extensions) { + my $dir = File::Spec->catfile('extensions', $name, 'web'); + push @static_dirs, $dir if -d $dir; +} + +Bugzilla->preload_features(); + +# Force instantiation of template so Bugzilla::Template::PreloadProvider can do its magic. +Bugzilla->template; + +use Bugzilla::Sentry; + + +my $bugzilla_app = builder { + my $static_paths = join '|', map quotemeta, sort {length $b <=> length $a || $a cmp $b } @static_dirs; + + enable 'Log4perl', category => 'Plack'; + + enable 'Static', + path => sub { s{^/(?:static/v\d+\.\d+/)?($static_paths)/}{$1/}gs }, + root => Bugzilla::Constants::bz_locations->{cgi_path}; + + my @scripts = glob('*.cgi'); + + my %mount; + + foreach my $script (@scripts) { + my $name = basename($script); + $mount{$name} = compile_cgi($script); + } + + Bugzilla::Hook::process('psgi_builder', { mount => \%mount }); + + foreach my $name ( keys %mount ) { + mount "/$name" => $mount{$name}; + } + + # so mount / => $app will make *all* files redirect to the index. + # instead we use an inline middleware to rewrite / to /index.cgi + enable sub { + my $app = shift; + return sub { + my $env = shift; + $env->{PATH_INFO} = '/index.cgi' if $env->{PATH_INFO} eq '/'; + return $app->($env); + }; + }; + + mount '/robots.txt' => $mount{'robots.cgi'}; + mount '/rest' => $mount{'rest.cgi'}; + +}; + +unless (caller) { + require Plack::Runner; + my $runner = Plack::Runner->new; + $runner->parse_options(@ARGV); + $runner->run($bugzilla_app); + exit 0; +} + +return $bugzilla_app; diff --git a/buglist.cgi b/buglist.cgi index 019bf0d4e..d1cde7096 100755 --- a/buglist.cgi +++ b/buglist.cgi @@ -1103,4 +1103,4 @@ $cgi->close_standby_message($contenttype, $disposition, $disp_prefix, $format->{ # Generate and return the UI (HTML page) from the appropriate template. $template->process($format->{'template'}, $vars) - || ThrowTemplateError($template->error());
\ No newline at end of file + || ThrowTemplateError($template->error()); diff --git a/docs/en/rst/integrating/templates.rst b/docs/en/rst/integrating/templates.rst index b477a9553..ee2c08e92 100644 --- a/docs/en/rst/integrating/templates.rst +++ b/docs/en/rst/integrating/templates.rst @@ -262,7 +262,7 @@ customizing for your installation. It needs a couple of lines of boilerplate at the top like this:: [% USE Bugzilla %] - [% cgi = Bugzilla.cgi % + [% cgi = Bugzilla.cgi %] Then, this template can reference the form fields you have created using the syntax ``[% cgi.param("field_name") %]``. When a bug report is diff --git a/editusers.cgi b/editusers.cgi index d2ad3a82f..beb9b3a4c 100755 --- a/editusers.cgi +++ b/editusers.cgi @@ -32,8 +32,7 @@ my $dbh = Bugzilla->dbh; my $userid = $user->id; my $editusers = $user->in_group('editusers'); my $disableusers = $user->in_group('disableusers'); - -local our $vars = {}; +local our $vars = {}; # Reject access if there is no sense in continuing. $editusers diff --git a/enter_bug.cgi b/enter_bug.cgi index 33cdf8535..5b8a97dba 100755 --- a/enter_bug.cgi +++ b/enter_bug.cgi @@ -37,6 +37,8 @@ use Bugzilla::Field; use Bugzilla::Status; use Bugzilla::UserAgent; +use List::Util qw(any); + my $user = Bugzilla->login(LOGIN_REQUIRED); my $cloned_bug; @@ -299,8 +301,13 @@ else { $default{'bug_severity'} = formvalue('bug_severity', Bugzilla->params->{'defaultseverity'}); # BMO - use per-product default hw/os - $default{'rep_platform'} = formvalue('rep_platform', $product->default_platform // detect_platform()); - $default{'op_sys'} = formvalue('op_sys', $product->default_op_sys // detect_op_sys()); + if (any { $_->NAME eq 'BMO' } @{ Bugzilla->extensions }) { + $default{'rep_platform'} = formvalue('rep_platform', $product->default_platform // detect_platform()); + $default{'op_sys'} = formvalue('op_sys', $product->default_op_sys // detect_op_sys()); + } else { + $default{'rep_platform'} = formvalue('rep_platform', detect_platform()); + $default{'op_sys'} = formvalue('op_sys', detect_op_sys()); + } $vars->{'rep_platform'} = detect_platform(); $vars->{'rep_op_sys'} = detect_op_sys(); diff --git a/errors/401.html b/errors/401.html deleted file mode 100644 index 8242b549f..000000000 --- a/errors/401.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <title>Access Denied</title> - <style> - body { - margin: 1em 2em; - background-color: #455372; - color: #ddd; - font-family: sans-serif; - } - h1, h3 { - color: #fff; - } - a { - color: #fff; - text-decoration: none; - } - #buggie { - float: left; - } - #content { - margin-left: 100px; - padding-top: 20px; - } - </style> - </head> - <body> - <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215"> - <div id="content"> - <h1>Authentication Required</h1> - <p>This server could not verify that you are authorized to access - that url. you either supplied the wrong credentials (e.g., bad - password), or your browser doesn't understand how to supply the - credentials required.</p> - <h3>Error 401</h3> - <p><a href="/">bugzilla.mozilla.org</a></p> - </div> - </body> -</html> diff --git a/errors/403.html b/errors/403.html deleted file mode 100644 index e2faf8522..000000000 --- a/errors/403.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <title>Access Denied</title> - <style> - body { - margin: 1em 2em; - background-color: #455372; - color: #ddd; - font-family: sans-serif; - } - h1, h3 { - color: #fff; - } - a { - color: #fff; - text-decoration: none; - } - #buggie { - float: left; - } - #content { - margin-left: 100px; - padding-top: 20px; - } - </style> - </head> - <body> - <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215"> - <div id="content"> - <h1>Access Denied</h1> - <p>Access to the requested resource has been denied.</p> - <h3>Error 403</h3> - <p><a href="/">bugzilla.mozilla.org</a></p> - </div> - </body> -</html> diff --git a/errors/404.html b/errors/404.html deleted file mode 100644 index 3b476471c..000000000 --- a/errors/404.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <title>Object Not Found</title> - <style> - body { - margin: 1em 2em; - background-color: #455372; - color: #ddd; - font-family: sans-serif; - } - h1, h3 { - color: #fff; - } - a { - color: #fff; - text-decoration: none; - } - #buggie { - float: left; - } - #content { - margin-left: 100px; - padding-top: 20px; - } - </style> - </head> - <body> - <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215"> - <div id="content"> - <h1>Object Not Found</h1> - <p>The requested URL was not found on this server.</p> - <h3>Error 404</h3> - <p><a href="/">bugzilla.mozilla.org</a></p> - </div> - </body> -</html> diff --git a/errors/500.html b/errors/500.html deleted file mode 100644 index e0657001d..000000000 --- a/errors/500.html +++ /dev/null @@ -1,37 +0,0 @@ -<!DOCTYPE HTML> -<html> - <head> - <title>Internal Server Error</title> - <style> - body { - margin: 1em 2em; - background-color: #455372; - color: #ddd; - font-family: sans-serif; - } - h1, h3 { - color: #fff; - } - a { - color: #fff; - text-decoration: none; - } - #buggie { - float: left; - } - #content { - margin-left: 100px; - padding-top: 20px; - } - </style> - </head> - <body> - <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215"> - <div id="content"> - <h1>Internal Server Error</h1> - <p>The server encountered an internal error and was unable to complete your request.</p> - <h3>Error 500</h3> - <p><a href="/">bugzilla.mozilla.org</a></p> - </div> - </body> -</html> diff --git a/extensions/AntiSpam/lib/Config.pm b/extensions/AntiSpam/lib/Config.pm index e35a7f001..278baea8f 100644 --- a/extensions/AntiSpam/lib/Config.pm +++ b/extensions/AntiSpam/lib/Config.pm @@ -55,7 +55,7 @@ sub get_param_list { "This account has been automatically disabled as a result of " . "a high number of comments tagged as abusive.<br>\n<br>\n" . "All interactions on Bugzilla should follow our " . - "<a href=\"https://bugzilla.mozilla.org/page.cgi?id=etiquette.html\">" . + "<a href=\"" . Bugzilla->localconfig->{'urlbase'} . "page.cgi?id=etiquette.html\">" . "etiquette guidelines</a>.<br>\n<br>\n" . "Please contact the address at the end of this message if you " . "believe this to be an error, or if you would like your account " . diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm index 102b71068..743d03099 100644 --- a/extensions/BMO/Extension.pm +++ b/extensions/BMO/Extension.pm @@ -46,6 +46,7 @@ use Bugzilla::User; use Bugzilla::UserAgent qw(detect_platform detect_op_sys); use Bugzilla::User::Setting; use Bugzilla::Util; +use Bugzilla::PSGI qw(compile_cgi); use Date::Parse; use DateTime; @@ -878,7 +879,7 @@ sub object_end_of_create { # Add default searches to new user's footer my $dbh = Bugzilla->dbh; - my $sharer = Bugzilla::User->new({ name => 'nobody@mozilla.org' }) + my $sharer = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} }) or return; my $group = Bugzilla::Group->new({ name => 'everyone' }) or return; @@ -919,7 +920,7 @@ sub _bug_reporters_hw_os { sub _bug_is_unassigned { my ($self) = @_; my $assignee = $self->assigned_to->login; - return $assignee eq 'nobody@mozilla.org' || $assignee =~ /\.bugs$/; + return $assignee eq Bugzilla->params->{'nobody_user'} || $assignee =~ /\.bugs$/; } sub _bug_has_current_patch { @@ -1100,7 +1101,7 @@ sub object_start_of_update { # and the assignee isn't a real person return unless - $new_bug->assigned_to->login eq 'nobody@mozilla.org' + $new_bug->assigned_to->login eq Bugzilla->params->{'nobody_user'} || $new_bug->assigned_to->login =~ /\.bugs$/; # and the user can set the status to NEW @@ -1595,7 +1596,7 @@ sub field_end_of_create { my $name = $field->name; if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) { - Bugzilla->set_user(Bugzilla::User->check({ name => 'nobody@mozilla.org' })); + Bugzilla->set_user(Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} })); print "Creating IT permission grant bug for new field '$name'..."; } @@ -1666,6 +1667,28 @@ sub webservice { $dispatch->{BMO} = "Bugzilla::Extension::BMO::WebService"; } +sub psgi_builder { + my ($self, $args) = @_; + my $mount = $args->{mount}; + + my $ses_index = Plack::Builder::builder(sub { + my $auth_user = Bugzilla->localconfig->{ses_username}; + my $auth_pass = Bugzilla->localconfig->{ses_password}; + Plack::Builder::enable("Auth::Basic", authenticator => sub { + my ($username, $password, $env) = @_; + return ( $auth_user + && $auth_pass + && $username + && $password + && $username eq $auth_user + && $password eq $auth_pass ); + }); + compile_cgi("ses/index.cgi"); + }); + + $mount->{'ses/index.cgi'} = $ses_index; +} + our $search_content_matches; BEGIN { $search_content_matches = \&Bugzilla::Search::_content_matches; @@ -1951,7 +1974,7 @@ sub _post_employee_incident_bug { my ($investigate_bug, $ssh_key_bug); my $old_user = Bugzilla->user; eval { - Bugzilla->set_user(Bugzilla::User->new({ name => 'nobody@mozilla.org' })); + Bugzilla->set_user(Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} })); my $new_user = Bugzilla->user; # HACK: User needs to be in the editbugs and primary bug's group to allow diff --git a/extensions/BMO/bin/bug_1093952.pl b/extensions/BMO/bin/bug_1093952.pl index 735c6a37a..fd891f4ae 100755 --- a/extensions/BMO/bin/bug_1093952.pl +++ b/extensions/BMO/bin/bug_1093952.pl @@ -52,7 +52,7 @@ printf "About to fix %s bugs\n", scalar(@$bugs); print "Press <Ctrl-C> to stop or <Enter> to continue...\n"; getc(); -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }); my $field = Bugzilla::Field->check({ name => 'status_whiteboard' }); my $when = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); diff --git a/extensions/BMO/bin/bug_1141452.pl b/extensions/BMO/bin/bug_1141452.pl index 869593802..155c4704c 100755 --- a/extensions/BMO/bin/bug_1141452.pl +++ b/extensions/BMO/bin/bug_1141452.pl @@ -50,7 +50,7 @@ printf "About to fix %s bugs\n", scalar(@$flags); print "Press <Ctrl-C> to stop or <Enter> to continue...\n"; getc(); -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }); my $when = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); $dbh->bz_start_transaction(); diff --git a/extensions/BMO/bin/migrate-github-pull-requests.pl b/extensions/BMO/bin/migrate-github-pull-requests.pl index 53c1727b5..c39778a4a 100755 --- a/extensions/BMO/bin/migrate-github-pull-requests.pl +++ b/extensions/BMO/bin/migrate-github-pull-requests.pl @@ -23,7 +23,7 @@ use Bugzilla::User; use Bugzilla::Util qw(trim); my $dbh = Bugzilla->dbh; -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }); my $field = Bugzilla::Field->check({ name => 'attachments.mimetype' }); # grab list of suitable attachments diff --git a/extensions/BMO/disabled b/extensions/BMO/disabled new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/extensions/BMO/disabled diff --git a/extensions/BMO/lib/WebService.pm b/extensions/BMO/lib/WebService.pm index 327c8563f..b9d8e4132 100644 --- a/extensions/BMO/lib/WebService.pm +++ b/extensions/BMO/lib/WebService.pm @@ -116,7 +116,7 @@ Bugzilla::Extension::BMO::Webservice - The BMO WebServices API =head1 DESCRIPTION -This module contains API methods that are useful to user's of bugzilla.mozilla.org. +This module contains API methods that are useful to users of bugzilla.mozilla.org. =head1 METHODS diff --git a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl index 697542ead..0bd1c94d7 100644 --- a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl @@ -297,7 +297,7 @@ function validate_form() { <input type="hidden" name="version" value="unspecified"> <input type="hidden" name="bug_severity" value="normal"> <input type="hidden" name="group" value="pr-private"> -<input type="hidden" name="assigned_to" id="assigned_to" value="nobody@mozilla.org"> +<input type="hidden" name="assigned_to" id="assigned_to" value="[% Param('nobody_user') FILTER html %]"> <input type="hidden" name="token" value="[% token FILTER html %]"> <div class="head"> diff --git a/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl index d6243c73b..9c0c4780d 100644 --- a/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl @@ -43,7 +43,7 @@ please provide some information about your application or product.</p> <input type="hidden" name="priority" value="--"> <input type="hidden" name="op_sys" value="Other"> <input type="hidden" name="version" value="unspecified"> - <input type="hidden" name="assigned_to" value="nobody@mozilla.org"> + <input type="hidden" name="assigned_to" value="[% Param('nobody_user') FILTER html %]"> <input type="hidden" name="cc" value="liz@mozilla.com"> <input type="hidden" name="groups" value="marketing-private"> <input type="hidden" name="token" value="[% token FILTER html %]"> diff --git a/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl index 92517cb80..803f2a746 100644 --- a/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl @@ -88,7 +88,7 @@ function validateAndSubmit() { <input type="hidden" name="token" value="[% token FILTER html %]"> <div class="head_desc"> - <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines"> + <a href="[% terms.BugWritingGuidelinesURL %]"> [% terms.Bug %] writing guidelines</a> </div> diff --git a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl index 6ecd0bc75..d3c7412bf 100644 --- a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl +++ b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl @@ -17,7 +17,7 @@ [% END +%] [% UNLESS no_bug_guidelines %] Before reporting a [% terms.bug %], make sure you've read our - <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines"> + <a href="[% terms.BugWritingGuidelinesURL %]"> [% terms.bug %] writing guidelines</a> and double checked that your [% terms.bug %] hasn't already been reported. Consult our list of <a href="https://bugzilla.mozilla.org/duplicates.cgi"> most frequently reported [% terms.bugs %]</a> and <a href="https://bugzilla.mozilla.org/query.cgi"> diff --git a/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl b/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl index e1c67605f..dc253ee03 100644 --- a/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl +++ b/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl @@ -7,5 +7,5 @@ #%] [% PROCESS global/redirect.html.tmpl - url = "https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines" + url = terms.BugWritingGuidelinesURL %] diff --git a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl index 45dd5bd65..fe7d2cd3d 100644 --- a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl +++ b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl @@ -173,7 +173,7 @@ <h2>See Also</h2> <p> - <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">The [% terms.Bug %] Writing Guidelines</a>. + <a href="[% terms.BugWritingGuidelinesURL %]">The [% terms.Bug %] Writing Guidelines</a>. </p> [% INCLUDE global/footer.html.tmpl %] diff --git a/extensions/BMO/template/en/default/pages/group_admins.html.tmpl b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl index cfa3bd3ea..838a1e84a 100644 --- a/extensions/BMO/template/en/default/pages/group_admins.html.tmpl +++ b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl @@ -39,7 +39,7 @@ [% group.name FILTER html %]</span> </td> <td nowrap> - [% IF group.owner.login == 'nobody@mozilla.org' %] + [% IF group.owner.login == Param('nobody_user') %] – [% ELSE %] [% INCLUDE global/user.html.tmpl who = group.owner %] diff --git a/extensions/BugModal/Extension.pm b/extensions/BugModal/Extension.pm index 1291fca21..ef9c93a37 100644 --- a/extensions/BugModal/Extension.pm +++ b/extensions/BugModal/Extension.pm @@ -188,10 +188,12 @@ sub template_before_process { return if exists $bug->{error}; # trigger loading of tracking flags - Bugzilla::Extension::TrackingFlags->template_before_process({ - file => 'bug/edit.html.tmpl', - vars => $vars, - }); + if (Bugzilla->has_extension('TrackingFlags')) { + Bugzilla::Extension::TrackingFlags->template_before_process({ + file => 'bug/edit.html.tmpl', + vars => $vars, + }); + } if (any { $bug->product eq $_ } READABLE_BUG_STATUS_PRODUCTS) { my @flags = map { { name => $_->name, status => $_->status } } @{$bug->flags}; diff --git a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl index 47044e232..5d38d8340 100644 --- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl +++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl @@ -19,7 +19,7 @@ # these are used in a few places is_cced = bug.cc.contains(user.login); - unassigned = (bug.assigned_to.login == "nobody@mozilla.org") + unassigned = (bug.assigned_to.login == Param('nobody_user')) || (bug.assigned_to.login.search('\.bugs$')); # custom fields that have custom rendering, or should not be rendered diff --git a/extensions/BzAPI/Extension.pm b/extensions/BzAPI/Extension.pm index bb9805134..1f7cce04a 100644 --- a/extensions/BzAPI/Extension.pm +++ b/extensions/BzAPI/Extension.pm @@ -15,6 +15,7 @@ use base qw(Bugzilla::Extension); use Bugzilla::Extension::BzAPI::Constants; use Bugzilla::Extension::BzAPI::Util qw(fix_credentials filter_wants_nocache); +use Bugzilla::PSGI qw(compile_cgi); use Bugzilla::Error; use Bugzilla::Util qw(trick_taint datetime_from); @@ -188,6 +189,14 @@ sub webservice_status_code_map { $status_code_map->{51} = STATUS_BAD_REQUEST; } +sub psgi_builder { + my ($self, $args) = @_; + my $mount = $args->{mount}; + + $mount->{'bzapi'} = compile_cgi('extensions/BzAPI/bin/rest.cgi'); +} + + ##################### # Utility Functions # ##################### diff --git a/extensions/ComponentWatching/Extension.pm b/extensions/ComponentWatching/Extension.pm index 674e0da7b..96eb877a6 100644 --- a/extensions/ComponentWatching/Extension.pm +++ b/extensions/ComponentWatching/Extension.pm @@ -23,7 +23,7 @@ use Bugzilla::Util qw(detaint_natural trim trick_taint); our $VERSION = '2'; use constant REQUIRE_WATCH_USER => 1; -use constant DEFAULT_ASSIGNEE => 'nobody@mozilla.org'; +use constant DEFAULT_ASSIGNEE => Bugzilla->params->{'nobody_user'}; use constant REL_COMPONENT_WATCHER => 15; @@ -158,7 +158,9 @@ sub object_columns { my $columns = $args->{columns}; return unless $class->isa('Bugzilla::Component'); - push(@$columns, 'watch_user'); + if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'watch_user')) { + push @$columns, 'watch_user'; + } } sub object_update_columns { diff --git a/extensions/ContributorEngagement/Extension.pm b/extensions/ContributorEngagement/Extension.pm index 949517ecf..35eba24ab 100644 --- a/extensions/ContributorEngagement/Extension.pm +++ b/extensions/ContributorEngagement/Extension.pm @@ -70,7 +70,10 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::User')) { - push(@$columns, 'first_patch_reviewed_id'); + my $dbh = Bugzilla->dbh; + if ($dbh->bz_column_info($class->DB_TABLE, 'first_patch_reviewed_id')) { + push @$columns, 'first_patch_reviewed_id'; + } } } diff --git a/extensions/EditComments/Extension.pm b/extensions/EditComments/Extension.pm index ab19ab6e7..e2ace3f23 100644 --- a/extensions/EditComments/Extension.pm +++ b/extensions/EditComments/Extension.pm @@ -191,7 +191,9 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::Comment')) { - push(@$columns, 'edit_count'); + if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'edit_count')) { + push @$columns, 'edit_count'; + } } } diff --git a/extensions/EditComments/lib/WebService.pm b/extensions/EditComments/lib/WebService.pm index 6969ca742..5fdd6ffee 100644 --- a/extensions/EditComments/lib/WebService.pm +++ b/extensions/EditComments/lib/WebService.pm @@ -88,7 +88,7 @@ Bugzilla::Extension::EditComments::Webservice - The EditComments WebServices API =head1 DESCRIPTION -This module contains API methods that are useful to user's of bugzilla.mozilla.org. +This module contains API methods that are useful to users of bugzilla.mozilla.org. =head1 METHODS diff --git a/extensions/Ember/lib/WebService.pm b/extensions/Ember/lib/WebService.pm index 10c828537..2e00773f2 100644 --- a/extensions/Ember/lib/WebService.pm +++ b/extensions/Ember/lib/WebService.pm @@ -781,7 +781,7 @@ Bugzilla::Extension::Ember::Webservice - The BMO Ember WebServices API =head1 DESCRIPTION -This module contains API methods that are useful to user's of the Bugzilla Ember +This module contains API methods that are useful to users of the Bugzilla Ember based UI. =head1 METHODS diff --git a/extensions/FlagTypeComment/Extension.pm b/extensions/FlagTypeComment/Extension.pm index 3ec506176..e7b34113d 100644 --- a/extensions/FlagTypeComment/Extension.pm +++ b/extensions/FlagTypeComment/Extension.pm @@ -127,13 +127,18 @@ sub _set_ftc_states { 'active_or_has_flags' => $bug->id, }); - my $types = join(',', map { $_->id } @$flag_types); - my $states = "'" . join("','", FLAGTYPE_COMMENT_STATES) . "'"; - $db_result = $dbh->selectall_arrayref( - "SELECT type_id AS flagtype, on_status AS state, comment AS text - FROM flagtype_comments - WHERE type_id IN ($types) AND on_status IN ($states)", - { Slice => {} }); + if (@$flag_types) { + my $types = join(',', map { $_->id } @$flag_types); + my $states = "'" . join("','", FLAGTYPE_COMMENT_STATES) . "'"; + $db_result = $dbh->selectall_arrayref( + "SELECT type_id AS flagtype, on_status AS state, comment AS text + FROM flagtype_comments + WHERE type_id IN ($types) AND on_status IN ($states)", + { Slice => {} }); + } + else { + $db_result = []; + } } foreach my $row (@$db_result) { diff --git a/extensions/GuidedBugEntry/disabled b/extensions/GuidedBugEntry/disabled new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/extensions/GuidedBugEntry/disabled diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl index e1a9e0bc5..7ffa04922 100644 --- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl +++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl @@ -356,7 +356,7 @@ Product: <b><span id="dupes_product_name">?</span></b>: <ul> <li>Please fill out this form clearly, precisely and in as much detail as you can manage.</li> <li>Please report only a single problem at a time.</li> -<li><a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines" target="_blank" rel="noopener noreferrer">These guidelines</a> +<li><a href="[% terms.BugWritingGuidelinesURL %]" target="_blank" rel="noopener noreferrer">These guidelines</a> explain how to write effective [% terms.bug %] reports.</li> </ul> diff --git a/extensions/MyDashboard/lib/WebService.pm b/extensions/MyDashboard/lib/WebService.pm index 5407c1d0b..5ab849350 100644 --- a/extensions/MyDashboard/lib/WebService.pm +++ b/extensions/MyDashboard/lib/WebService.pm @@ -172,7 +172,7 @@ Bugzilla::Extension::MyDashboard::Webservice - The MyDashboard WebServices API =head1 DESCRIPTION -This module contains API methods that are useful to user's of bugzilla.mozilla.org. +This module contains API methods that are useful to users of bugzilla.mozilla.org. =head1 METHODS diff --git a/extensions/PhabBugz/disabled b/extensions/PhabBugz/disabled new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/extensions/PhabBugz/disabled diff --git a/extensions/PhabBugz/lib/Util.pm b/extensions/PhabBugz/lib/Util.pm index 5dbe31d0e..5ad8a5207 100644 --- a/extensions/PhabBugz/lib/Util.pm +++ b/extensions/PhabBugz/lib/Util.pm @@ -107,7 +107,7 @@ sub get_bug_role_phids { my @bug_users = ( $bug->reporter ); push(@bug_users, $bug->assigned_to) - if $bug->assigned_to->email !~ /^nobody\@mozilla\.org$/; + if $bug->assigned_to->email != Bugzilla->params->{'nobody_user'}; push(@bug_users, $bug->qa_contact) if $bug->qa_contact; push(@bug_users, @{ $bug->cc_users }) if @{ $bug->cc_users }; diff --git a/extensions/Push/Config.pm b/extensions/Push/Config.pm index 860e31a23..59b78d5a2 100644 --- a/extensions/Push/Config.pm +++ b/extensions/Push/Config.pm @@ -42,12 +42,6 @@ use constant REQUIRED_MODULES => [ ]; use constant OPTIONAL_MODULES => [ - # connectors need the ability to extend this - { - package => 'Net-SFTP', - module => 'Net::SFTP', - version => '0' - }, { package => 'XML-Simple', module => 'XML::Simple', diff --git a/extensions/Push/disabled b/extensions/Push/disabled new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/extensions/Push/disabled diff --git a/extensions/Push/lib/Connector/TCL.pm b/extensions/Push/lib/Connector/TCL.pm deleted file mode 100644 index f5b430e47..000000000 --- a/extensions/Push/lib/Connector/TCL.pm +++ /dev/null @@ -1,353 +0,0 @@ -# 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. - -package Bugzilla::Extension::Push::Connector::TCL; - -use 5.10.1; -use strict; -use warnings; - -use base 'Bugzilla::Extension::Push::Connector::Base'; - -use Bugzilla::Constants; -use Bugzilla::Extension::Push::Constants; -use Bugzilla::Extension::Push::Serialise; -use Bugzilla::Extension::Push::Util; -use Bugzilla::User; -use Bugzilla::Attachment; - -use Digest::MD5 qw(md5_hex); -use Encode qw(encode_utf8); - -sub options { - return ( - { - name => 'tcl_user', - label => 'Bugzilla TCL User', - type => 'string', - default => 'tcl@bugzilla.tld', - required => 1, - validate => sub { - Bugzilla::User->new({ name => $_[0] }) - || die "Invalid Bugzilla user ($_[0])\n"; - }, - }, - { - name => 'sftp_host', - label => 'SFTP Host', - type => 'string', - default => '', - required => 1, - }, - { - name => 'sftp_port', - label => 'SFTP Port', - type => 'string', - default => '22', - required => 1, - validate => sub { - $_[0] =~ /\D/ && die "SFTP Port must be an integer\n"; - }, - }, - { - name => 'sftp_user', - label => 'SFTP Username', - type => 'string', - default => '', - required => 1, - }, - { - name => 'sftp_pass', - label => 'SFTP Password', - type => 'password', - default => '', - required => 1, - }, - { - name => 'sftp_remote_path', - label => 'SFTP Remote Path', - type => 'string', - default => '', - required => 0, - }, - ); -} - -my $_instance; - -sub init { - my ($self) = @_; - $_instance = $self; -} - -sub load_config { - my ($self) = @_; - $self->SUPER::load_config(@_); -} - -sub should_send { - my ($self, $message) = @_; - - my $data = $message->payload_decoded; - my $bug_data = $self->_get_bug_data($data) - || return 0; - - # sanity check user - $self->{tcl_user} ||= Bugzilla::User->new({ name => $self->config->{tcl_user} }); - if (!$self->{tcl_user} || !$self->{tcl_user}->is_enabled) { - return 0; - } - - # only send bugs created by the tcl user - unless ($bug_data->{reporter}->{id} == $self->{tcl_user}->id) { - return 0; - } - - # don't push changes made by the tcl user - if ($data->{event}->{user}->{id} == $self->{tcl_user}->id) { - return 0; - } - - # send comments - if ($data->{event}->{routing_key} eq 'comment.create') { - return 0 if $data->{comment}->{is_private}; - return 1; - } - - # send status and resolution updates - foreach my $change (@{ $data->{event}->{changes} }) { - return 1 if $change->{field} eq 'bug_status' - || $change->{field} eq 'resolution' - || $change->{field} eq 'cf_blocking_b2g'; - } - - # send attachments - if ($data->{event}->{routing_key} =~ /^attachment\./) { - return 0 if $data->{attachment}->{is_private}; - return 1; - } - - # and nothing else - return 0; -} - -sub send { - my ($self, $message) = @_; - my $logger = Bugzilla->push_ext->logger; - my $config = $self->config; - - require XML::Simple; - require Net::SFTP; - - $self->{tcl_user} ||= Bugzilla::User->new({ name => $self->config->{tcl_user} }); - if (!$self->{tcl_user}) { - return (PUSH_RESULT_TRANSIENT, "Invalid bugzilla-user (" . $self->config->{tcl_user} . ")"); - } - - # load the bug - my $data = $message->payload_decoded; - my $bug_data = $self->_get_bug_data($data); - - # build payload - my $attachment; - my %xml = ( - Mozilla_ID => $bug_data->{id}, - When => $data->{event}->{time}, - Who => $data->{event}->{user}->{login}, - Status => $bug_data->{status}->{name}, - Resolution => $bug_data->{resolution}, - Blocking_B2G => $bug_data->{cf_blocking_b2g}, - ); - if ($data->{event}->{routing_key} eq 'comment.create') { - $xml{Comment} = $data->{comment}->{body}; - } elsif ($data->{event}->{routing_key} =~ /^attachment\.(\w+)/) { - my $is_update = $1 eq 'modify'; - if (!$is_update) { - $attachment = Bugzilla::Attachment->new($data->{attachment}->{id}); - } - $xml{Attach} = { - Attach_ID => $data->{attachment}->{id}, - Filename => $data->{attachment}->{file_name}, - Description => $data->{attachment}->{description}, - ContentType => $data->{attachment}->{content_type}, - IsPatch => $data->{attachment}->{is_patch} ? 'true' : 'false', - IsObsolete => $data->{attachment}->{is_obsolete} ? 'true' : 'false', - IsUpdate => $is_update ? 'true' : 'false', - }; - } - - # convert to xml - my $xml = XML::Simple::XMLout( - \%xml, - NoAttr => 1, - RootName => 'sync', - XMLDecl => 1, - ); - $xml = encode_utf8($xml); - - # generate md5 - my $md5 = md5_hex($xml); - - # build filename - my ($sec, $min, $hour, $day, $mon, $year) = localtime(time); - my $change_set = $data->{event}->{change_set}; - $change_set =~ s/\.//g; - my $filename = sprintf( - '%04s%02d%02d%02d%02d%02d%s', - $year + 1900, - $mon + 1, - $day, - $hour, - $min, - $sec, - $change_set, - ); - - # create temp files; - my $temp_dir = File::Temp::Directory->new(); - my $local_dir = $temp_dir->dirname; - _write_file("$local_dir/$filename.sync", $xml); - _write_file("$local_dir/$filename.sync.check", $md5); - _write_file("$local_dir/$filename.done", ''); - if ($attachment) { - _write_file("$local_dir/$filename.sync.attach", $attachment->data); - } - - my $remote_dir = $self->config->{sftp_remote_path} eq '' - ? '' - : $self->config->{sftp_remote_path} . '/'; - - # send files via sftp - $logger->debug("Connecting to " . $self->config->{sftp_host} . ":" . $self->config->{sftp_port}); - my $sftp = Net::SFTP->new( - $self->config->{sftp_host}, - ssh_args => { - port => $self->config->{sftp_port}, - }, - user => $self->config->{sftp_user}, - password => $self->config->{sftp_pass}, - ); - - $logger->debug("Uploading $local_dir/$filename.sync"); - $sftp->put("$local_dir/$filename.sync", "$remote_dir$filename.sync") - or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync"); - - $logger->debug("Uploading $local_dir/$filename.sync.check"); - $sftp->put("$local_dir/$filename.sync.check", "$remote_dir$filename.sync.check") - or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync.check"); - - if ($attachment) { - $logger->debug("Uploading $local_dir/$filename.sync.attach"); - $sftp->put("$local_dir/$filename.sync.attach", "$remote_dir$filename.sync.attach") - or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync.attach"); - } - - $logger->debug("Uploading $local_dir/$filename.done"); - $sftp->put("$local_dir/$filename.done", "$remote_dir$filename.done") - or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.done"); - - # success - return (PUSH_RESULT_OK, "uploaded $filename.sync"); -} - -sub _get_bug_data { - my ($self, $data) = @_; - my $target = $data->{event}->{target}; - if ($target eq 'bug') { - return $data->{bug}; - } elsif (exists $data->{$target}->{bug}) { - return $data->{$target}->{bug}; - } else { - return; - } -} - -sub _write_file { - my ($filename, $content) = @_; - open(my $fh, ">", $filename) or die "Failed to write to $filename: $!\n"; - binmode($fh); - print $fh $content; - close($fh) or die "Failed to write to $filename: $!\n"; -} - -1; - -# File::Temp->newdir() requires a newer version of File::Temp than we have on -# production, so here's a small inline package which performs the same task. - -package File::Temp::Directory; - -use strict; -use warnings; - -use File::Temp; -use File::Path qw(rmtree); -use File::Spec; - -my @chars; - -sub new { - my ($class) = @_; - my $self = {}; - bless($self, $class); - - @chars = qw/ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z - a b c d e f g h i j k l m n o p q r s t u v w x y z - 0 1 2 3 4 5 6 7 8 9 _ - /; - - $self->{TEMPLATE} = File::Spec->catdir(File::Spec->tmpdir, 'X' x 10); - $self->{DIRNAME} = $self->_mktemp(); - return $self; -} - -sub _mktemp { - my ($self) = @_; - my $path = $self->_random_name(); - while(1) { - if (mkdir($path, 0700)) { - # in case of odd umask - chmod(0700, $path); - return $path; - } else { - # abort with error if the reason for failure was anything except eexist - die "Could not create directory $path: $!\n" unless ($!{EEXIST}); - # loop round for another try - } - $path = $self->_random_name(); - } - - return $path; -} - -sub _random_name { - my ($self) = @_; - my $path = $self->{TEMPLATE}; - $path =~ s/X/$chars[int(rand(@chars))]/ge; - return $path; -} - -sub dirname { - my ($self) = @_; - return $self->{DIRNAME}; -} - -sub DESTROY { - my ($self) = @_; - local($., $@, $!, $^E, $?); - if (-d $self->{DIRNAME}) { - # Some versions of rmtree will abort if you attempt to remove the - # directory you are sitting in. We protect that and turn it into a - # warning. We do this because this occurs during object destruction and - # so can not be caught by the user. - eval { rmtree($self->{DIRNAME}, 0, 0); }; - warn $@ if ($@ && $^W); - } -} - -1; - diff --git a/extensions/RestrictComments/Extension.pm b/extensions/RestrictComments/Extension.pm index 213a1c44a..e93540d5a 100644 --- a/extensions/RestrictComments/Extension.pm +++ b/extensions/RestrictComments/Extension.pm @@ -68,7 +68,9 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::Bug')) { - push(@$columns, 'restrict_comments'); + if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'restrict_comments')) { + push @$columns, 'restrict_comments'; + } } } diff --git a/extensions/Review/Extension.pm b/extensions/Review/Extension.pm index 406c29c7c..a918a5ca5 100644 --- a/extensions/Review/Extension.pm +++ b/extensions/Review/Extension.pm @@ -286,10 +286,14 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::Product')) { - push @$columns, 'reviewer_required'; + my $dbh = Bugzilla->dbh; + my @new_columns = qw(reviewer_required); + push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; } elsif ($class->isa('Bugzilla::User')) { - push @$columns, qw(review_request_count feedback_request_count needinfo_request_count); + my $dbh = Bugzilla->dbh; + my @new_columns = qw(review_request_count feedback_request_count needinfo_request_count); + push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; } } diff --git a/extensions/Review/bin/migrate_mentor_from_whiteboard.pl b/extensions/Review/bin/migrate_mentor_from_whiteboard.pl index c6b69006f..debf173a7 100755 --- a/extensions/Review/bin/migrate_mentor_from_whiteboard.pl +++ b/extensions/Review/bin/migrate_mentor_from_whiteboard.pl @@ -36,7 +36,7 @@ EOF <>; # we need to be logged in to do user searching and update bugs -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }); $nobody->{groups} = [ Bugzilla::Group->get_all ]; Bugzilla->set_user($nobody); diff --git a/extensions/Review/lib/WebService.pm b/extensions/Review/lib/WebService.pm index 3f6816916..0c54d725a 100644 --- a/extensions/Review/lib/WebService.pm +++ b/extensions/Review/lib/WebService.pm @@ -51,7 +51,7 @@ sub suggestions { # we always need to be authentiated to perform user matching my $user = Bugzilla->user; if (!$user->id) { - Bugzilla->set_user(Bugzilla::User->check({ name => 'nobody@mozilla.org' })); + Bugzilla->set_user(Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} })); push @reviewers, @{ $bug->mentors }; Bugzilla->set_user($user); } else { diff --git a/extensions/SecureMail/Extension.pm b/extensions/SecureMail/Extension.pm index 508b1f5e8..2b5e1bdd6 100644 --- a/extensions/SecureMail/Extension.pm +++ b/extensions/SecureMail/Extension.pm @@ -104,7 +104,10 @@ sub object_columns { my $columns = $args->{'columns'}; if ($class->isa('Bugzilla::Group')) { - push(@$columns, 'secure_mail'); + my $dbh = Bugzilla->dbh; + if ($dbh->bz_column_info($class->DB_TABLE, 'secure_mail')) { + push @$columns, 'secure_mail'; + } } } diff --git a/extensions/TagNewUsers/Extension.pm b/extensions/TagNewUsers/Extension.pm index b94873979..1810f204f 100644 --- a/extensions/TagNewUsers/Extension.pm +++ b/extensions/TagNewUsers/Extension.pm @@ -123,7 +123,9 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::User')) { - push(@$columns, qw(comment_count creation_ts first_patch_bug_id)); + my $dbh = Bugzilla->dbh; + my @new_columns = qw(comment_count creation_ts first_patch_bug_id); + push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; } } @@ -131,9 +133,14 @@ sub object_before_create { my ($self, $args) = @_; my ($class, $params) = @$args{qw(class params)}; if ($class->isa('Bugzilla::User')) { - my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()"); - $params->{comment_count} = 0; - $params->{creation_ts} = $timestamp; + my $dbh = Bugzilla->dbh; + my ($timestamp) = $dbh->selectrow_array("SELECT NOW()"); + if ($dbh->bz_column_info($class->DB_TABLE, 'comment_count')) { + $params->{comment_count} = 0; + } + if ($dbh->bz_column_info($class->DB_TABLE, 'creation_ts')) { + $params->{creation_ts} = $timestamp; + } } elsif ($class->isa('Bugzilla::Attachment')) { if ($params->{ispatch} && !Bugzilla->user->first_patch_bug_id) { Bugzilla->user->first_patch_bug_id($params->{bug}->id); diff --git a/extensions/TrackingFlags/bin/bug_825946.pl b/extensions/TrackingFlags/bin/bug_825946.pl index 3f380b7ac..896dc5448 100755 --- a/extensions/TrackingFlags/bin/bug_825946.pl +++ b/extensions/TrackingFlags/bin/bug_825946.pl @@ -24,7 +24,7 @@ use Bugzilla::Bug qw(LogActivityEntry); Bugzilla->usage_mode(USAGE_MODE_CMDLINE); my $dbh = Bugzilla->dbh; -my $user = Bugzilla::User->check({name => 'nobody@mozilla.org'}); +my $user = Bugzilla::User->check({name => Bugzilla->params->{'nobody_user'}}); my $tf_vis = $dbh->selectall_arrayref(<<SQL); SELECT diff --git a/extensions/TrackingFlags/bin/bulk_flag_clear.pl b/extensions/TrackingFlags/bin/bulk_flag_clear.pl index 1745018d5..305fbf883 100755 --- a/extensions/TrackingFlags/bin/bulk_flag_clear.pl +++ b/extensions/TrackingFlags/bin/bulk_flag_clear.pl @@ -110,7 +110,7 @@ if (!$config->{update_db}) { # update bugs -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }); # put our nobody user into all groups to avoid permissions issues $nobody->{groups} = [Bugzilla::Group->get_all]; Bugzilla->set_user($nobody); diff --git a/extensions/TrackingFlags/disabled b/extensions/TrackingFlags/disabled new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/extensions/TrackingFlags/disabled diff --git a/extensions/UserProfile/Extension.pm b/extensions/UserProfile/Extension.pm index 079f7a948..9171b942d 100644 --- a/extensions/UserProfile/Extension.pm +++ b/extensions/UserProfile/Extension.pm @@ -385,7 +385,9 @@ sub object_columns { my ($self, $args) = @_; my ($class, $columns) = @$args{qw(class columns)}; if ($class->isa('Bugzilla::User')) { - push(@$columns, qw(last_activity_ts last_statistics_ts)); + my $dbh = Bugzilla->dbh; + my @new_columns = qw(last_activity_ts last_statistics_ts); + push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns; } } diff --git a/heartbeat.cgi b/heartbeat.cgi index 493674c16..11bb3ac30 100755 --- a/heartbeat.cgi +++ b/heartbeat.cgi @@ -44,4 +44,4 @@ FATAL("heartbeat error: $@") if !$ok && $@; my $cgi = Bugzilla->cgi; print $cgi->header(-type => 'text/plain', -status => $ok ? '200 OK' : '500 Internal Server Error'); -print $ok ? "Bugzilla OK\n" : "Bugzilla NOT OK\n";
\ No newline at end of file +print $ok ? "Bugzilla OK\n" : "Bugzilla NOT OK\n"; diff --git a/js/instant-search.js b/js/instant-search.js index 6e8f104f2..183d5a3be 100644 --- a/js/instant-search.js +++ b/js/instant-search.js @@ -138,7 +138,7 @@ YAHOO.bugzilla.instantSearch = { YAHOO.bugzilla.instantSearch.dataTable.showTableMessage( 'Searching... ' + - '<img src="extensions/GuidedBugEntry/web/images/throbber.gif"' + + '<img src="images/throbber.gif"' + ' width="16" height="11">', YAHOO.widget.DataTable.CLASS_LOADING ); @@ -191,7 +191,7 @@ YAHOO.bugzilla.instantSearch = { var result = []; var name = Dom.get('product').value; result.push(name); - if (products[name] && products[name].related) { + if (typeof products !== 'undefined' && products[name] && products[name].related) { for (var i = 0, n = products[name].related.length; i < n; i++) { result.push(products[name].related[i]); } diff --git a/scripts/eject-users-from-groups.pl b/scripts/eject-users-from-groups.pl index 52e2bbbf3..4b27be83d 100755 --- a/scripts/eject-users-from-groups.pl +++ b/scripts/eject-users-from-groups.pl @@ -23,7 +23,7 @@ Bugzilla->usage_mode(USAGE_MODE_CMDLINE); my $dbh = Bugzilla->dbh; my @remove_group_names; -my $nobody_name = 'nobody@mozilla.org'; +my $nobody_name = Bugzilla->params->{'nobody_user'}; my $admin_name = 'automation@bmo.tld'; GetOptions( diff --git a/scripts/entrypoint.pl b/scripts/entrypoint.pl index 21d9aebb1..f5c52f6a6 100755 --- a/scripts/entrypoint.pl +++ b/scripts/entrypoint.pl @@ -57,11 +57,6 @@ check_env(qw( BMO_urlbase )); -if ( $ENV{BMO_urlbase} eq 'AUTOMATIC' ) { - $ENV{BMO_urlbase} = sprintf 'http://%s:%d/%s', hostname(), $ENV{PORT}, $ENV{BZ_QA_LEGACY_MODE} ? 'bmo/' : ''; - $ENV{BZ_BASE_URL} = sprintf 'http://%s:%d', hostname(), $ENV{PORT}; -} - $func->($opts->()); sub cmd_demo { @@ -110,6 +105,11 @@ sub cmd_dev_httpd { exit $httpd_exit_f->get; } +sub cmd_checksetup_gen_files { + my (@args) = @_; + run( 'perl', 'checksetup.pl', '--no-database', @args); +} + sub cmd_checksetup { check_data_dir(); wait_for_db(); @@ -140,7 +140,7 @@ sub cmd_test_webservices { check_data_dir(); copy_qa_extension(); assert_database()->get; - my $httpd_exit_f = run_cereal_and_httpd('-DHTTPD_IN_SUBDIR', '-DACCESS_LOGS'); + my $httpd_exit_f = run_cereal_and_httpd('-DHTTPD_IN_SUBDIR'); my $prove_exit_f = run_prove( httpd_url => $conf->{browser_url}, prove_cmd => [ @@ -195,7 +195,7 @@ sub cmd_test_bmo { $ENV{BZ_TEST_NEWBIE2} = 'newbie2@mozilla.example'; $ENV{BZ_TEST_NEWBIE2_PASS} = 'captain.space.pants.time.lord'; - my $httpd_exit_f = run_cereal_and_httpd('-DACCESS_LOGS'); + my $httpd_exit_f = run_cereal_and_httpd(); my $prove_exit_f = run_prove( httpd_url => $ENV{BZ_BASE_URL}, prove_cmd => [ 'prove', '-I/app', '-I/app/local/lib/perl5', @prove_args ], @@ -244,6 +244,10 @@ sub copy_qa_extension { dircopy('/app/qa/extensions/QA', '/app/extensions/QA'); } +sub cmd_wait_for_db { + wait_for_db(); +} + sub wait_for_db { assert_database()->get; } diff --git a/scripts/generate_bmo_data.pl b/scripts/generate_bmo_data.pl index 6356762c8..8a9f72d17 100755 --- a/scripts/generate_bmo_data.pl +++ b/scripts/generate_bmo_data.pl @@ -158,7 +158,7 @@ $group->update(); my @users = ( { - login => 'nobody@mozilla.org', + login => Bugzilla->params->{'nobody_user'}, realname => 'Nobody; OK to take it and work on it', password => '*' }, @@ -267,7 +267,7 @@ my @products = ( name => 'General', description => 'For bugs in Firefox which do not fit into ' . 'other more specific Firefox components', - initialowner => 'nobody@mozilla.org', + initialowner => Bugzilla->params->{'nobody_user'}, initialqaowner => '', initial_cc => [], watch_user => 'general@firefox.bugs' @@ -287,7 +287,7 @@ my @products = ( name => 'General', description => 'This is the component for issues specific to bugzilla.mozilla.org ' . 'that do not belong in other components.', - initialowner => 'nobody@mozilla.org', + initialowner => Bugzilla->params->{'nobody_user'}, initialqaowner => '', initial_cc => [], watch_user => 'general@bugzilla.bugs' diff --git a/scripts/move_os.pl b/scripts/move_os.pl index 546b47c7e..963188261 100755 --- a/scripts/move_os.pl +++ b/scripts/move_os.pl @@ -40,7 +40,7 @@ my $dbh = Bugzilla->dbh; my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); my $bug_ids = $dbh->selectcol_arrayref(q{SELECT bug_id FROM bugs WHERE bugs.op_sys = ?}, undef, $from_os); my $field = Bugzilla::Field->check({ name => 'op_sys', cache => 1 }); -my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org', cache => 1 }); +my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'}, cache => 1 }); my $bug_count = @$bug_ids; if ($bug_count == 0) { diff --git a/scripts/movebugs.pl b/scripts/movebugs.pl index 2c643cdfb..55a43d943 100755 --- a/scripts/movebugs.pl +++ b/scripts/movebugs.pl @@ -73,10 +73,12 @@ my $component_field_id = $dbh->selectrow_array( $component_field_id or die "Can't find field ID for 'component' field\n"; +my $nobody = Bugzilla->params->{'nobody_user'}; my $user_id = $dbh->selectrow_array( - "SELECT userid FROM profiles WHERE login_name='nobody\@mozilla.org'"); + "SELECT userid FROM profiles WHERE login_name=?", + undef, $nobody); $user_id - or die "Can't find user ID for 'nobody\@mozilla.org'\n"; + or die "Can't find user ID for '$nobody'\n"; $dbh->bz_start_transaction(); diff --git a/scripts/nagios_blocker_checker.pl b/scripts/nagios_blocker_checker.pl index a02a1602a..01a7b7348 100755 --- a/scripts/nagios_blocker_checker.pl +++ b/scripts/nagios_blocker_checker.pl @@ -28,7 +28,7 @@ my $config = { assignee => '', product => '', component => '', - unassigned => 'nobody@mozilla.org', + unassigned => Bugzilla->params->{'nobody_user'}, # severities severity => 'major,critical,blocker', # time in hours to wait before paging/warning diff --git a/scripts/remove_idle_group_members.pl b/scripts/remove_idle_group_members.pl index 74e8658ff..e4ef88bc1 100755 --- a/scripts/remove_idle_group_members.pl +++ b/scripts/remove_idle_group_members.pl @@ -78,7 +78,7 @@ foreach my $group_id (keys %remove_data) { $dbh->bz_commit_transaction(); # nobody@mozilla.org cannot recieve email - next if $group->owner->login eq 'nobody@mozilla.org'; + next if $group->owner->login eq Bugzilla->params->{'nobody_user'}; _send_email($group, \@users_removed); } diff --git a/scripts/reset_default_user.pl b/scripts/reset_default_user.pl index d0d2534f2..942afda17 100755 --- a/scripts/reset_default_user.pl +++ b/scripts/reset_default_user.pl @@ -52,7 +52,7 @@ if (!$product || $help } # We will need these for entering into bugs_activity -my $who = Bugzilla::User->new({ name => 'nobody@mozilla.org' }); +my $who = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} }); my $field = Bugzilla::Field->new({ name => $field_name }); trick_taint($product); diff --git a/scripts/rewrite2mojo.pl b/scripts/rewrite2mojo.pl new file mode 100755 index 000000000..bae6d514b --- /dev/null +++ b/scripts/rewrite2mojo.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl +# 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 5.10.1; +use strict; +use warnings; +use Mojo::Parameters; +use Data::Dumper; + +while (<>) { + my ($cmd, @args) = split /\s+/, $_; + next unless $cmd; + if (lc($cmd) eq "\LRewriteRule") { + my ($regex, $target, $flags) = @args; + $flags //= ''; + next if $flags =~ /E=HTTP/; + next if $target eq '-'; + my $action = 'rewrite_query'; + if ($flags =~ /R/) { + next; + } + my ($script, $query) = $target =~ /^([^?]+)(?:\?(.+))?$/; + my $name = _file_to_method($script); + $regex =~ s/^\^//; + $regex =~ s/\$$//; + my $regex_name = _regex_to_name($regex); + my $param_hash = Mojo::Parameters->new($query)->to_hash; + my $param_str = Data::Dumper->new([$param_hash])->Terse(1)->Indent(0)->Dump; + say "\$r->any('/:$regex_name' => [$regex_name => qr{$regex}])->to("; + say " 'CGI#$name' => $param_str"; + say ");"; + + } + # elsif (lc($cmd) eq "\LRedirect") { + # my ($type, $path, $url) = @args; + # if ($type eq 'permanent') { + # say "if (\$path =~ m{^\Q$path\E}s) {"; + # say " redirect(\$c, q{$url});"; + # say " return;"; + # say "}"; + # } + # else { + # warn "I don't understand Redirect $type\n"; + # } + # } +} + +sub _file_to_method { + my ($name) = @_; + $name =~ s/\./_/s; + $name =~ s/\W+/_/gs; + return $name; +} + +sub _regex_to_name { + my ($name) = @_; + $name =~ s/\./_/s; + $name =~ s/\W+/_/gs; + $name =~ s/_+/_/g; + $name =~ s/^_//s; + $name =~ s/_$//s; + return $name; +} + + diff --git a/t/bmo/comments.t b/t/bmo/comments.t index 4b0bb8177..00002040c 100644 --- a/t/bmo/comments.t +++ b/t/bmo/comments.t @@ -35,7 +35,7 @@ my $bug_1 = Bugzilla::Bug->create( keywords => [], cc => [], comment => 'This is a brand new bug', - assigned_to => 'nobody@mozilla.org', + assigned_to => Bugzilla->params->{'nobody_user'}, } ); ok($bug_1->id, "got a new bug"); @@ -55,7 +55,7 @@ my $bug_2 = Bugzilla::Bug->create( keywords => [], cc => [], comment => "This is related to ${urlbase}show_bug.cgi?id=$bug_1_id", - assigned_to => 'nobody@mozilla.org', + assigned_to => Bugzilla->params->{'nobody_user'}, } ); diff --git a/t/docker.t b/t/docker.t index 3c8cd055b..c1f85088c 100644 --- a/t/docker.t +++ b/t/docker.t @@ -28,7 +28,7 @@ while (my $line = readline $dockerfile_fh) { close $dockerfile_fh; my ($image, $version) = split(/:/ms, $base, 2); -is($image, 'mozillabteam/bmo-slim', "base image is mozillabteam/bmo-slim"); +is($image, 'bugzilla/harmony-slim', "base image is bugzilla/harmony-slim"); like($version, qr/\d{4}\d{2}\d{2}\.\d+/ms, "version is YYYYMMDD.x"); my $regex = qr{ @@ -49,4 +49,4 @@ while (my $line = readline $ci_config_fh) { } close $ci_config_fh; -done_testing;
\ No newline at end of file +done_testing; diff --git a/template/en/default/account/prefs/account.html.tmpl b/template/en/default/account/prefs/account.html.tmpl index 1e7bc25db..61ce80011 100644 --- a/template/en/default/account/prefs/account.html.tmpl +++ b/template/en/default/account/prefs/account.html.tmpl @@ -138,7 +138,7 @@ <td></td> <td> <p> - Your contributions on bugzilla.mozilla.org will still be visible; + Your contributions on [% terms.Bugzilla %] will still be visible; however, your email address and name will be removed in most locations. We are not able to remove your details that are part of comment text. </p> diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl index 329e0ab49..7006448d3 100644 --- a/template/en/default/attachment/create.html.tmpl +++ b/template/en/default/attachment/create.html.tmpl @@ -83,14 +83,14 @@ TUI_hide_default('attachment_text_field'); <td> <em>If you want to assign this [% terms.bug %] to yourself, check the box below.</em><br> - [% IF bug.assigned_to.login == "nobody@mozilla.org" || bug.assigned_to.login.search('.bugs$') %] + [% IF bug.assigned_to.login == Param('nobody_user') || bug.assigned_to.login.search('.bugs$') %] [% take_if_patch = 1 %] [% END %] <input type="checkbox" id="takebug" name="takebug" value="1" [% IF take_if_patch %] data-take-if-patch="1" [% END %]> <label for="takebug">take [% terms.bug %]</label> [% bug_statuses = [] %] [% FOREACH bug_status = bug.status.can_change_to %] - [% NEXT IF bug_status.name == "UNCONFIRMED" + [% NEXT IF bug_status.name == "UNCONFIRMED" && !bug.product_obj.allows_unconfirmed %] [% bug_statuses.push(bug_status) IF bug_status.is_open %] [% END %] diff --git a/template/en/default/bug/create/user-message.html.tmpl b/template/en/default/bug/create/user-message.html.tmpl index fa42ace81..51e787870 100644 --- a/template/en/default/bug/create/user-message.html.tmpl +++ b/template/en/default/bug/create/user-message.html.tmpl @@ -30,7 +30,7 @@ [% PROCESS global/variables.none.tmpl %] Before reporting [% terms.abug %], please read the -<a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines"> +<a href="[% terms.BugWritingGuidelinesURL %]"> [% terms.bug %] writing guidelines</a>, please look at the list of <a href="duplicates.cgi">most frequently reported [% terms.bugs %]</a>, and please <a href="query.cgi">search</a> for the [% terms.bug %]. diff --git a/template/en/default/bug/new_bug.html.tmpl b/template/en/default/bug/new_bug.html.tmpl index ef5e361c0..9e0b2c1ab 100644 --- a/template/en/default/bug/new_bug.html.tmpl +++ b/template/en/default/bug/new_bug.html.tmpl @@ -27,10 +27,10 @@ <h2>Create New [% terms.Bug %]</h2> <p> Before reporting a [% terms.bug %], make sure you've read our - <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines"> + <a href="[% terms.BugWritingGuidelinesURL %]"> [% terms.bug %] writing guidelines</a> and double checked that your [% terms.bug %] hasn't already - been reported. Consult our list of <a href="https://bugzilla.mozilla.org/duplicates.cgi"> - most frequently reported [% terms.bugs %]</a> and <a href="https://bugzilla.mozilla.org/query.cgi"> + been reported. Consult our list of <a href="duplicates.cgi"> + most frequently reported [% terms.bugs %]</a> and <a href="query.cgi"> search through descriptions</a> of previously reported [% terms.bugs %]. </p> </div> diff --git a/template/en/default/global/variables.none.tmpl b/template/en/default/global/variables.none.tmpl index faf1a5427..93002efa3 100644 --- a/template/en/default/global/variables.none.tmpl +++ b/template/en/default/global/variables.none.tmpl @@ -37,7 +37,9 @@ "bugs" => "bugs", "Bugs" => "Bugs", "zeroSearchResults" => "Zarro Boogs found", - "Bugzilla" => "Bugzilla" + "Bugzilla" => "Bugzilla", + + "BugWritingGuidelinesURL" => "https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines", } %] diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl index e63bf0e87..2aff68615 100644 --- a/template/en/default/index.html.tmpl +++ b/template/en/default/index.html.tmpl @@ -76,7 +76,7 @@ <a href="page.cgi?id=etiquette.html">[%- terms.Bugzilla %] Etiquette</a> </li> <li> - | <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">[%- terms.Bug %] Writing Guidelines</a> + | <a href="[% terms.BugWritingGuidelinesURL %]">[%- terms.Bug %] Writing Guidelines</a> </li> [% Hook.process('additional_links') %] </ul> diff --git a/template/en/default/list/edit-multiple.html.tmpl b/template/en/default/list/edit-multiple.html.tmpl index eb989d15c..ead3ff54c 100644 --- a/template/en/default/list/edit-multiple.html.tmpl +++ b/template/en/default/list/edit-multiple.html.tmpl @@ -437,7 +437,6 @@ [% FOREACH r = resolutions %] [% NEXT IF !r %] [% NEXT IF r == "DUPLICATE" || r == "MOVED" %] - [% NEXT IF r == "EXPIRED" AND user.login != "gerv@mozilla.org" %] <option value="[% r FILTER html %]">[% display_value("resolution", r) FILTER html %]</option> [% END %] </select> diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl index df2f6b349..486f3a00a 100644 --- a/template/en/default/list/table.html.tmpl +++ b/template/en/default/list/table.html.tmpl @@ -90,7 +90,9 @@ <th class="sorttable_nosort"> </th> [% END %] <th colspan="[% splitheader ? 2 : 1 %]" class="first-child - sorted_[% lsearch(order_columns, 'bug_id') FILTER html %]"> + [% order_columns.defined + ? 'sorted_' _ lsearch(order_columns, 'bug_id') + : '' FILTER html %]"> <a href="buglist.cgi? [% urlquerypart FILTER html %]&order= [% PROCESS new_order id='bug_id' %] @@ -136,7 +138,9 @@ [% BLOCK columnheader %] <th colspan="[% splitheader ? 2 : 1 %]" class="sortable_column_[% key FILTER html %] - sorted_[% lsearch(order_columns, id) FILTER html %]"> + [% order_columns.defined + ? 'sorted_' _ lsearch(order_columns, id) + : '' FILTER html %]"> <a href="buglist.cgi?[% urlquerypart FILTER html %]&order= [% PROCESS new_order %] [%-#%]&query_based_on= diff --git a/template/en/default/search/search-google.html.tmpl b/template/en/default/search/search-google.html.tmpl index 7fdc1daaa..1b07320ce 100644 --- a/template/en/default/search/search-google.html.tmpl +++ b/template/en/default/search/search-google.html.tmpl @@ -32,7 +32,7 @@ <p> <form method="get" action="https://www.google.com/search" data-no-csrf> -<input type="hidden" name="sitesearch" value="bugzilla.mozilla.org"> +<input type="hidden" name="sitesearch" value="[% urlbase.match('^([^:]*://)?(.*?)/?$').1 %]"> <nobr> <input type="text" name="q" size="60" maxlength="255" value=""> <input type="submit" value="Search"> diff --git a/template/en/default/search/search-instant.html.tmpl b/template/en/default/search/search-instant.html.tmpl index d0cf078e7..ed3942166 100644 --- a/template/en/default/search/search-instant.html.tmpl +++ b/template/en/default/search/search-instant.html.tmpl @@ -8,11 +8,15 @@ [% PROCESS global/variables.none.tmpl %] +[% javascript_urls = [ 'js/instant-search.js' ] %] +[% IF has_extension('GuidedBugEntry') %] + [% javascript_urls.import(['extensions/GuidedBugEntry/web/js/products.js']); %] +[% END %] + [% PROCESS global/header.html.tmpl title = "Instant Search" generate_api_token = 1 - javascript_urls = [ 'extensions/GuidedBugEntry/web/js/products.js', - 'js/instant-search.js', ] + javascript_urls = javascript_urls %] [% UNLESS default.exists('product') && default.product.size %] @@ -30,8 +30,7 @@ use lib qw(. lib local/lib/perl5); use Bugzilla; use Bugzilla::Error; -my $is_enabled = grep { $_->NAME eq 'Voting' } @{ Bugzilla->extensions }; -$is_enabled || ThrowCodeError('extension_disabled', { name => 'Voting' }); +Bugzilla->has_extension('Voting') || ThrowCodeError('extension_disabled', { name => 'Voting' }); my $cgi = Bugzilla->cgi; my $action = $cgi->param('action') || 'show_user'; |