ソフトウェアのコピーレフトライセンスと非コピーレフト

OSS ライセンスの大まかな違い
– コピーレフトライセンス(GPLなど)の場合、配布者にソースコード公開の義務を負う
– 準コピーレフトライセンス(GNU Lesser General Public Licenseなど)は動的リンクとして使用した場合は、そこ以外の部分にはLGPLライセンスを適応させなくていい
– 非コピーレフトライセンス(MIT, Apache Licenseなど)の場合、成果物のソースコードを公開する義務を負わない(非公開にできる)

### Licenses一覧
– Apache License 2.0
 L 非コピーレフト型ライセンス
 L 著作権表示と免責事項表示の保持を求めている。
 L 使用、商用利用、改変、複製、公開、再配布、改変したものの配布、サブライセンス、アプリケーションへの埋め込み、特許技術の利用は可能
 L Trademarksに商標の使用を許可しない
 L 他のライセンスに比べるとルールが緩め
 L 利用割合 13%
 L Spring, Tomcat, Apache HTTP SERVER

– GNU General Public License v3.0
 L コピーレフト型ライセンス
 L ライセンシの派生物まで同じライセンスを求める
 L ライセンサが配布するOSSをライセンシが他のソフトウェアと組み合わせた場合、 ライセンサはライセンシに組み合わせ先のソフトウェアにまで同じライセンスの適用を要求
 L 著作権表示を保持しなければならない+無保証
 L GPLライセンスのオープンソース・フリーソフトウェアは、誰でも自由に複製・改変・頒布することが許可されている
 L 利用割合 14%
 L MySQL(GPL)

– MIT License
 L 非コピーレフト型ライセンス
 L 再配布時には著作権表示を残す+無保障
 L ザブライセンスや著作権者の許諾に関する内容が細かく記載されている
 L 利用割合 38%

– BSD 2-Clause “Simplified” License
 L 非コピーレフト型ライセンス
 L 再配布時には著作権表示を残す
 L 無保証
– BSD 3-Clause “New” or “Revised” License
 L 非コピーレフト型ライセンス
– Creative Commons Zero v1.0 Universal
 L 「著作権者のクレジット(名前)表記」のみが絶対の条件とされ、他に3つの使用条件を組み合わせる事で、著作権者の希望に沿ったランセンスを明示できる
– Eclipse Public License 2.0
– GNU Affero General Public License v3.0
 L コピーレフト型ライセンス
– GNU General Public License v2.0
 L コピーレフト型ライセンス
– GNU Lesser General Public License v2.1
 L 準コピーレフト型ライセンス
 L 動的リンクとして使用した場合は、そこ以外の部分にはLGPLライセンスを適応させなくていい
 L ライブラリやモジュールによく使用される
– GNU Lesser General Public License v3.0
 L 準コピーレフト型ライセンス
– Mozilla Public License 2.0

ライセンスは非常にセンシティブなところですな。

LaravelのDB::rawのエスケープとSQLインジェクション

SQL Injectionとは?
->アプリケーションが想定しないSQL文を実行させること

公式: https://readouble.com/laravel/6.x/ja/queries.html

rawメソッドはクエリを文字列として挿入するため、SQLインジェクションの脆弱性を生まないように十分気をつけてください。

DB::rawメソッド使用時にはエスケープされない。

 User::where(DB::raw('CONCAT(last_name, first_name)'), 'like', '%'.$text.'%')->get();

mysqlのlike演算子では、% と _ 特別な意味を持つが、DB::rawではエスケープされないので、$textに’%’や’_’が入っていた場合など、SQLインジェクションの脆弱性を生む。
$textの値は、¥%、¥¥、¥_と言うようにエスケープしないといけない。

以下のような使い方の場合は問題なしか。

User::select(DB::Raw('concat(last_name, first_name) as name'), 'id')

Laravelの詳細設計書で、MVCモジュール構成図を書いていきたい

### Laravelでの詳細設計の項目検討
– MVCモジュール構成図
– シーケンス図
– controller処理ロジック
– クロスサイトスクリプティング、SQLインジェクション対策
– 環境構築手順
– デプロイ・リリース手順
– テスト手順
– コーディングルール、その他

### LaravelのMVCモジュール構成図
モデル、コントローラ、ビューだけだと説明不足のように感じるので、Middleware、Eventなど、アプリケーションに使用しているclassも書いていくイメージか?

「開発工程は、要件定義→基本設計→詳細設計→プログラミング→単体テスト→結合テスト→総合テスト→運用テスト→本番移行」を鵜呑みにして、詳細設計書は実装の前に書くものかと思ってましたが、実際の実務では、ベテランエンジニアを除けばある程度実装してから書かないと、かなり手直しが発生するんなんじゃないかと思ってしまいます。

Laravel : http requestからルーティングまでのkernel処理の流れ

ユーザがアクセスしてきた時に、requestからresponseまでの処理がどうなっているのか?
1. /public/.httaccess が読み込まれる
2. RewriteCond %{REQUEST_FILENAME}により、該当ディレクトリ、該当ファイルが読み込まれる
3. /public/index.php が呼ばれる
4. index.phpにより、カーネル処理が登録される
5. ルーティング処理

### 1,2 /public/.httaccess
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
-> RewriteCondで、該当ディレクトリ、該当ファイルが読み込まれる
-> RewriteCond に記述した条件が満たされた時のみ RewriteRule に記述したURLの書き換えと転送が実行される

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews -Indexes
    </IfModule>

    RewriteEngine On

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} (.+)/$
    RewriteRule ^ %1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

### 3~4./public/index.php
– autoload.php、bootstrap/app.phpが読み込まれる
 (controllerのuse classを使用する為)
– アプリケーションインスタンスの生成
 (Illuminate\Foundation\Applicationのインスタンス)
– カーネル処理
 (app/Http/Kernel.phpに渡される。その際に「環境設定」「エラーハンドラー」「ミドルウェア」「サービスプロバイダ」などが読み込まれる)
 HTTPカーネルがサービスプロバイダを登録する際に、web.phpファイルが読み込まれる
– リクエストのディスパッチ

require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);
$response->send();
$kernel->terminate($request, $response);

### 5. Illuminate\Contracts\Http\Kernel

public function bootstrap();
public function handle($request);
public function terminate($request, $response);
public function getApplication();

### 6. ルーティング
– ファサードを使い、Illuminate\Routing\Routerクラスの各メソッドを使う

vendor/laravel/framework/src/illuminateに機能が揃ってますね。

Virtual Boxのハードウェア構成の見方

ここでは、amazon linux2のハードウェア構成を確認します。

### Oracle Virtual box マネージャを起動
OS:Linux 2.6 / 3.x / 4.x 64-bit
システム メインメモリー:1024MB
アクセラレーション: VT-x/AMD-V、ネステッドページング 、PAE/NX, KVM 準仮想化
ディスプレイ: ビデオメモリー16MB、グラフィックコントローラ VBoxVGA
ストレージ: box-disk001.vmdk(25.00GB)
ネットワーク アダプタ: Intel PRO/1000MT Desktop(NAT)

### CPU
ヘッダの設定から、システム、ディスプレイ、ストレージ、オーディオ、ネットワーク、ポート、共有フォルダなど設定可能

1CPU, メインメモリ1GBだと、t2.microと同じくらいのスペック

Laravel 6.x command(スケジューラ)の使い方

### make:command
$ php artisan make:command TestCommand

app/Console/Commands/TestCommand.php

protected $signature = 'command:testcommand';
public function handle()
    {
        //
        echo "test command execute!";
    }

app/Console/Kernel.php

 protected $commands = [
        //
        \App\Console\Commands\TestCommand::class,
    ];

    /**
     * Define the application's command schedule.
     *
     * @param  \Illuminate\Console\Scheduling\Schedule  $schedule
     * @return void
     */
    protected function schedule(Schedule $schedule)
    {
        // $schedule->command('inspire')
        //          ->hourly();
        $schedule->command('command:testcommand')->daily();
    }

### command実行
$ php artisan list;
$ php artisan command:testcommand;

$ crontab -e

実用性から考えると、バッチ処理はcronで直書きの方が楽そうですが、Githubなどで全てソースコードで管理したい場合は使えるかもしれません。どちらが良いかは好みやコンセンサスでしょうか。

Laravel Logの設定

### .env
Log channelはdefaultでstackに設定されている

LOG_CHANNEL=stack

### config/logging.php
stackで、channelsは’single’に設定されています。

'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single'],
            'ignore_exceptions' => false,
        ],

        'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
        ],
        // 省略
    ],

### ログの出力先
storate/logs/laravel.log

###コマンドラインで出力
less +F storage/logs/laravel.log

### controllerからログ出力
$ php artisan make:controller –resource LogController

Route::get('log', 'LogController@index');
public function index()
    {
        //
        \Log::info('ログ出力test');
        return 'test';
    }

heplerを使う場合

logger()->info('something has happened');

laravel.log

[2020-02-24 14:13:10] local.INFO: ログ出力test 
[2020-02-24 14:22:10] local.INFO: something has happened  

### ログレベル
emergency, alert, critical, error, warning, notice, info, debug

ログの設定は、運用体制と併せて柔軟に検討する必要がある。

Laravel 6.x softdeleteしたユーザ情報を取得

softdeleteしたユーザ情報を取得したい場合は、withTrashed();をコントローラやモデルで付与する。

### controller

User::withTrashed()->get();

### belongsToの場合

public function user(){
        return $this->belongsTo('App\User')->withTrashed();
    }

このようにすれば、わざわざViewで条件処理を加えなくて済む。

{{ $hoge->user ? $hoge->user->name : 'ユーザ削除済' }}

### User::query()の場合
-> 後ろにつける

$query = User::query()->withTrashed();

User::withTrashed()->query();とするとエラーになるので注意が必要