mardi 29 janvier 2019

How can I store random_bytes in a database in PHP?

Inside of my migration I have a string column named encryption_key which looks like this:

$table->string('encryption_key')->unique();

I have a Controller that uses a trait to generate the encryption commands.

use LiveChat;

public function create()
{
    $this->header->insert([
        'encryption_key' => $this->issueKey()
    ]);

    $this->participants->insert([
        'chat_id' => DB::getPdo()->lastInsertId(),
        'user_id' => Auth::id()
    ]);

    return response(['status' => true, 'chat_id' => DB::getPdo()->lastInsertId()], 200)
        ->header('Content-Type', 'application/json');
}

The trait looks like this so far

trait LiveChat
{
    protected function issueKey()
    {
        return random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
    }
}

However, upon testing this I receive this error:

SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect string value: '\xFFX\x8Af\x1F$...' for column 'encryption_key' at row 1 (SQL: insert into chat_headers (encryption_key) values (ÿXŠf\x1F$¨ì™ÒÂø¢Ú!£”…¸ÈÍØ7ÿDå\x00Œ¿3ê))

If I use dd() to debug the response of $this->issueKey() I get something like this:

b"Bp,[\x1A\¢®ù·š(×g6ùs=l«j,©;_ó8ýòúÍ6"

How can I store this key to use for future reference inside my DB?



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2G8kenZ
via IFTTT

Issue with Laravel 5.7 Authentication - multi auth

I am trying to implement a user registration system in Laravel 5.7 where I am facing an issue.

I have two tables for Users- Admin(created by copying default Laravel auth), new routes, new middleware for admin. Every thing works fine while using guards.

But the issue started when I wanted to limit the user login and add Approve/Disapprove functionality.

I tried to add a extra column - admin(boolean) to the Users.

In Login controller - LoginController.php Page, I added

  protected function authenticated($request, $user)
    {
        if ( $request->user()->admin != 1)
        // if($user->admin != 1)
        {
            return redirect()->route('approval');
        }
        else
        {
            return redirect('/engineer');
        }
    }

when the admin is 1 I an directed to '/enginner' where as in other case I am directed to 'approval'.

Its also working as desired!.

The real issue I am now facing is that if I try to access the 'engineer' using user whose not approved I am able to access the page. I am not sure how to restrict it. The page is still restricted to public.

Since the controller will be accessed by both the user and admin, I used __construct in the controller

web.php

Route::resource('engineer', 'engineerController');

engineerController.php

public function __construct()
        {
            $this->middleware('auth:web,admin');
        }

I am a self learner and new to laravel. I am pretty sure that I am not following the right practice. I started something and was trying to follow it till I finish. Please guide me through it.

Along with it please let me how could I have done it better.



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2FWsFU4
via IFTTT

Laravel - Eager Loading

I'm trying to understand Eager Loading using Laravel to avoid generating a lot of unnecessary queries. I want to get 15 last added Posts and also get their rates from relationship of my rates table (before I was getting Posts and later in foreach I was calling for $item->avgRate() that creates 15 additional queries :S).

My Post model:

public function rates()
{
    return $this->hasMany(Rate::class);
}

public function scopeLastAdded($query, $limit = 15)
{
    return $query->latest()->limit($limit)->with('rates')->get();
}

This works, for each post, I'm also getting all rates, but the main goal is to make some function to calculate avg rate for each post and not retrieve all rates. I created a new method:

public function avgRate()
{
    return number_format($this->rates()->avg('rate'), 1, '.', '');
}

When I use with('avgRate') my model fails:

Call to a member function addEagerConstraints() on string

How can I get avgRate in some clean way with my last 15 Posts to perform only 2 queries and not 16?

Expected output:

// Post view
@foreach ($posts as $post)
   <div></div>
   <div></div> //I want to get data without performing 15 queries
@endforeach



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2B6A4w0
via IFTTT

How fix error on redirect with parameters?

Having defined routes in routes/web.php as:

Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
...
Route::resource('box-rooms', 'Admin\StorageSpacesController', [ 'as' => 'box-rooms', 'except' => [] ] )->middleware('WorkTextString');
Route::get( 'get-box-rooms-dt-listing', [ 'uses' => 'Admin\StorageSpacesController@get_storage_spaces_dt_listing' ] );

In control I try to redirect :

return redirect()->route('box-rooms.index', [ 'id'=>$requestData['check_in_client_id'],'action'=>'check_in' ]);
OR
return redirect()->route('admin.box-rooms.index', [ 'id'=>$requestData['check_in_client_id'],'action'=>'check_in' ]);

But in both cases I got error that route is not defined. Why eror?

laravel 5.7

Thanks in advance!



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2SkkU0d
via IFTTT

How can I dynamically change the keys that Crypt uses in Laravel?

I have been researching how to use Laravel Encryption as building a homestead encryption platform is frowned upon and rightfully so.

Illuminate\Support\Facades\Crypt::encryptString('This is a secret message from user 1 to user 2');

Take the above example, this is using my APP_KEY which derives from my .env file, generation previously by php artisan key:generate. The issue is that user 1 is never issued two sets of keys to communicate only to user 2. User 3, 4 and so on could still read this message using the Illuminate\Support\Facades\Crypt::decryptString method.

Currently, my database is set up to have a chat header. This contains information about what is communicating. All participants will use these keys for encryption and decryption - thus any outside users not being able to decrypt the messages.

public function up()
{
    Schema::create('chat_headers', function(Blueprint $table) {
        $table->increments('id');

        $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
        $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

        $table->string('private_key')->unique();
        $table->string('public_key')->unique();
    });
}

I also have a chat participants, this contains information about who is communicating:

public function up()
{
    Schema::create('chat_participants', function(Blueprint $table) {
        $table->increments('id');

        $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
        $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

        $table->integer('user_id')->unsigned();

        # TODO: Build RBAC

        $table->index(['user_id']);
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
    });
}

Finally, I have a table for message logs. This contains the encrypted message followed by what chat room they're associating with.

public function up()
{
    Schema::create('chat_messages', function(Blueprint $table) {
        $table->increments('id');

        $table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
        $table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));

        $table->integer('chat_id')->unsigned();
        $table->string('message');

        $table->index(['chat_id']);
        $table->foreign('chat_id')->references('id')->on('chat_headers')->onDelete('cascade');
    });
}

How can I dynamically assign new keys to the Illuminate\Support\Facades\Crypt to use in order to encrypt messages between a chat party?



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2HGyR4i
via IFTTT

How to test and mock guzzle responses in different situations?

I want to test my API controller that using some guzzle requests from another services. I have one request for making a download link.

  1. this is my API route

    Route::group(['prefix' => '/v1'], function () {
    Route::get('/exampledl', 'DownloadController@downloadChecker');
    });
    
    
  2. DownloadChecker controller checks if user is admin or subscriber makes a guzzle request to one of my services on a different domain, if not do another Guzzle request to another service and for each situations responses are different. This is a part of controller checks admin role.

    $client = new Client();
    try {
        $response = $client->request('GET', 'https://www.example.com/api/user?u=' . $request->uid);
        $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True);
    
        // if user doesn't exist in CM
    
        //this part has been written to avoid repeating code
        if (array_key_exists('user', $json) && $json['user'] == null) {
            abort(403);
        }
        elseif (in_array("administrator", $json['Roles'])) {
            User::create([
                'uid'               => (int)$request->uid,
                'subscription.role' => 'administrator',
            ]);
            $client = new Client();
    $response = $client->request('GET', "https://vod.example2.com/vod/2.0/videos/{$a_id}?secure_ip={$u_ip}", [
        'headers' => [
            'authorization' => '**********'
        ]
    ]);
    $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), TRUE);
    
    if (isset($json['data']['mp4_videos'])) {
        $links = [];
        foreach ($json['data']['mp4_videos'] as $mp_video) {
            if (stripos($mp_video, "h_144") !== false) {
                $links['144p'] = $mp_video;
            }
            elseif (stripos($mp_video, "h_240") !== false) {
                $links['240p'] = $mp_video;
            }
            elseif (stripos($mp_video, "h_360") !== false) {
                $links['360p'] = $mp_video;
            }
            elseif (stripos($mp_video, "h_480") !== false) {
                $links['480p'] = $mp_video;
            }
            elseif (stripos($mp_video, "h_720") !== false) {
                $links['720p'] = $mp_video;
            }
            elseif (stripos($mp_video, "h_1080") !== false) {
                $links['1080p'] = $mp_video;
            }
        }
        }
    
    
  3. one of my tests.

    public function test_user_notExist_admin()
    {
    $client = new Client();
    $response = $client->request('GET', 'https://www.example.com/api/user_days_and_roles?u=' . request()->uid);
    $json = \GuzzleHttp\json_decode($response->getBody()->getContents(), True);
    
    $this->get('/api/v1/exampledl?uid=1&n_id=400&u_ip=104.58.1.45&arvan_id=a81498a9')
        ->assertStatus(200)
        ->assertSee('links');
    
    $this->assertDatabaseHas('users', [
        'uid'               => (int)request('uid'),
        'subscription.role' => 'administrator',
    ]);
    }
    
    

There are some other conditions check and I'm not sure how to mock these different situations.

Should I make unit test for every situations? Or is there any way to make guzzle in test environment return a custom response? Or any other way?



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2B97GcG
via IFTTT

Laravel not retrieving milliseconds in DateTime columns

In Laravel, I have some columns with milliseconds. Note that some other columns do not have milliseconds (e.g. created_at, updated_at).

Here is my migration:

Schema::create('brands', function (Blueprint $table) {
    $table->increments('id');
    $table->dateTime('sync_date_time', 3);
    $table->timestamps();
});

My model is simply:

class Brand extends Model {}

Yet when I have a record with milliseconds (e.g. 2018-12-19 01:40:46.512) , and execute:

$brand->sync_date_time;

It always returns a string without the milliseconds portion (e.g. 2018-12-19 01:40:46).

Why is this happening, and how can I fix this issue?

Note that this is not a Carbon issue, as I am not using Carbon for this field at all.



from Newest questions tagged laravel-5 - Stack Overflow http://bit.ly/2RUNZzz
via IFTTT