primo upload

This commit is contained in:
claus75a
2024-03-16 20:37:32 +01:00
commit e43b9b4b28
3019 changed files with 406000 additions and 0 deletions
@@ -0,0 +1,32 @@
<?php
namespace Vanguard\Services\Auth\Social;
use Laravel\Socialite\Contracts\User as SocialUser;
trait ManagesSocialAvatarSize
{
/**
* Get appropriate image size for a specific provider.
*
* @param $provider
* @param SocialUser $socialUser
* @return mixed|string
*/
protected function getAvatarForProvider($provider, SocialUser $socialUser)
{
if ($provider == 'facebook') {
return str_replace('width=1920', 'width=150', $socialUser->avatar_original);
}
if ($provider == 'google') {
return $socialUser->avatar_original . '?sz=150';
}
if ($provider == 'twitter') {
return str_replace('_normal', '_200x200', $socialUser->getAvatar());
}
return $socialUser->getAvatar();
}
}
@@ -0,0 +1,73 @@
<?php
namespace Vanguard\Services\Auth\Social;
use Illuminate\Support\Str;
use Laravel\Socialite\Contracts\User as SocialUser;
use Vanguard\Repositories\Role\RoleRepository;
use Vanguard\Repositories\User\UserRepository;
use Vanguard\Support\Enum\UserStatus;
class SocialManager
{
use ManagesSocialAvatarSize;
public function __construct(private UserRepository $users, private RoleRepository $roles)
{
}
/**
* Associate social user with given provider. If user with the same email address
* retrieved from social network exists in our database, we will just associate it
* with provided social account. If not, user will be created.
*
* @param SocialUser $socialUser
* @param string $provider
* @return mixed|null|\Vanguard\User
*/
public function associate(SocialUser $socialUser, $provider)
{
$user = $this->users->findByEmail($socialUser->getEmail());
if (! $user) {
// User with email retrieved from social auth provider does not
// exist in our database. That means that we have to create new user here
list($firstName, $lastName) = $this->parseUserFullName($socialUser);
$role = $this->roles->findByName('User');
$user = $this->users->create([
'email' => $socialUser->getEmail(),
'password' => Str::random(10),
'first_name' => $firstName,
'last_name' => $lastName,
'status' => UserStatus::ACTIVE,
'avatar' => $this->getAvatarForProvider($provider, $socialUser),
'role_id' => $role->id,
'email_verified_at' => now()
]);
}
// Associate social account with user account inside our application
$this->users->associateSocialAccountForUser($user->id, $provider, $socialUser);
return $user;
}
/**
* Parse User's name from his social network account.
*
* @param SocialUser $user
* @return array
*/
private function parseUserFullName(SocialUser $user)
{
$name = $user->getName();
if (str_contains($name, " ")) {
return explode(" ", $name, 2);
}
return [$name, ''];
}
}
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace Vanguard\Services\Auth;
use Illuminate\Foundation\Auth\ThrottlesLogins as ThrottlesLoginsBase;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
trait ThrottlesLogins
{
use ThrottlesLoginsBase;
/**
* Get the login username to be used by the controller.
*
* @return string
*/
public function username()
{
return 'username';
}
/**
* Determine how many retries are left for the user.
*
* @param Request $request
* @return int
*/
protected function retriesLeft(Request $request)
{
$attempts = $this->limiter()->attempts(
$this->throttleKey($request)
);
return $this->maxAttempts() - $attempts + 1;
}
/**
* Redirect the user after determining they are locked out.
*
* @param Request $request
* @return RedirectResponse
*/
protected function sendLockoutResponse(Request $request)
{
$seconds = $this->limiter()->availableIn(
$this->throttleKey($request)
);
return redirect('login')
->withInput($request->only($this->username(), 'remember'))
->withErrors([
$this->username() => $this->getLockoutErrorMessage($seconds),
]);
}
/**
* Get the login lockout error message.
*
* @param int $seconds
* @return string
*/
protected function getLockoutErrorMessage($seconds)
{
return trans('auth.throttle', ['seconds' => $seconds]);
}
/** @inheritDoc */
protected function maxAttempts()
{
return setting('throttle_attempts', 5);
}
/** @inheritDoc */
protected function decayMinutes()
{
$lockout = (int) setting('throttle_lockout_time');
return $lockout <= 1 ? 1 : $lockout;
}
}
@@ -0,0 +1,81 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor;
trait Authenticatable
{
/**
* Get the e-mail address used for two-factor authentication.
*
* @return string
*/
public function getEmailForTwoFactorAuth()
{
return $this->email;
}
/**
* Get the country code used for two-factor authentication.
*
* @return string
*/
public function getAuthCountryCode()
{
return $this->two_factor_country_code;
}
/**
* Get the phone number used for two-factor authentication.
*
* @return string
*/
public function getAuthPhoneNumber()
{
return $this->two_factor_phone;
}
/**
* Set the country code and phone number used for two-factor authentication.
*
* @param $countryCode
* @param string $phoneNumber
*/
public function setAuthPhoneInformation($countryCode, $phoneNumber)
{
$this->two_factor_country_code = $countryCode;
$this->two_factor_phone = $phoneNumber;
}
/**
* Get the two-factor provider options in array format.
*
* @return array
*/
public function getTwoFactorAuthProviderOptions()
{
return json_decode($this->two_factor_options, true) ?: [];
}
/**
* Set the two-factor provider options in array format.
*
* @param array $options
* @return void
*/
public function setTwoFactorAuthProviderOptions(array $options)
{
$this->two_factor_options = json_encode($options);
}
/**
* Determine if the user is using two-factor authentication.
*
* @return bool
*/
public function getUsingTwoFactorAuthAttribute()
{
$options = $this->getTwoFactorAuthProviderOptions();
return isset($options['id']);
}
}
+107
View File
@@ -0,0 +1,107 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor;
use Exception;
use GuzzleHttp\Client as HttpClient;
use Vanguard\Services\Auth\TwoFactor\Contracts\Provider;
use Vanguard\Services\Auth\TwoFactor\Contracts\Authenticatable as TwoFactorAuthenticatable;
class Authy implements Provider
{
/**
* Determine if the given user has two-factor authentication enabled.
*
* @param TwoFactorAuthenticatable $user
* @return bool
*/
public function isEnabled(TwoFactorAuthenticatable $user)
{
$options = $user->getTwoFactorAuthProviderOptions();
return isset($options['enabled']) && $options['enabled'] === true;
}
/**
* Register the given user with the provider.
*
* @param TwoFactorAuthenticatable $user
*/
public function register(TwoFactorAuthenticatable $user)
{
$key = config('services.authy.key');
$response = json_decode((new HttpClient)->post('https://api.authy.com/protected/json/users/new?api_key='.$key, [
'form_params' => [
'user' => [
'email' => $user->getEmailForTwoFactorAuth(),
'cellphone' => preg_replace('/[^0-9]/', '', $user->getAuthPhoneNumber()),
'country_code' => $user->getAuthCountryCode(),
],
],
])->getBody(), true);
$user->setTwoFactorAuthProviderOptions([
'id' => $response['user']['id'],
]);
}
/**
* {@inheritdoc}
*/
public function sendTwoFactorVerificationToken(TwoFactorAuthenticatable $user)
{
$key = config('services.authy.key');
$options = $user->getTwoFactorAuthProviderOptions();
$response = json_decode((new HttpClient)->get(
'https://api.authy.com/protected/json/sms/'.$options['id'].'?force=true&api_key='.$key
)->getBody(), true);
return $response['success'] === true;
}
/**
* Determine if the given token is valid for the given user.
*
* @param TwoFactorAuthenticatable $user
* @param string $token
* @return bool
*/
public function tokenIsValid(TwoFactorAuthenticatable $user, $token)
{
try {
$key = config('services.authy.key');
$options = $user->getTwoFactorAuthProviderOptions();
$response = json_decode((new HttpClient)->get(
'https://api.authy.com/protected/json/verify/'.$token.'/'.$options['id'].'?force=true&api_key='.$key
)->getBody(), true);
return $response['token'] === 'is valid';
} catch (Exception $e) {
return false;
}
}
/**
* Delete the given user from the provider.
*
* @param TwoFactorAuthenticatable $user
* @return bool
*/
public function delete(TwoFactorAuthenticatable $user)
{
$key = config('services.authy.key');
$options = $user->getTwoFactorAuthProviderOptions();
(new HttpClient)->post(
'https://api.authy.com/protected/json/users/delete/'.$options['id'].'?api_key='.$key
);
$user->setTwoFactorAuthProviderOptions([]);
}
}
@@ -0,0 +1,27 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor;
use Illuminate\Support\ServiceProvider;
class AuthyServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->bind('authy', Authy::class);
}
/**
* @return array
*/
public function provides()
{
return ['authy'];
}
}
@@ -0,0 +1,52 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor\Contracts;
use Illuminate\Contracts\Auth\Authenticatable as BaseAuthenticatable;
interface Authenticatable extends BaseAuthenticatable
{
/**
* Get the e-mail address used for two-factor authentication.
*
* @return string
*/
public function getEmailForTwoFactorAuth();
/**
* Get the country code used for two-factor authentication.
*
* @return string
*/
public function getAuthCountryCode();
/**
* Get the phone number used for two-factor authentication.
*
* @return string
*/
public function getAuthPhoneNumber();
/**
* Set the country code and phone number used for two-factor authentication.
*
* @param integer $countryCode
* @param integer $phoneNumber
*/
public function setAuthPhoneInformation($countryCode, $phoneNumber);
/**
* Get the two-factor provider options in array format.
*
* @return array
*/
public function getTwoFactorAuthProviderOptions();
/**
* Set the two-factor provider options in array format.
*
* @param array $options
* @return void
*/
public function setTwoFactorAuthProviderOptions(array $options);
}
@@ -0,0 +1,47 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor\Contracts;
use Vanguard\Services\Auth\TwoFactor\Contracts\Authenticatable as TwoFactorAuthenticatable;
interface Provider
{
/**
* Determine if the given user has two-factor authentication enabled.
*
* @param Authenticatable $user
* @return bool
*/
public function isEnabled(TwoFactorAuthenticatable $user);
/**
* Register the given user with the provider.
*
* @param Authenticatable $user
*/
public function register(TwoFactorAuthenticatable $user);
/**
* Sends an SMS with a phone verification token.
* @param Authenticatable $user
* @return mixed
*/
public function sendTwoFactorVerificationToken(TwoFactorAuthenticatable $user);
/**
* Determine if the given token is valid for the given user.
*
* @param Authenticatable $user
* @param string $token
* @return bool
*/
public function tokenIsValid(TwoFactorAuthenticatable $user, $token);
/**
* Delete the given user from the provider.
*
* @param Authenticatable $user
* @return bool
*/
public function delete(TwoFactorAuthenticatable $user);
}
+18
View File
@@ -0,0 +1,18 @@
<?php
namespace Vanguard\Services\Auth\TwoFactor;
class Facade extends \Illuminate\Support\Facades\Facade
{
/**
* Get the registered name of the component.
*
* @return string
*
* @throws \RuntimeException
*/
protected static function getFacadeAccessor()
{
return 'authy';
}
}
+137
View File
@@ -0,0 +1,137 @@
<?php
namespace Vanguard\Services\Upload;
use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Str;
use Vanguard\User;
use Illuminate\Filesystem\Filesystem;
use Intervention\Image\ImageManager;
class UserAvatarManager
{
const AVATAR_WIDTH = 160;
const AVATAR_HEIGHT = 160;
/**
* @var User
*/
protected $user;
/**
* @var Filesystem
*/
private $fs;
/**
* @var ImageManager
*/
private $imageManager;
/**
* @var string Storage disk used for keeping photos.
*/
protected $disk = 'public';
public function __construct(FilesystemManager $fs, ImageManager $imageManager)
{
$this->fs = $fs->disk($this->disk);
$this->imageManager = $imageManager;
}
/**
* Upload and crop user avatar to predefined width and height.
*
* @param UploadedFile $file
* @param array|null $cropPoints
* @return string Avatar file name.
*/
public function uploadAndCropAvatar(UploadedFile $file, array $cropPoints = null)
{
try {
return $this->cropAndResizeImage($file, $cropPoints);
} catch (\Exception $e) {
logger("Cannot upload and crop image. " . $e->getMessage());
return null;
}
}
/**
* Check if user has uploaded avatar photo.
* If he is using some external url for avatar, then
* it is assumed that avatar is not uploaded manually.
*
* @param User $user
* @return bool
*/
private function userHasUploadedAvatar(User $user)
{
return $user->avatar && ! Str::contains($user->avatar, ['http', 'gravatar']);
}
/**
* Get destination directory where avatar should be uploaded.
*
* @return string
*/
private function getDestinationDirectory()
{
return '/upload/users';
}
/**
* @param User $user
*/
public function deleteAvatarIfUploaded(User $user)
{
if (! $this->userHasUploadedAvatar($user)) {
return;
}
$path = sprintf(
"%s/%s",
$this->getDestinationDirectory(),
$user->avatar
);
$this->fs->delete($path);
}
/**
* Crop image from provided selected points and
* resize it to predefined width and height.
*
* @param UploadedFile $file
* @param array|null $points
* @return string
*/
private function cropAndResizeImage(UploadedFile $file, array $points = null)
{
$image = $this->imageManager->make($file);
if ($points) {
// Calculate delta between two points on X axis. This
// value will be used as width and height for cropped image.
$size = floor($points['x2'] - $points['x1']);
$image->crop($size, $size, (int) $points['x1'], (int) $points['y1'])
->resize(self::AVATAR_WIDTH, self::AVATAR_HEIGHT);
} else {
// If crop points are not provided, we will just crop
// provided image to specified width and height.
$image->crop(self::AVATAR_WIDTH, self::AVATAR_HEIGHT);
}
$fileName = $file->hashName($this->getDestinationDirectory());
$this->fs->put(
$fileName,
$image->stream(null, 100)->__toString(),
'public'
);
return basename($fileName);
}
}