Kategorien
Symfony

Symfony mögliche Konfigurationsparameter anzeigen

Um eine alle möglichen Config Parameter eines Packetes anzuzeigen, kann man folgenden Konsolenbefehl verwenden:

php bin/console config:dump-reference doctrine_migrations

Ausgabe:

# Default configuration for extension with alias: "doctrine_migrations"
doctrine_migrations:

    # A list of namespace/path pairs where to look for migrations.
    migrations_paths:

        # Prototype
        namespace:            ~

    # A set of services to pass to the underlying doctrine/migrations library, allowing to change its behaviour.
    services:

        # Prototype
        service:              ~

    # A set of callables to pass to the underlying doctrine/migrations library as services, allowing to change its behaviour.
    factories:

        # Prototype
        factory:              ~

    # Storage to use for migration status metadata.
    storage:

        # The default metadata storage, implemented as a table in the database.
        table_storage:
            table_name:           null
            version_column_name:  null
            version_column_length: null
            executed_at_column_name: null
            execution_time_column_name: null

    # A list of migrations to load in addition to the one discovered via "migrations_paths".
    migrations:           []

    # Connection name to use for the migrations database.
    connection:           null

    # Entity manager name to use for the migrations database (available when doctrine/orm is installed).
    em:                   null

    # Run all migrations in a transaction.
    all_or_nothing:       false

    # Adds an extra check in the generated migrations to allow execution only on the same platform as they were initially generated on.
    check_database_platform: true

    # Custom template path for generated migration classes.
    custom_template:      null

    # Organize migrations mode. Possible values are: "BY_YEAR", "BY_YEAR_AND_MONTH", false
    organize_migrations:  false

    # Use profiler to calculate and visualize migration status.
    enable_profiler:      false

    # Whether or not to wrap migrations in a single transaction.
    transactional:        true
Kategorien
PHP Symfony

PHP Anwendungen automatisiert modernisieren mit rector

Das Tool rector ist eine Konsolenanwendung für automatisiertes Refactoring von PHP Anwendungen.

Damit lassen sich schnell einfache Altlasten entfernen aus Legacy Projekten.

Mit dem folgenden Rector Script (./rector.php) können die gängigsten Refactorings durchgeführt werden:

<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\SetList;

return static function (RectorConfig $rectorConfig): void {
    $setLists = [
        SetList::PHP_52,
        SetList::PHP_53,
        SetList::PHP_54,
        SetList::PHP_55,
        SetList::PHP_56,
        SetList::PHP_70,
        SetList::PHP_71,
        SetList::PHP_72,
        SetList::PHP_73,
        SetList::PHP_74,
        SetList::PHP_80,
        SetList::PHP_81,
        SetList::ACTION_INJECTION_TO_CONSTRUCTOR_INJECTION,
        SetList::CODE_QUALITY,
        SetList::CODING_STYLE,
        SetList::DEAD_CODE,
        SetList::EARLY_RETURN,
        SetList::GMAGICK_TO_IMAGICK,
        SetList::MONOLOG_20,
        SetList::MYSQL_TO_MYSQLI,
        SetList::NAMING,
        SetList::PRIVATIZATION,
        SetList::TYPE_DECLARATION,
        SetList::TYPE_DECLARATION_STRICT,
    ];

    foreach($setLists as $setList) {

        $rectorConfig->import(
            $setList
        );
    }

    $rectorConfig->paths([
        __DIR__.'/src',
        __DIR__.'/tests',
    ]);
};

ausführbar im Dry mode ohne Änderungen am Code mit:

vendor/bin/rector process --debug --dry-run

Kategorien
Docker Symfony

SSO Saml Login mit Symfony

Single-Sign-On ist das Thema der Stunde, es verbessert die Sicherheit und auch die User Verwaltung. Um Saml SSO in Symfony einzubauen gibt es das OneloginSaml Bundle, ein Symfony Wrapper für das php-saml Packet.

Der Vorteil für die Benutzer von SSO liegt darin, dass diese sich morgens einmal authentifizieren müssen und danach den ganzen Tag alle Anwendungen verwenden können ohne sich nochmals einloggen zu müssen.

Der Vorteil für das Unternehmen liegt darin, dass es vorgeben kann, dass die Authentifierung nur mit 2 Faktor Authentifizierung stattfinden kann (z.B. Handy App und Passwort), um mehr Sicherheit zu gewährleisten. Dies kannn in der Zukunft den steigendenden Sicherheitsbedürfnissen angepasst werden. Außerdem können zentral Rechte vergeben werden für User und nach dem Austritt aus dem Unternehmen einfach wieder entzogen werden.

Wenn das Bundle installiert und korrekt konfiguriert ist, benötigt man eine Dev-Umgebung mit einem Identity Provider (IdP). Dafür bietet sich docker-simplesamlphp an:

docker-compose.yml:

version: '3.7'
services:
	idp:
		image: kenchan0130/simplesamlphp
		container_name: idp
		ports:
			- "8080:8080"
		environment:
			SIMPLESAMLPHP_SP_ENTITY_ID: http://localhost/saml/metadata
			SIMPLESAMLPHP_SP_ASSERTION_CONSUMER_SERVICE: http://localhost/saml/acs
			SIMPLESAMLPHP_SP_SINGLE_LOGOUT_SERVICE: http://localhost/saml/logout

Das OneloginSaml Bundle muss folgender Maßen konfiguriert werden:

hslavich_onelogin_saml:
  # Basic settings
  idp:
    # Identifier of the SP entity  (must be a URI)
    entityId: 'http://localhost:8080/simplesaml/saml2/idp/metadata.php'
    singleSignOnService:
      url: 'http://localhost:8080/simplesaml/saml2/idp/SSOService.php'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    singleLogoutService:
      url: 'http://localhost:8080/simplesaml/saml2/idp/SingleLogoutService.php'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    x509cert: 'insert certificate here'
  # Service Provider Data that we are deploying.
  sp:
    entityId: 'http://localhost/saml/metadata'
    assertionConsumerService:
      url: 'http://localhost/saml/acs'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
    singleLogoutService:
      url: 'http://localhost/saml/logout'
      binding: 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect'
    privateKey: ''

Die Informationen kann man hier ablesen, auch die vom Zertifikat:

SAML Metadata: http://localhost:8080/simplesaml/saml2/idp/metadata.php?output=xhtml

Wenn man alles richtig konfiguriert hat, dann landet man beim Aufruf der Symfony Anwendung auf der Login Seite des IdP Providers und kann sich dort einloggen:

Login Seite des IdP Providers

Die Logins lauten:

admin:     secret
user1:     password
user2:     password

Dann sollte man sich mit seiner Symfony Applikation lokal über SAML einloggen und testen können.

Kategorien
PHP Symfony Testing

Symfony System-Test für valide Konfiguration der Umgebungen

Es gibt in Symfony die Möglichkeit mehrere Umgebungen (Environments) anzulegen und verschiedenartig zu konfigurieren. Das Problem ist, dass die automatisierten Tests immer gegen die Test-Umgebung und somit auch gegen die Test-Konfiguration gemacht werden.

Wie kann man sicher gehen, dass die produktive Konfiguration valide ist und dies mit einem automatisierten Test absichern?

Die Antwort ist sehr einfach, sollte eine Umgebungs-Konfiguration syntaktisch falsch sein, schlägt der Test fehl:

<?php

namespace App\Tests\System;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class BootKernelTest extends WebTestCase
{

    /**
     * @return array
     */
    public function dataProviderTestBootKernel(): array
    {
        return [
            'dev' => ['dev'],
            'test' => ['test'],
            'prod' => ['prod'],
        ];
    }

    /**
     * the test would fail if the environment config is wrong
     *
     * @dataProvider dataProviderTestBootKernel
     *
     * @param string $environment
     * @return void
     */
    public function testBootKernel(string $environment)
    {
        $kernel = $this->bootKernel(['environment' => $environment]);

        $this->assertNotEmpty($kernel);
    }

}

Kategorien
Symfony

Symfony Cache mit Datenbank

Die Symfony Cache Komponente besitzt eine große Zahl von möglichen Adaptern zum Cachen von Informationen.

Zum Cachen in der Datenbank kann man den folgenden PdoAdapter für Doctrine verwenden und folgender Maßen konfigurieren:

#config/packages/framework.yaml
framework:
    cache:
        pools:
            app:
                adapter: AppCache
#config/services.yaml
AppCache:
  class: Symfony\Component\Cache\Adapter\PdoAdapter
  arguments:
    - '@doctrine.dbal.default_connection'

Damit erzeugt Symfony eine Datenbank Tabelle innerhalb der default Datenbank Verbindung für die Cache Einträge.

Dies hat besonders Performancegewinne und ist übersichtlicher im Vergleich zu  der Default-Filesystem-Variante. Besonders ist dies für eine Docker Umgebung zu empfehlen, weil das langsame Dateisystem nicht verwnedet werden muss.

Kategorien
Symfony

Symfony 5 Exception „The annotation was never imported.“

Ein Grund der Fehlermeldung kann sein, dass es tatsächlich eine Annotation ist, die ungültig ist, sich aber im vendor Code befindet. Dann sollte man diese ignorieren.

Fehlermeldung:

Doctrine\Common\Annotations\AnnotationException : [Semantical Error] The annotation "@suppress" in method Monolog\Formatter\LineFormatter::normalizeException() was never imported. Did you maybe forget to add a "use" statement for this annotation?

Sollte man die Annotation ignorieren mit dem statischen Aufruf von in der config/bootstrap.php:

AnnotationReader::addGlobalIgnoredName('suppress');

 

Kategorien
Amazon AWS Symfony

Monolog Logging für AWS Cloudwatch Logs konfigurieren

Damit die Logs schön formatiert aus einer Symfony 4 Anwendung in AWS Cloudwatch ankommen, muss man Monolog folgendermaßen konfigurieren:

# config/services.yaml
Monolog\Formatter\JsonFormatter:
    calls:
        - [includeStacktraces]

und

# config/packages/prod/monolog.yaml
monolog:
  handlers:
    main:
      type:  stream
      level: error
      path:  '%kernel.logs_dir%/error.log'
      formatter: Monolog\Formatter\JsonFormatter

Danach muss man der Cloudwatch Daemon konfigurieren:

# /etc/awslogs/awslogs.conf
[general]
# Path to the CloudWatch Logs agent's state file. The agent uses this file to maintain
# client side state across its executions.
state_file = /var/lib/awslogs/agent-state

[/var/www/html/var/log/error.prod.log]
datetime_format = [%Y-%m-%d H:%M:%S]
file = /var/www/html/var/log/error.log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = test_group_name/error_log

und man erhält wunderbare (aggregierte) ErrorLog Informationen in Cloudwatch Logs Insight:

 

 

Kategorien
Symfony

Symfony Switftmailer Mail wird nicht gesendet

Mit dem folgende Befehl kann eine Testmail versendet werden mit Swiftmailer. Falls die Email nicht ankommt, sind die Switftmailer Parameter in config/packages/swiftmailer.yaml wahrscheinlich falsch:

php bin/console swiftmailer:email:send --help

Da die Email mit eine Queue versendet werden, sollte trotzdem in das error_log untersucht werden unter var/log/, darin fand sich bei mir der Grund für mein Versand Problem:

app.ERROR: Exception occurred while flushing email queue: Expected response code 250 but got code "554", with message "554 Message rejected: 
Email address is not verified. The following identities failed the check in region EU-WEST-1: email1, email2

 

Kategorien
Symfony

Symfony Sonata Redirect der Root URL in den Adminbereich

Wenn man den User bei der Eingabe im Browser ohne ein Pfad (www.foo.de) zum Adminbereich von Sonata (www.foo.de/admin) weiterleiten will, kann man dies sehr elegant mittels eines Symfony Redirects in der routing.yml tun:

index:
  path: /
  defaults:
    _controller: FrameworkBundle:Redirect:urlRedirect
    path: /admin
    permanent: true
Kategorien
Symfony

Tutorial: Symfony Administrations-Backend erstellen

In diesem Beitrag werde ich mit Symfony 4 eine Administartionsoberfläche mit Hilfe von Sonata erstellen und die einzelnen Schritte beschreiben.

1. Anlegen eines neuen Symfony Projektes

Mit composer kann man schnell ein neues Symfony Skeleton Projekt anlegen lassen:

composer create-project symfony/website-skeleton my-admin-demo

Das Skeleton Projekt enthält die wichtigsten Symfony Komponenten für eine Webapplikation sowie Doctrine.

Jetzt ist ein guter Zeitpunkt das Porjket in ein Versionierungsystem wie GIT einzuchecken und zum ersten mal zu committen.

Optional kann jetzt Symfony PHPUnit Bridge installiert werden, wenn Tests geschrieben werden sollen:

composer require phpunit --dev

Die Datenbank kann jetzt konfiguriert werden in der .env Datei:

DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name

Und mit folgendem Befehl angelegt werden:

php bin/console doctrine:database:create

2. Installation des SonataAdmin Bundles