Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 1023-paypal-link-is-not-working-for-en-version
  • 1100-switch-development-redis-cache-to-a-cluster
  • 1132-add-query-to-adgoal-data
  • 1138-use-searx-as-source
  • 1161-small-change-to-footer
  • 1167-remove-unnecessary-javascript
  • 1172-zitate-txt-revision
  • 1175-extract-non-confidentials-informations-from-sumas-json
  • 1200-metager-org-shopping-focus-doesn-t-work
  • 1203-implement-result-serialization
  • 1206-translating-metager-into-spanish
  • 1220-add-a-back-arrow-to-help-page
  • 1227-refactor-result-class
  • 1235-migrate-to-new-keymanager
  • 1240-remove-some-spelling-mistakes
  • 1245-token-changes-require-some-help-file-changes-search-in-search-ceased
  • 1281-link-to-contact-form-broken-on-team-page-2
  • 1299-restructure-parameter-filters
  • 1308-implement-icons-in-css
  • 1319-integrate-infobox
  • 1320-integrate-maps-view
  • 1322-exchange-help-pictures-to-the-current-metager-version
  • 1326-create-an-advertiser-portal
  • 1332-fix-resultpage-searchbar
  • 1334-donation-campaign
  • 1335-integrate-takeads-serp
  • 1343-update-dependencies
  • 1347-add-paypal-and-creditcard-payment-options-to-membership
  • 765-wcag-2-0-level-a-wird-eingehalten
  • development
  • master
31 results

Target

Select target project
  • sebastian/MetaGer
  • cpietsch/MetaGer
  • kossow/MetaGer
  • jens/MetaGer
  • open-source/MetaGer
5 results
Select Git revision
  • 1023-paypal-link-is-not-working-for-en-version
  • 1100-switch-development-redis-cache-to-a-cluster
  • 1132-add-query-to-adgoal-data
  • 1138-use-searx-as-source
  • 1161-small-change-to-footer
  • 1167-remove-unnecessary-javascript
  • 1172-zitate-txt-revision
  • 1175-extract-non-confidentials-informations-from-sumas-json
  • 1200-metager-org-shopping-focus-doesn-t-work
  • 1203-implement-result-serialization
  • 1206-translating-metager-into-spanish
  • 1220-add-a-back-arrow-to-help-page
  • 1227-refactor-result-class
  • 1235-migrate-to-new-keymanager
  • 1240-remove-some-spelling-mistakes
  • 1245-token-changes-require-some-help-file-changes-search-in-search-ceased
  • 1281-link-to-contact-form-broken-on-team-page-2
  • 1299-restructure-parameter-filters
  • 1308-implement-icons-in-css
  • 1319-integrate-infobox
  • 1320-integrate-maps-view
  • 1322-exchange-help-pictures-to-the-current-metager-version
  • 1326-create-an-advertiser-portal
  • 1332-fix-resultpage-searchbar
  • 1334-donation-campaign
  • 1335-integrate-takeads-serp
  • 1343-update-dependencies
  • 1347-add-paypal-and-creditcard-payment-options-to-membership
  • 765-wcag-2-0-level-a-wird-eingehalten
  • development
  • master
31 results
Show changes
Commits on Source (38)
Showing
with 783 additions and 320 deletions
......@@ -143,16 +143,19 @@ stop_review:
development:
<<: *development_template
only:
refs:
- development
kubernetes: active
except:
variables:
- $STAGING_ENABLED
- $CANARY_ENABLED
- $INCREMENTAL_ROLLOUT_ENABLED
- $INCREMENTAL_ROLLOUT_MODE
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$STAGING_ENABLED'
when: never
- if: '$CANARY_ENABLED'
when: never
- if: '$INCREMENTAL_ROLLOUT_ENABLED'
when: never
- if: '$INCREMENTAL_ROLLOUT_MODE'
when: never
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
production:
......@@ -162,6 +165,19 @@ production:
ROLLOUT_RESOURCE_TYPE: deployment
environment:
url: https://metager.de
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
- if: '$STAGING_ENABLED'
when: never
- if: '$CANARY_ENABLED'
when: never
- if: '$INCREMENTAL_ROLLOUT_ENABLED'
when: never
- if: '$INCREMENTAL_ROLLOUT_MODE'
when: never
- if: '$CI_COMMIT_BRANCH == "master"'
integrationtest:
stage: integrationtest
......
......@@ -51,6 +51,7 @@ ingress:
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "ReferrerPolicy: origin";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Permissions-Policy: interest-cohort=()";
if ($arg_out = "results-with-style") {
more_set_headers "X-Frame-Options: allow-from https://scripts.zdv.uni-mainz.de/";
}
......
......@@ -71,6 +71,7 @@ ingress:
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "ReferrerPolicy: origin";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Permissions-Policy: interest-cohort=()";
if ($arg_out = "results-with-style") {
more_set_headers "X-Frame-Options: allow-from https://scripts.zdv.uni-mainz.de/";
}
......
......@@ -17,6 +17,7 @@ ingress:
more_set_headers "X-Content-Type-Options: nosniff";
more_set_headers "ReferrerPolicy: origin";
more_set_headers "X-XSS-Protection: 1; mode=block";
more_set_headers "Permissions-Policy: interest-cohort=()";
if ($arg_out = "results-with-style") {
more_set_headers "X-Frame-Options: allow-from https://scripts.zdv.uni-mainz.de/";
}
......
......@@ -8,7 +8,7 @@
"name": "PHP - Listen for XDebug",
"type": "php",
"request": "launch",
"port": 9000,
"port": 9003,
"pathMappings": {
"/html": "${workspaceRoot}"
}
......@@ -17,7 +17,7 @@
"name": "PHP - Launch currently open script",
"type": "php",
"request": "launch",
"port": 9000,
"port": 9003,
"program": "${file}",
"cwd": "${fileDirname}",
"pathMappings": {
......
FROM alpine:3.11.3
FROM debian:10
RUN apk add --update \
# Install System Components
RUN apt update \
&& apt install -y \
nginx \
tzdata \
ca-certificates \
dcron \
zip \
redis \
libpng \
php7 \
php7-fpm \
php7-common \
php7-curl \
php7-mbstring \
php7-sqlite3 \
php7-pdo_mysql \
php7-pdo_sqlite \
php7-dom \
php7-simplexml \
php7-tokenizer \
php7-zip \
php7-redis \
php7-gd \
php7-json \
php7-pcntl \
php7-opcache \
php7-fileinfo \
&& rm -rf /var/cache/apk/*
cron \
lsb-release \
apt-transport-https \
curl \
zip
RUN curl -o /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg \
&& echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list
# Install PHP Components
RUN apt update \
&& apt install -y \
php7.4 \
php7.4-xml \
php7.4-fpm \
php7.4-common \
php7.4-curl \
php7.4-mbstring \
php7.4-sqlite3 \
php7.4-mysql \
php7.4-sqlite \
php7.4-zip \
php7.4-redis \
php7.4-gd \
php7.4-json \
php7.4-opcache
WORKDIR /html
RUN sed -i 's/;error_log = log\/php7\/error.log/error_log = \/dev\/stderr/g' /etc/php7/php-fpm.conf && \
sed -i 's/;daemonize = yes/daemonize = no/g' /etc/php7/php-fpm.conf && \
sed -i 's/listen = 127.0.0.1:9000/listen = 9000/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;request_terminate_timeout = 0/request_terminate_timeout = 30/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;request_terminate_timeout_track_finished = no/request_terminate_timeout_track_finished = yes/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;decorate_workers_output = no/decorate_workers_output = no/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;catch_workers_output = yes/catch_workers_output = yes/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/user = nobody/user = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/group = nobody/group = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.max_children = 5/pm.max_children = 1024/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.start_servers = 2/pm.start_servers = 50/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 5/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 50/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/user = www-data/user = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/group = www-data/group = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php7/php.ini && \
sed -i 's/expose_php = On/expose_php = Off/g' /etc/php7/php.ini && \
RUN mkdir -p /run/php && \
sed -i 's/error_log = \/var\/log\/php7.4-fpm.log/error_log = \/dev\/stderr/g' /etc/php/7.4/fpm/php-fpm.conf && \
sed -i 's/;daemonize = yes/daemonize = no/g' /etc/php/7.4/fpm/php-fpm.conf && \
sed -i 's/listen = \/run\/php\/php7.4-fpm.sock/listen = 9000/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;request_terminate_timeout = 0/request_terminate_timeout = 30/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;request_terminate_timeout_track_finished = no/request_terminate_timeout_track_finished = yes/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;decorate_workers_output = no/decorate_workers_output = no/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;catch_workers_output = yes/catch_workers_output = yes/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.max_children = 5/pm.max_children = 1024/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.start_servers = 2/pm.start_servers = 50/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 5/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 50/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/7.4/fpm/php.ini && \
# Opcache configuration
sed -i 's/;opcache.enable=1/opcache.enable=1/g' /etc/php7/php.ini && \
sed -i 's/;opcache.memory_consumption=128/opcache.memory_consumption=128/g' /etc/php7/php.ini && \
sed -i 's/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=8/g' /etc/php7/php.ini && \
sed -i 's/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=10000/g' /etc/php7/php.ini && \
sed -i 's/;opcache.max_wasted_percentage=5/opcache.max_wasted_percentage=5/g' /etc/php7/php.ini && \
sed -i 's/;opcache.validate_timestamps=1/opcache.validate_timestamps=1/g' /etc/php7/php.ini && \
sed -i 's/;opcache.revalidate_freq=2/opcache.revalidate_freq=300/g' /etc/php7/php.ini && \
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 30M/g' /etc/php7/php.ini && \
sed -i 's/post_max_size = 8M/post_max_size = 30M/g' /etc/php7/php.ini && \
echo "daemonize yes" >> /etc/redis.conf && \
ln -s /dev/null /var/log/nginx/access.log && \
ln -s /dev/stdout /var/log/nginx/error.log && \
sed -i 's/;opcache.enable=1/opcache.enable=1/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.memory_consumption=128/opcache.memory_consumption=128/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.interned_strings_buffer=8/opcache.interned_strings_buffer=8/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.max_accelerated_files=10000/opcache.max_accelerated_files=10000/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.max_wasted_percentage=5/opcache.max_wasted_percentage=5/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.validate_timestamps=1/opcache.validate_timestamps=1/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/;opcache.revalidate_freq=2/opcache.revalidate_freq=300/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 30M/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/post_max_size = 8M/post_max_size = 30M/g' /etc/php/7.4/fpm/php.ini && \
cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime && \
echo "Europe/Berlin" > /etc/timezone && \
(crontab -l ; echo "* * * * * php /html/artisan schedule:run >> /dev/null 2>&1") | crontab -
COPY config/nginx.conf /etc/nginx/nginx.conf
COPY config/nginx-default.conf /etc/nginx/conf.d/default.conf
RUN sed -i 's/fastcgi_pass phpfpm:9000;/fastcgi_pass localhost:9000;/g' /etc/nginx/conf.d/default.conf
COPY --chown=root:nginx . /html
COPY config/nginx-default.conf /etc/nginx/sites-available/default
RUN sed -i 's/fastcgi_pass phpfpm:9000;/fastcgi_pass localhost:9000;/g' /etc/nginx/sites-available/default
COPY --chown=root:www-data . /html
WORKDIR /html
EXPOSE 80
......@@ -76,8 +73,8 @@ CMD cp /root/.env .env && \
sed -i 's/^REDIS_PASSWORD=.*/REDIS_PASSWORD=null/g' .env && \
if [ "$GITLAB_ENVIRONMENT_NAME" = "production" ]; then sed -i 's/^APP_ENV=.*/APP_ENV=production/g' .env; else sed -i 's/^APP_ENV=.*/APP_ENV=development/g' .env; fi && \
cp database/useragents.sqlite.example database/useragents.sqlite && \
chown -R root:nginx storage/logs/metager bootstrap/cache && \
chown -R root:www-data storage/logs/metager bootstrap/cache && \
chmod -R g+w storage/logs/metager bootstrap/cache && \
crond -L /dev/stdout && \
cron -L /dev/stdout && \
php artisan spam:load && \
php-fpm7
php-fpm7.4
FROM alpine:3.11.3
FROM debian:10
RUN apk add --update \
# Install System Components
RUN apt update \
&& apt install -y \
nginx \
tzdata \
ca-certificates \
dcron \
zip \
redis \
php7 \
php7-fpm \
php7-common \
php7-curl \
php7-mbstring \
php7-sqlite3 \
php7-pdo_mysql \
php7-pdo_sqlite \
php7-dom \
php7-simplexml \
php7-tokenizer \
php7-zip \
php7-redis \
php7-gd \
php7-json \
php7-pcntl \
php7-fileinfo \
php7-xdebug \
&& rm -rf /var/cache/apk/*
cron \
lsb-release \
apt-transport-https \
curl \
zip
RUN curl -o /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg \
&& echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list
# Install PHP Components
RUN apt update \
&& apt install -y \
php7.4 \
php7.4-xml \
php7.4-fpm \
php7.4-common \
php7.4-curl \
php7.4-mbstring \
php7.4-sqlite3 \
php7.4-mysql \
php7.4-sqlite \
php7.4-zip \
php7.4-redis \
php7.4-gd \
php7.4-json \
php7.4-xdebug
WORKDIR /html
RUN sed -i 's/;error_log = log\/php7\/error.log/error_log = \/dev\/stderr/g' /etc/php7/php-fpm.conf && \
sed -i 's/;daemonize = yes/daemonize = no/g' /etc/php7/php-fpm.conf && \
sed -i 's/listen = 127.0.0.1:9000/listen = 9000/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;request_terminate_timeout = 0/request_terminate_timeout = 900/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;request_terminate_timeout_track_finished = no/request_terminate_timeout_track_finished = yes/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;decorate_workers_output = no/decorate_workers_output = no/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;catch_workers_output = yes/catch_workers_output = yes/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/user = nobody/user = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/group = nobody/group = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.max_children = 5/pm.max_children = 100/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.start_servers = 2/pm.start_servers = 5/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 5/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 25/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/user = www-data/user = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/group = www-data/group = nginx/g' /etc/php7/php-fpm.d/www.conf && \
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php7/php.ini && \
sed -i 's/expose_php = On/expose_php = Off/g' /etc/php7/php.ini && \
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 30M/g' /etc/php7/php.ini && \
sed -i 's/post_max_size = 8M/post_max_size = 30M/g' /etc/php7/php.ini && \
sed -i 's/;zend_extension=xdebug.so/zend_extension=xdebug.so/g' /etc/php7/conf.d/xdebug.ini && \
echo "xdebug.remote_enable = 1" >> /etc/php7/conf.d/xdebug.ini && \
echo "xdebug.remote_autostart = 1" >> /etc/php7/conf.d/xdebug.ini && \
echo "xdebug.remote_connect_back = 1" >> /etc/php7/conf.d/xdebug.ini && \
echo "xdebug.idekey=VSCODE" >> /etc/php7/conf.d/xdebug.ini && \
echo "daemonize yes" >> /etc/redis.conf && \
ln -s /dev/null /var/log/nginx/access.log && \
ln -s /dev/stdout /var/log/nginx/error.log && \
RUN mkdir -p /run/php && \
sed -i 's/error_log = \/var\/log\/php7.4-fpm.log/error_log = \/dev\/stderr/g' /etc/php/7.4/fpm/php-fpm.conf && \
sed -i 's/;daemonize = yes/daemonize = no/g' /etc/php/7.4/fpm/php-fpm.conf && \
sed -i 's/listen = \/run\/php\/php7.4-fpm.sock/listen = 9000/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;request_terminate_timeout = 0/request_terminate_timeout = 30/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;request_terminate_timeout_track_finished = no/request_terminate_timeout_track_finished = yes/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;decorate_workers_output = no/decorate_workers_output = no/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;catch_workers_output = yes/catch_workers_output = yes/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.max_children = 5/pm.max_children = 1024/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.start_servers = 2/pm.start_servers = 50/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.min_spare_servers = 1/pm.min_spare_servers = 5/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/pm.max_spare_servers = 3/pm.max_spare_servers = 50/g' /etc/php/7.4/fpm/pool.d/www.conf && \
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 30M/g' /etc/php/7.4/fpm/php.ini && \
sed -i 's/post_max_size = 8M/post_max_size = 30M/g' /etc/php/7.4/fpm/php.ini && \
echo "xdebug.mode = debug" >> /etc/php/7.4/fpm/conf.d/20-xdebug.ini && \
echo "xdebug.start_with_request = yes" >> /etc/php/7.4/fpm/conf.d/20-xdebug.ini && \
echo "xdebug.discover_client_host = true" >> /etc/php/7.4/fpm/conf.d/20-xdebug.ini && \
echo "xdebug.idekey=VSCODE" >> /etc/php/7.4/fpm/conf.d/20-xdebug.ini && \
cp /usr/share/zoneinfo/Europe/Berlin /etc/localtime && \
echo "Europe/Berlin" > /etc/timezone && \
(crontab -l ; echo "* * * * * php /html/artisan schedule:run >> /dev/null 2>&1") | crontab -
......@@ -63,7 +60,7 @@ RUN sed -i 's/;error_log = log\/php7\/error.log/error_log = \/dev\/stderr/g' /et
WORKDIR /html
EXPOSE 80
CMD chown -R root:nginx storage/logs/metager bootstrap/cache && \
CMD chown -R root:www-data storage/logs/metager bootstrap/cache && \
chmod -R g+w storage/logs/metager bootstrap/cache && \
crond -L /dev/stdout && \
php-fpm7
cron -L /dev/stdout && \
php-fpm7.4
......@@ -43,14 +43,16 @@ class SaveUseragents extends Command
$agent = null;
$now = Carbon::now('utc')->toDateTimeString();
while (($agent = Redis::lpop("useragents")) !== null) {
while (!empty(($agent = Redis::lpop("useragents")))) {
$newEntry = json_decode($agent, true);
$newEntry["created_at"] = $now;
$newEntry["updated_at"] = $now;
$agents[] = $newEntry;
}
\App\UserAgent::insert($agents);
if (!empty($agents)) {
\App\UserAgent::insert($agents);
}
// Delete old entries (older than 24h)
$expiration = Carbon::now('utc')->subDays(1);
......
......@@ -6,37 +6,38 @@ use Cookie;
use Illuminate\Http\Request;
use LaravelLocalization;
use \App\Models\Key;
use \Carbon\Carbon;
use Validator;
class KeyController extends Controller
{
public function index(Request $request)
{
$redirUrl = $request->input('redirUrl', "");
$cookie = Cookie::get('key');
$key = $request->input('keyToSet', '');
if (empty($key) && empty($cookie)) {
$key = 'enter_key_here';
} elseif (empty($key) && !empty($cookie)) {
$key = $cookie;
} elseif (!empty($key)) {
$key = $request->input('key');
}
// How many Ad Free searches should a user get max when he creates a new key
const KEYCHANGE_ADFREE_SEARCHES = 150;
public function index(\App\Models\Key $key, Request $request)
{
$cookieLink = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('loadSettings', Cookie::get()));
$key->canChange();
$changedAt = null;
if (!empty($key) && !empty($key->keyinfo) && !empty($key->keyinfo->KeyChangedAt)) {
$changedAt = $key->keyinfo->KeyChangedAt;
$changedAt = Carbon::createFromFormat('Y-m-d\TH:i:s.u\Z', $changedAt, "Europe/London");
}
return view('key')
->with('title', trans('titles.key'))
->with('cookie', $key)
->with('keystatus', $key->getStatus())
->with('cookie', $key->key)
->with('changedAt', $changedAt)
->with('cookieLink', $cookieLink);
}
public function setKey(Request $request)
{
$redirUrl = $request->input('redirUrl', "");
$keyToSet = $request->input('keyToSet');
$key = new Key($request->input('keyToSet', ''));
if ($key->getStatus()) {
$status = $key->getStatus();
if ($status !== null) {
# Valid Key
$host = $request->header("X_Forwarded_Host", "");
if (empty($host)) {
......@@ -46,10 +47,7 @@ class KeyController extends Controller
$settings = Cookie::get();
$settings['key'] = $keyToSet;
$cookieLink = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('loadSettings', $settings));
return view('key')
->with('title', trans('titles.key'))
->with('cookie', $keyToSet)
->with('cookieLink', $cookieLink);
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
} else {
$cookieLink = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('loadSettings', Cookie::get()));
return view('key')
......@@ -74,4 +72,152 @@ class KeyController extends Controller
return redirect($url);
}
}
public function changeKeyIndex(\App\Models\Key $key, Request $request){
if(!$key->canChange()){
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
return view('keychange', [
"title" => trans('titles.keychange'),
"key" => $key->key,
"css" => [mix('css/keychange/index.css')]
]);
}
public function removeCurrent(\App\Models\Key $key, Request $request){
if(!$key->canChange()){
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
// Reduce Current Key
$res = $key->reduce(self::KEYCHANGE_ADFREE_SEARCHES);
if(empty($res) || empty($res->status) || $res->status !== "success"){
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
// Redirect to Cookie Remove URL with redirect to step two
$validUntil = Carbon::now("Europe/London")->addDays(2);
$format = "Y-m-d H:i:s";
$data = [
"validUntil" => $validUntil->format($format),
"password" => hash_hmac("sha256", $validUntil->format($format), env("APP_KEY", "WEAK_KEY")),
];
$targetUrl = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('changeKeyTwo', $data));
$redirUrl = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('removeCookie', [
"ir" => $targetUrl
]));
return redirect($redirUrl);
}
public function generateNew(\App\Models\Key $key, Request $request){
// Validate Request Data
$validUntil = $request->input('validUntil', '');
$password = $request->input('password', '');
$format = "Y-m-d H:i:s";
// Check if Validuntil
$valid = true;
if(empty($validUntil)){
$valid = false;
}else{
$validUntil = Carbon::createFromFormat($format, $validUntil, "Europe/London");
if(!$validUntil){
$valid = false;
}
}
if($valid && Carbon::now()->diffInSeconds($validUntil) <= 0){
$valid = false;
}
if($valid){
// Check if hash matches
$expectedHash = hash_hmac("sha256", $validUntil->format($format), env("APP_KEY", "WEAK_KEY"));
if(!hash_equals($expectedHash, $password)){
$valid = false;
}
}
if(!$valid){
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
// Check if the key already was generated
if (!$key->checkForChange("", $password)) {
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
return view('keychangetwo', [
"title" => trans('titles.keychange'),
"validUntil" => $validUntil,
"css" => [mix('css/keychange/index.css')]
]);
}
public function generateNewPost(\App\Models\Key $key, Request $request){
// Validate Request Data
$validUntil = $request->input('validUntil', '');
$password = $request->input('password', '');
$format = "Y-m-d H:i:s";
// Check if Validuntil
$valid = true;
if(empty($validUntil)){
$valid = false;
}else{
$validUntil = Carbon::createFromFormat($format, $validUntil, "Europe/London");
if(!$validUntil){
$valid = false;
}
}
if($valid && Carbon::now()->diffInSeconds($validUntil) <= 0){
$valid = false;
}
if($valid){
// Check if hash matches
$expectedHash = hash_hmac("sha256", $validUntil->format($format), env("APP_KEY", "WEAK_KEY"));
if(!hash_equals($expectedHash, $password)){
$valid = false;
}
}
if(!$valid){
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('keyindex')));
}
$validator = Validator::make($request->all(), [
'newkey' => 'required|min:4|max:20',
]);
if($validator->fails()) {
$data = [
"validUntil" => $validUntil->format($format),
"password" => hash_hmac("sha256", $validUntil->format($format), env("APP_KEY", "WEAK_KEY")),
"newkey" => $request->input('newkey', ''),
];
$targetUrl = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('changeKeyTwo', $data));
return redirect($targetUrl);
}
$newkey = $request->input('newkey', '');
$characters = '0123456789abcdefghijklmnopqrstuvwxyz';
$randomSuffix = "";
$suffixCount = 3;
for($i = 0; $i < $suffixCount; $i++){
$randomSuffix .= $characters[rand(0, strlen($characters)-1)];
}
$newkey = $newkey . $randomSuffix;
if($key->checkForChange($newkey, $password)){
$result = $key->generateKey(null, self::KEYCHANGE_ADFREE_SEARCHES, $newkey, "Schlüssel gewechselt. Hash $password");
if(!empty($result)){
Cookie::queue('key', $result, 525600, '/', null, false, false);
return redirect(LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('changeKeyThree', ["newkey" => $result])));
}
}
$data = [
"validUntil" => $validUntil->format($format),
"password" => hash_hmac("sha256", $validUntil->format($format), env("APP_KEY", "WEAK_KEY")),
];
$targetUrl = LaravelLocalization::getLocalizedURL(LaravelLocalization::getCurrentLocale(), route('changeKeyTwo', $data));
return redirect($targetUrl);
}
}
......@@ -197,7 +197,7 @@ class MailController extends Controller
# Validate Email
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$email = "anonymous@suma-ev.de";
$email = "";
}
if(($private && (empty($firstname) || empty($lastname))) || (!$private && empty($company))){
$messageToUser = trans('spende.error.name');
......@@ -220,7 +220,7 @@ class MailController extends Controller
$betrag = round($betrag, 2, PHP_ROUND_HALF_DOWN);
# Generating personalised key for donor
$key = app('App\Models\Key')->generateKey($betrag);
$key = app('App\Models\Key')->generateKey($betrag, null, null, 'Für ' . $betrag . '€ aufgeladen am '. date("d.m.Y"));
try {
$postdata = [
......
......@@ -93,6 +93,21 @@ class MetaGerSearch extends Controller
# Ergebnisse der Suchmaschinen kombinieren:
$metager->prepareResults($timings);
$admitad = [];
$adgoal = [];
if(!$metager->isApiAuthorized() && !$metager->isDummy()){
$newAdmitad = new \App\Models\Admitad($metager);
if(!empty($newAdmitad->hash)){
$admitad[] = $newAdmitad;
}
$newAdgoal = new \App\Models\Adgoal($metager);
if(!empty($newAdgoal->hash)){
$adgoal[] = $newAdgoal;
}
}
$metager->parseAffiliates($admitad);
$metager->parseAffiliates($adgoal);
$finished = true;
foreach ($metager->getEngines() as $engine) {
......@@ -106,10 +121,8 @@ class MetaGerSearch extends Controller
"metager" => [
"apiAuthorized" => $metager->isApiAuthorized(),
],
"adgoal" => [
"loaded" => $metager->isAdgoalLoaded(),
"adgoalHash" => $metager->getAdgoalHash(),
],
"admitad" => $admitad,
"adgoal" => $adgoal,
"engines" => $metager->getEngines(),
], 60 * 60);
} catch (\Exception $e) {
......@@ -190,14 +203,14 @@ class MetaGerSearch extends Controller
$engines = $cached["engines"];
$adgoal = $cached["adgoal"];
$admitad = $cached["admitad"];
$mg = $cached["metager"];
$metager = new MetaGer(substr($hash, strpos($hash, "loader_") + 7));
$metager->setApiAuthorized($mg["apiAuthorized"]);
$metager->setAdgoalLoaded($adgoal["loaded"]);
$metager->setAdgoalHash($adgoal["adgoalHash"]);
$metager->parseFormData($request, false);
$metager->setJsEnabled(true);
# Nach Spezialsuchen überprüfen:
$metager->checkSpecialSearches($request);
$metager->restoreEngines($engines);
......@@ -210,6 +223,20 @@ class MetaGerSearch extends Controller
$metager->rankAll();
$metager->prepareResults();
if(!$metager->isApiAuthorized() && !$metager->isDummy()){
$newAdmitad = new \App\Models\Admitad($metager);
if(!empty($newAdmitad->hash)){
$admitad[] = $newAdmitad;
}
$newAdgoal = new \App\Models\Adgoal($metager);
if(!empty($newAdgoal->hash)){
$adgoal[] = $newAdgoal;
}
}
$admitadFinished = $metager->parseAffiliates($admitad);
$adgoalFinished = $metager->parseAffiliates($adgoal);
$result = [
'finished' => true,
'newResults' => [],
......@@ -256,7 +283,7 @@ class MetaGerSearch extends Controller
}
}
if (!$metager->isAdgoalLoaded()) {
if (!$adgoalFinished || !$admitadFinished) {
$finished = false;
}
......@@ -273,10 +300,8 @@ class MetaGerSearch extends Controller
"metager" => [
"apiAuthorized" => $metager->isApiAuthorized(),
],
"adgoal" => [
"loaded" => $metager->isAdgoalLoaded(),
"adgoalHash" => $metager->getAdgoalHash(),
],
"admitad" => $admitad,
"adgoal" => $adgoal,
"engines" => $metager->getEngines(),
], 1 * 60);
......
......@@ -73,12 +73,6 @@ class StartpageController extends Controller
return view($subpage, ['title' => 'Datenschutz Richtlinien']);
}
public function loadLocalPage($locale = "de", $subpage = "datenschutz")
{
\App::setLocale($locale);
return loadPage($subpage);
}
public function loadPlugin(Request $request, $locale = "de")
{
$link = action('MetaGerSearch@search', []);
......
......@@ -24,7 +24,6 @@ class Stresstest extends MetaGerSearch
# deactivates adgoal
$metager->setDummy(true);
$metager->setAdgoalHash(true);
parent::search($request, $metager, $timing);
}
......
......@@ -17,7 +17,7 @@ class RemoveKey
public function handle($request, Closure $next)
{
// Check if a wrong Key Cookie is set and if so remove it
if(Cookie::has("key") && !app('App\Models\Key')->getStatus()){
if(Cookie::has("key") && app('App\Models\Key')->getStatus() === null){
return redirect(route("removeCookie", ["ir" => url()->full()]));
}
return $next($request);
......
......@@ -48,6 +48,7 @@ class MetaGer
protected $availableFoki = [];
protected $startCount = 0;
protected $canCache = false;
protected $javascript = false;
# Daten über die Abfrage$
protected $ip;
protected $useragent;
......@@ -213,7 +214,15 @@ class MetaGer
->with('browser', (new Agent())->browser())
->with('fokus', $this->fokus);
break;
case 'rss20':
return view('resultpages.metager3resultsrss20')
->with('results', $viewResults)
->with('eingabe', $this->eingabe)
->with('apiAuthorized', $this->apiAuthorized)
->with('metager', $this)
->with('resultcount', sizeof($viewResults))
->with('fokus', $this->fokus);
break;
case 'api':
return view('resultpages.metager3resultsatom10', ['eingabe' => $this->eingabe, 'resultcount' => sizeof($viewResults), 'key' => $this->apiKey, 'metager' => $this]);
break;
......@@ -307,33 +316,12 @@ class MetaGer
if (empty($this->adgoalLoaded)) {
$this->adgoalLoaded = false;
}
if (!$this->apiAuthorized && !$this->adgoalLoaded && !$this->dummy) {
if (empty($this->adgoalHash)) {
if (!empty($this->jskey)) {
$js = Redis::connection('cache')->lpop("js" . $this->jskey);
if ($js !== null && boolval($js)) {
$this->javascript = true;
}
}
$this->adgoalHash = \App\Models\Adgoal::startAdgoal($this->results);
if (!empty($timings)) {
$timings["prepareResults"]["started adgoal"] = microtime(true) - $timings["starttime"];
}
}
if (!$this->javascript) {
$this->adgoalLoaded = \App\Models\Adgoal::parseAdgoal($this->results, $this->adgoalHash, true);
if (!empty($timings)) {
$timings["prepareResults"]["parsed adgoal"] = microtime(true) - $timings["starttime"];
}
} else {
$this->adgoalLoaded = \App\Models\Adgoal::parseAdgoal($this->results, $this->adgoalHash, false);
if (!empty($timings)) {
$timings["prepareResults"]["parsed adgoal"] = microtime(true) - $timings["starttime"];
}
if (!empty($this->jskey)) {
$js = Redis::connection('cache')->lpop("js" . $this->jskey);
if ($js !== null && boolval($js)) {
$this->javascript = true;
}
} else {
$this->adgoalLoaded = true;
}
# Human Verification
......@@ -435,7 +423,26 @@ class MetaGer
}
}
/**
* @param \App\Models\Admitad[] $admitads
* @param Boolean $wait Wait for Results?
* @return Boolean whether or not all Admitad Objects are finished
*/
public function parseAffiliates(&$affiliates){
$wait = false;
$finished = true;
if(!$this->javascript){
$wait = true;
}
foreach ($affiliates as $affiliate) {
$affiliate->fetchAffiliates($wait);
$affiliate->parseAffiliates($this->results);
if(!$affiliate->finished){
$finished = false;
}
}
return $finished;
}
public function humanVerification(&$results)
{
......@@ -1108,7 +1115,7 @@ class MetaGer
$this->out = $request->input('out', "html");
# Standard output format html
if ($this->out !== "html" && $this->out !== "json" && $this->out !== "results" && $this->out !== "results-with-style" && $this->out !== "result-count" && $this->out !== "atom10" && $this->out !== "api") {
if ($this->out !== "html" && $this->out !== "json" && $this->out !== "results" && $this->out !== "results-with-style" && $this->out !== "result-count" && $this->out !== "atom10" && $this->out !== "api" && $this->out !== "rss20") {
$this->out = "html";
}
# Wir schalten den Cache aus, wenn die Ergebniszahl überprüft werden soll
......@@ -1503,7 +1510,6 @@ class MetaGer
$logEntry .= " time=" . round((microtime(true) - $this->starttime), 2) . " serv=" . $this->fokus;
$logEntry .= " interface=" . LaravelLocalization::getCurrentLocale();
$logEntry .= " sprachfilter=" . $this->lang;
$logEntry .= " key=" . $this->apiKey;
$logEntry .= " eingabe=" . $this->eingabe;
$logEntry = preg_replace("/\n+/", " ", $logEntry);
......@@ -1718,6 +1724,9 @@ class MetaGer
$this->results = $results;
}
/**
* @return \App\Models\Result[]
*/
public function getResults()
{
return $this->results;
......@@ -1891,26 +1900,6 @@ class MetaGer
return $this->engines;
}
public function setAdgoalHash($hash)
{
$this->adgoalHash = $hash;
}
public function getAdgoalHash()
{
return $this->adgoalHash;
}
public function isAdgoalLoaded()
{
return $this->adgoalLoaded;
}
public function setAdgoalLoaded($adgoalLoaded)
{
$this->adgoalLoaded = $adgoalLoaded;
}
public function isApiAuthorized()
{
return $this->apiAuthorized;
......@@ -1931,6 +1920,17 @@ class MetaGer
return $this->headerPrinted;
}
public function isDummy(){
return $this->dummy;
}
public function jsEnabled() {
return $this->javascript;
}
public function setJsEnabled(bool $bool){
$this->javascript = $bool;
}
/**
* Used by JS result loader to restore MetaGer Object of previous request
*/
......
......@@ -22,29 +22,47 @@ class Adgoal
"lk","sh","kn","lc","pm","vc","sd","sr","za","kr","sz","sy","tj","tw","tz","th","tg","to","tt","td","cz","tn",
"tm","tc","tv","tr","us","ug","ua","xx","hu","uy","uz","vu","va","ve","ae","vn","wf","cx","by","eh","ww","zr","cf","cy",];
public static function startAdgoal(&$results)
public $hash;
public $finished = false; // Is true when the Request was sent to and read from Admitad App
private $affiliates = null;
private $startTime;
/**
* Creates a new Adgoal object which will start a request for affiliate links
* based on a result List from MetaGer.
* It will parse the Links of the results and query any affiliate shops.
*
* @param \App\MetaGer $metager
*/
public function __construct(&$metager)
{
$this->startTime = microtime(true);
$publicKey = getenv('adgoal_public');
$privateKey = getenv('adgoal_private');
if ($publicKey === false) {
return true;
}
$results = $metager->getResults();
$linkList = "";
foreach ($results as $result) {
if (!$result->new) {
continue;
}
$link = $result->link;
$link = $result->originalLink;
if (strpos($link, "http") !== 0) {
$link = "http://" . $link;
}
$linkList .= $link . ",";
}
if(empty($linkList)){
return;
}
$linkList = rtrim($linkList, ",");
# Hashwert
$hash = md5($linkList . $privateKey);
$this->hash = md5($linkList . $privateKey);
$link = "https://xf.gdprvalidate.de/v4/check";
......@@ -73,14 +91,14 @@ class Adgoal
"key" => $publicKey,
"panel" => "ZMkW9eSKJS",
"member" => "338b9Bnm",
"signature" => $hash,
"signature" => $this->hash,
"links" => $linkList,
"country" => $country,
];
// Submit fetch job to worker
$mission = [
"resulthash" => $hash,
"resulthash" => $this->hash,
"url" => $link,
"useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0",
"username" => null,
......@@ -97,76 +115,92 @@ class Adgoal
];
$mission = json_encode($mission);
Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission);
return $hash;
}
public static function parseAdgoal(&$results, $hash, $waitForResult)
{
# Wait for result
$startTime = microtime(true);
$answer = null;
# Hash is true if Adgoal request wasn't started in the first place
if ($hash === true) {
return true;
public function fetchAffiliates($wait = false){
if($this->affiliates !== null){
return;
}
if ($waitForResult) {
$answer = null;
$startTime = microtime(true);
if($wait){
while (microtime(true) - $startTime < 5) {
$answer = Cache::get($hash);
$answer = Cache::get($this->hash);
if ($answer === null) {
usleep(50 * 1000);
} else {
break;
}
}
} else {
$answer = Cache::get($hash);
}else{
$answer = Cache::get($this->hash);
}
if ($answer === null) {
return false;
$answer = json_decode($answer, true);
// If the fetcher had an Error
if($answer === "no-result"){
$this->affiliates = [];
return;
}
try {
$answer = json_decode($answer, true);
foreach ($answer as $partnershop) {
$targetUrl = $partnershop["url"];
$tld = $partnershop["tld"];
$targetHost = parse_url($targetUrl, PHP_URL_HOST);
/*
Adgoal sometimes returns affiliate Links for every URL
That's why we check if the corresponding TLD matches the orginial URL
*/
if($targetHost !== false && stripos($targetHost, $tld) === false){
continue;
}
if(empty($answer) && !is_array($answer)){
return;
}
foreach ($results as $result) {
if ($result->link === $targetUrl && !$result->partnershop) {
# Ein Advertiser gefunden
if ($result->image !== "") {
$result->logo = $partnershop["logo"];
} else {
$result->image = $partnershop["logo"];
}
$this->affiliates = $answer;
}
# Den Link hinzufügen:
$result->link = $partnershop["click_url"];
$result->partnershop = true;
$result->changed = true;
/**
* Converts all Affiliate Links.
*
* @param \App\Models\Result[] $results
*/
public function parseAffiliates(&$results)
{
if($this->finished || $this->affiliates === null){
return;
}
foreach ($this->affiliates as $partnershop) {
$targetUrl = $partnershop["url"];
$tld = $partnershop["tld"];
// Sometimes TLD is null
if(empty($tld)){
continue;
}
$targetHost = parse_url($targetUrl, PHP_URL_HOST);
/*
Adgoal sometimes returns affiliate Links for every URL
That's why we check if the corresponding TLD matches the orginial URL
*/
if($targetHost !== false && stripos($targetHost, $tld) === false){
continue;
}
$preference = config("metager.metager.affiliate_preference", "adgoal");
foreach ($results as $result) {
if ($result->originalLink === $targetUrl && (config("metager.metager.affiliate_preference", "adgoal") === "adgoal" || !$result->partnershop)) {
# Ein Advertiser gefunden
if ($result->image !== "" && !$result->partnershop) {
$result->logo = $partnershop["logo"];
} else {
$result->image = $partnershop["logo"];
}
# Den Link hinzufügen:
$result->link = $partnershop["click_url"];
$result->partnershop = true;
$result->changed = true;
}
}
} catch (\ErrorException $e) {
Log::error($e->getMessage());
} finally {
$requestTime = microtime(true) - $startTime;
\App\PrometheusExporter::Duration($requestTime, "adgoal");
}
return true;
$requestTime = microtime(true) - $this->startTime;
\App\PrometheusExporter::Duration($requestTime, "adgoal");
$this->finished = true;
}
}
<?php
namespace App\Models;
use Cache;
use Log;
use LaravelLocalization;
use Illuminate\Support\Facades\Redis;
class Admitad
{
const VALID_LANGS = [
"de",
"en"
];
public $hash;
public $finished = false; // Is true when the Request was sent to and read from Admitad App
private $affiliates = null;
/**
* Creates a new Admitad object which will start a request for affiliate links
* based on a result List from MetaGer.
* It will parse the Links of the results and query any affiliate shops.
*
* @param \App\MetaGer $metager
*/
public function __construct(&$metager)
{
$results = $metager->getResults();
// Generate a list of URLs
$resultLinks = [];
foreach($results as $result){
if ($result->new) {
$resultLinks[] = $result->originalLink;
}
}
if(empty($resultLinks)){
return;
}
$lang = LaravelLocalization::getCurrentLocale();
if(!in_array($lang, self::VALID_LANGS)){
$lang = "de";
}
$requestData = [
"lang" => $lang,
"urls" => $resultLinks,
];
$requestData = json_encode($requestData);
$this->hash = md5($requestData);
$url = "https://direct.metager.de/check";
$token = env("ADMITAD_TOKEN", "");
// Submit fetch job to worker
$mission = [
"resulthash" => $this->hash,
"url" => $url,
"useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0",
"username" => null,
"password" => null,
"headers" => [
"Authorization" => "Bearer $token"
],
"cacheDuration" => 60,
"name" => "Admitad",
"curlopts" => [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $requestData
]
];
$mission = json_encode($mission);
Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission);
}
/**
* Fetches the Admitad Response from Redis
* @param Boolean $wait Whether or not to wait for a response
*/
public function fetchAffiliates($wait = false) {
if($this->affiliates !== null){
return;
}
$answer = null;
$startTime = microtime(true);
if($wait){
while (microtime(true) - $startTime < 5) {
$answer = Cache::get($this->hash);
if ($answer === null) {
usleep(50 * 1000);
} else {
break;
}
}
}else{
$answer = Cache::get($this->hash);
}
$answer = json_decode($answer, true);
// If the fetcher had an Error
if($answer === "no-result"){
$this->affiliates = [];
return;
}
if(empty($answer) || !isset($answer["error"]) || $answer["error"] || !is_array($answer["result"])){
return;
}
$this->affiliates = $answer["result"];
}
/**
* Converts all Affiliate Links.
*
* @param \App\Models\Result[] $results
*/
public function parseAffiliates(&$results){
if($this->finished || $this->affiliates === null){
return;
}
foreach($this->affiliates as $linkResult){
$originalUrl = $linkResult["originalUrl"];
$redirUrl = $linkResult["redirUrl"];
$image = $linkResult["image"];
if(empty($redirUrl)){
// No Partnershop
continue;
}
foreach ($results as $result) {
if ($result->originalLink === $originalUrl && (config("metager.metager.affiliate_preference", "adgoal") === "admitad" || !$result->partnershop)) {
# Ein Advertiser gefunden
if ($result->image !== "" && !$result->partnershop) {
$result->logo = $image;
} else {
$result->image = $image;
}
# Den Link hinzufügen:
$result->link = $redirUrl;
$result->partnershop = true;
$result->changed = true;
}
}
}
$this->finished = true;
}
}
......@@ -4,12 +4,15 @@ namespace App\Models;
use Illuminate\Support\Facades\Redis;
use Request;
use \Carbon\Carbon;
class Key
{
public $key;
public $status; # valid key = true, invalid key = false, unidentified key = null
public $status; # Null If Key invalid | false if valid but has no adFreeSearches | true if valid and has adFreeSearches
private $keyserver = "https://key.metager.de/";
public $keyinfo;
const CHANGE_EVERY = 1 * 24 * 60 * 60;
public function __construct($key, $status = null)
{
......@@ -25,35 +28,29 @@ class Key
{
if ($this->key !== '' && $this->status === null) {
$this->updateStatus();
if(empty($this->status)){
if($this->status === null){
// The user provided an invalid key which we will log to fail2ban
$fail2banEnabled = config("metager.metager.fail2ban_enabled");
if(empty($fail2banEnabled) || !$fail2banEnabled || !env("fail2banurl", false) || !env("fail2banuser") || !env("fail2banpassword")){
return false;
if (!empty($fail2banEnabled) && $fail2banEnabled && !empty(env("fail2banurl", false)) && !empty(env("fail2banuser")) && !empty(env("fail2banpassword"))) {
// Submit fetch job to worker
$mission = [
"resulthash" => "captcha",
"url" => env("fail2banurl") . "/mgkeytry/",
"useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0",
"username" => env("fail2banuser"),
"password" => env("fail2banpassword"),
"headers" => [
"ip" => Request::ip()
],
"cacheDuration" => 0,
"name" => "Captcha",
];
$mission = json_encode($mission);
Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission);
}
// Submit fetch job to worker
$mission = [
"resulthash" => "captcha",
"url" => env("fail2banurl") . "/mgkeytry/",
"useragent" => "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0",
"username" => env("fail2banuser"),
"password" => env("fail2banpassword"),
"headers" => [
"ip" => Request::ip()
],
"cacheDuration" => 0,
"name" => "Captcha",
];
$mission = json_encode($mission);
Redis::rpush(\App\MetaGer::FETCHQUEUE_KEY, $mission);
}
}
if ($this->status === null || $this->status === false) {
return false;
} else {
return true;
}
return $this->status;
}
public function updateStatus()
......@@ -71,14 +68,15 @@ class Key
try {
$link = $this->keyserver . "v2/key/". urlencode($this->key);
$result = json_decode(file_get_contents($link, false, $context));
if ($result->{'apiAccess'} == 'unlimited') {
$this->status = true;
return true;
} else if ($result->{'apiAccess'} == 'normal' && $result->{'adFreeSearches'} > 0){
$this->status = true;
if(!empty($result)){
$this->keyinfo = $result;
if($this->keyinfo->adFreeSearches > 0 || $this->keyinfo->apiAccess === "unlimited"){
$this->status = true;
}else{
$this->status = false;
}
return true;
} else {
$this->status = false;
}else{
return false;
}
} catch (\ErrorException $e) {
......@@ -118,15 +116,26 @@ class Key
return false;
}
}
public function generateKey($payment)
public function generateKey($payment = null, $adFreeSearches = null, $key = null, $notes = "")
{
$authKey = base64_encode(env("KEY_USER", "test") . ':' . env("KEY_PASSWORD", "test"));
$postdata = http_build_query(array(
'payment' => $payment,
$postdata = array(
'apiAccess' => 'normal',
'notes' => 'Fuer ' . $payment . '€ aufgeladen am '. date("d.m.Y"),
'expiresAfterDays' => 365
));
'expiresAfterDays' => 365,
'notes' => $notes
);
if(!empty($key)){
$postdata["key"] = $key;
}
if(!empty($payment)){
$postdata["payment"] = $payment;
}else if(!empty($adFreeSearches)){
$postdata["adFreeSearches"] = $adFreeSearches;
}else{
return false;
}
$postdata = http_build_query($postdata, "", "&", PHP_QUERY_RFC3986);
$opts = array(
'http' => array(
'method' => 'POST',
......@@ -149,4 +158,89 @@ class Key
return false;
}
}
public function reduce($count){
$authKey = base64_encode(env("KEY_USER", "test") . ':' . env("KEY_PASSWORD", "test"));
$postdata = http_build_query(array(
'adFreeSearches' => $count,
));
$opts = array(
'http' => array(
'method' => 'POST',
'header' => [
'Content-type: application/x-www-form-urlencoded',
'Authorization: Basic ' . $authKey
],
'content' => $postdata,
'timeout' => 5
),
);
$context = stream_context_create($opts);
try {
$link = $this->keyserver . "v2/key/" . $this->key . "/reduce-searches";
$result = json_decode(file_get_contents($link, false, $context));
return $result;
} catch (\ErrorException $e) {
return false;
}
}
/**
* Tells if this key is liable to change to a custom key
* Currently only members are allowed to do so and only every 2 days
* Also only the original member key is allowed to be changed
*
* @return boolean
*/
public function canChange(){
if(empty($this->status) || !preg_match("/^Mitgliederschlüssel\./", $this->keyinfo->notes) || $this->keyinfo->adFreeSearches < \App\Http\Controllers\KeyController::KEYCHANGE_ADFREE_SEARCHES){
return false;
}
if(!empty($this->keyinfo->KeyChangedAt)){
// "2021-03-09T09:19:44.000Z"
$keyChangedAt = Carbon::createFromTimeString($this->keyinfo->KeyChangedAt, 'Europe/London');
if($keyChangedAt->diffInSeconds(Carbon::now()) > self::CHANGE_EVERY){
return true;
}else{
return false;
}
}
return true;
}
public function checkForChange($newkey = "", $hash){
$authKey = base64_encode(env("KEY_USER", "test") . ':' . env("KEY_PASSWORD", "test"));
$postdata = http_build_query(array(
'hash' => $hash,
'key' => $newkey,
));
$opts = array(
'http' => array(
'method' => 'POST',
'header' => [
'Content-type: application/x-www-form-urlencoded',
'Authorization: Basic ' . $authKey
],
'content' => $postdata,
'timeout' => 5
),
);
$context = stream_context_create($opts);
try {
$link = $this->keyserver . "v2/key/can-change";
$result = json_decode(file_get_contents($link, false, $context));
if(!empty($result) && $result->status === "success" && empty($result->results)){
return true;
}else{
return false;
}
} catch (\ErrorException $e) {
return false;
}
}
}
......@@ -9,6 +9,7 @@ class Result
{
public $provider; # Die Engine von der das Suchergebnis kommt
public $titel; # Der Groß Angezeigte Name für das Suchergebnis
public $originalLink;
public $link; # Der Link auf die Ergebnisseite
public $anzeigeLink; # Der tatsächlich angezeigte Link (rein optisch)
public $descr; # Die eventuell gekürzte Beschreibung des Suchergebnisses
......@@ -41,6 +42,7 @@ class Result
$this->provider = $provider;
$this->titel = $this->sanitizeText(strip_tags(trim($titel)));
$this->link = trim($link);
$this->originalLink = trim($link);
$this->anzeigeLink = trim($anzeigeLink);
$this->anzeigeLink = preg_replace("/(http[s]{0,1}:\/\/){0,1}(www\.){0,1}/si", "", $this->anzeigeLink);
$this->descr = $this->sanitizeText(strip_tags(trim($descr), '<p>'));
......
......@@ -179,7 +179,7 @@ spec:
{{ toYaml .Values.resourcesNginx | indent 12 }}
# Redis Container
- name: {{ .Chart.Name }}-redis
image: "redis:5.0.3-alpine"
image: "redis:6"
imagePullPolicy: {{ .Values.image.pullPolicy }}
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
volumeMounts:
......@@ -206,7 +206,7 @@ spec:
- name: {{ .Chart.Name }}-fetcher
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["su"]
args: ["-s", "/bin/sh", "-c", "php artisan requests:fetcher", "nginx"]
args: ["-s", "/bin/sh", "-c", "php artisan requests:fetcher", "www-data"]
volumeMounts:
- name: secrets
mountPath: /html/.env
......