Skip to content

Commit

Permalink
Merge pull request #453 from statonlab/magic-link
Browse files Browse the repository at this point in the history
Magic link
  • Loading branch information
jwest60 authored May 14, 2019
2 parents 6009e15 + 9588983 commit dd6627c
Show file tree
Hide file tree
Showing 13 changed files with 352 additions and 7 deletions.
20 changes: 19 additions & 1 deletion app/Http/Controllers/ObservationsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
use App\Observation;
use App\Services\MetaLabels;
use App\User;
use App\ShareToken;
use Illuminate\Support\Carbon;
use Illuminate\Http\Request;
use App\Events\ObservationDeleted;
use Storage;
Expand Down Expand Up @@ -140,7 +142,23 @@ public function show($id, Request $request)
]);
}

return $this->success($this->getObservationJson($observation, $is_admin, $user));
$info = $this->getObservationJson($observation, $is_admin, $user);
$token = $request->token;

if ($token)
{
$share_token = ShareToken::where('value', $token)
->where('observation_id', $id)
->first();

if ($share_token && $share_token->expired_at >= Carbon::now())
{
$info['location']['latitude'] = $observation->latitude;
$info['location']['longitude'] = $observation->longitude;
}
}

return $this->success($info);
}

/**
Expand Down
65 changes: 65 additions & 0 deletions app/Http/Controllers/ShareTokensController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

namespace App\Http\Controllers;

use App\Observation;
use App\ShareToken;
use App\User;
use App\Http\Controllers\Traits\Responds;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class ShareTokensController extends Controller
{
use Responds;

/**
* Attempts to create a share link if the user is authorized to do so.
*
* @param $id
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\JsonResponse
*/
public function share($id, Request $request)
{
$user = $request->user();

$observation = Observation::findOrFail($id);

if ($observation->user_id !== $user->id) {
return $this->unauthorized();
}

$share_token = $this->createShareToken($user, $observation, $request);

return $this->success(
"https://treesnap.org/observation/$observation?token=$share_token->value"
);
}

/**
* Creates a token for the share URL.
*
* @param $user
* @param $observation
* @param $request
* @return mixed
*/
protected function createShareToken($user, $observation, $request)
{
$rand = Str::random(60);
while (ShareToken::where('value', $rand)->first()) {
// Key already exists so generate a new one
$rand = Str::random(60);
}

return ShareToken::create([
'user_id' => $user->id,
'email' => $request->email,
'observation_id' => $observation->id,
'value' => $rand,
'expires_at' => Carbon::now()->addYear(),
]);
}
}
49 changes: 49 additions & 0 deletions app/ShareToken.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class ShareToken extends Model
{
/**
* Fillable fields.
*
* @var array
*/
protected $fillable = [
'user_id',
'observation_id',
'expired_at',
'value',
];

/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $casts = [
'expired_at' => 'date',
];

/**
* Get the related user (sender).
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function user()
{
return $this->belongsTo('App\User');
}

/**
* Get the related observation.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function observation()
{
return $this->belongsTo('App\Observation');
}
}
9 changes: 9 additions & 0 deletions database/factories/ModelFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,15 @@ function fuzifyCoorinates($original_latitude, $original_longitude)
];
});

$factory->define(\App\ShareToken::class, function (Faker\Generator $faker) {
return [
'user_id' => factory(\App\User::class)->create()->id,
'observation_id' => factory(\App\Observation::class)->create()->id,
'value' => str_random(60),
'expired_at' => \Carbon\Carbon::now()->addYear(),
];
});

/** @var \Illuminate\Database\Eloquent\Factory $factory */
$factory->define(\App\SubscriptionTopic::class, function (Faker\Generator $faker) {
return [
Expand Down
37 changes: 37 additions & 0 deletions database/migrations/2019_05_08_175701_create_sharetokens_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateSharetokensTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('share_tokens', function (Blueprint $table) {
$table->bigIncrements('id');
$table->integer('user_id')->unsigned()->index();
$table->integer('observation_id')->unsigned()->index();
$table->string('value'); //->unique();
$table->timestamp('expired_at');
$table->timestamps();

$table->unique(['observation_id', 'value']);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('share_tokens');
}
}
1 change: 0 additions & 1 deletion public/js/4.45f52025495e7ada03e4.js

This file was deleted.

1 change: 1 addition & 0 deletions public/js/4.9f880df94c887757ba35.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/app.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion public/js/manifest.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions public/mix-manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"/js/vendor.js": "/js/vendor.js?id=da80df012039296cf353",
"/js/app.js": "/js/app.js?id=77c4fd7378b4f0f4e511",
"/js/app.js": "/js/app.js?id=bd3cc394c89877199d74",
"/css/app.css": "/css/app.css?id=076495e51d1dc3726549",
"/js/admin.js": "/js/admin.js?id=75c7242ae22087a5578f",
"/js/manifest.js": "/js/manifest.js?id=a0d339095905614077ad"
"/js/manifest.js": "/js/manifest.js?id=693e2b0facddc2e283d4"
}
1 change: 0 additions & 1 deletion resources/assets/js/scenes/ObservationScene.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export default class ObservationScene extends Scene {
}
}


componentDidMount() {
let id = this.props.match.params.id
this.loadObservation(id)
Expand Down
3 changes: 3 additions & 0 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
// Observations
Route::delete('/web/observation/{id}', 'ObservationsController@delete');

// Shareable Links
Route::get('/web/share/observation/{id}', 'ShareTokensController@share');

// Filters
Route::delete('/web/filter/{id}', 'FiltersController@delete');
Route::get('/web/filter/{id}', 'FiltersController@show');
Expand Down
Loading

0 comments on commit dd6627c

Please sign in to comment.