From 5e6c039b08f3c0c90329201b4eb083e637405992 Mon Sep 17 00:00:00 2001 From: Vinrobot <vinrobot97@gmail.com> Date: Thu, 8 Nov 2018 09:14:11 +0100 Subject: [PATCH 1/2] Added config to change Gravatar URL --- .env.example | 5 +++++ app/Auth/UserRepo.php | 2 +- app/Uploads/ImageService.php | 14 ++++++++++---- config/services.php | 1 + 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index eda20ea26..06394f54f 100644 --- a/.env.example +++ b/.env.example @@ -61,6 +61,11 @@ DISCORD_APP_SECRET=false # External services such as Gravatar and Draw.IO DISABLE_EXTERNAL_SERVICES=false +# Default GRAVATAR_URL set to Gravatar service +GRAVATAR_URL=false +# To use a different service to get user's avatar like libravatar +# Possible placeholders: %{hash} %{size} %{email} +#GRAVATAR_URL=https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon # LDAP Settings LDAP_SERVER=false diff --git a/app/Auth/UserRepo.php b/app/Auth/UserRepo.php index 7c88badb8..abff7c641 100644 --- a/app/Auth/UserRepo.php +++ b/app/Auth/UserRepo.php @@ -251,7 +251,7 @@ class UserRepo } try { - $avatar = Images::saveUserGravatar($user); + $avatar = Images::saveUserGravatar($user, config('services.gravatar_url')); $user->avatar()->associate($avatar); $user->save(); return true; diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index f109db600..b65a476f4 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -281,16 +281,22 @@ class ImageService extends UploadService /** * Save a gravatar image and set a the profile image for a user. * @param \BookStack\Auth\User $user + * @param null|string $gravatarUrl * @param int $size * @return mixed * @throws Exception */ - public function saveUserGravatar(User $user, $size = 500) + public function saveUserGravatar(User $user, $gravatarUrl, $size = 500) { - $emailHash = md5(strtolower(trim($user->email))); - $url = 'https://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; + if (!is_string($gravatarUrl) || empty($gravatarUrl)) { + $gravatarUrl = 'https://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'; + } + $email = strtolower(trim($user->email)); + $gravatarUrl = str_replace('%{hash}', md5($email), $gravatarUrl); + $gravatarUrl = str_replace('%{size}', $size, $gravatarUrl); + $gravatarUrl = str_replace('%{email}', urlencode($email), $gravatarUrl); $imageName = str_replace(' ', '-', $user->name . '-gravatar.png'); - $image = $this->saveNewFromUrl($url, 'user', $imageName); + $image = $this->saveNewFromUrl($gravatarUrl, 'user', $imageName); $image->created_by = $user->id; $image->updated_by = $user->id; $image->save(); diff --git a/config/services.php b/config/services.php index 711040386..b8f152124 100644 --- a/config/services.php +++ b/config/services.php @@ -19,6 +19,7 @@ return [ 'gravatar' => env('GRAVATAR', !env('DISABLE_EXTERNAL_SERVICES', false)), 'drawio' => env('DRAWIO', !env('DISABLE_EXTERNAL_SERVICES', false)), + 'gravatar_url' => env('GRAVATAR_URL', false), 'callback_url' => env('APP_URL', false), From b56fc21aafa08f8fd7a9909e20d7b9032b3080cb Mon Sep 17 00:00:00 2001 From: Dan Brown <ssddanbrown@googlemail.com> Date: Sat, 22 Dec 2018 19:29:19 +0000 Subject: [PATCH 2/2] Abstracted user avatar fetching away from gravatar Still uses gravatar as a default. Updated URL placeholders to follow LDAP format. Potential breaking config change: `GRAVATAR=false` replaced by `AVATAR_URL=false` Builds upon #1111 --- .env.example | 12 +++---- app/Auth/UserRepo.php | 17 ++++------ app/Console/Commands/CreateAdmin.php | 2 +- app/Http/Controllers/UserController.php | 2 +- app/Uploads/ImageService.php | 45 ++++++++++++++++++------- config/services.php | 9 +++-- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/.env.example b/.env.example index c839d254b..1005ad208 100644 --- a/.env.example +++ b/.env.example @@ -60,13 +60,13 @@ GITLAB_BASE_URI=false DISCORD_APP_ID=false DISCORD_APP_SECRET=false -# External services such as Gravatar and Draw.IO + +# Disable default services such as Gravatar and Draw.IO DISABLE_EXTERNAL_SERVICES=false -# Default GRAVATAR_URL set to Gravatar service -GRAVATAR_URL=false -# To use a different service to get user's avatar like libravatar -# Possible placeholders: %{hash} %{size} %{email} -#GRAVATAR_URL=https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon +# Use custom avatar service, Sets fetch URL +# Possible placeholders: ${hash} ${size} ${email} +# If set, Avatars will be fetched regardless of DISABLE_EXTERNAL_SERVICES option. +# AVATAR_URL=https://seccdn.libravatar.org/avatar/${hash}?s=${size}&d=identicon # LDAP Settings LDAP_SERVER=false diff --git a/app/Auth/UserRepo.php b/app/Auth/UserRepo.php index abff7c641..d436ab8eb 100644 --- a/app/Auth/UserRepo.php +++ b/app/Auth/UserRepo.php @@ -85,9 +85,7 @@ class UserRepo { $user = $this->create($data, $verifyEmail); $this->attachDefaultRole($user); - - // Get avatar from gravatar and save - $this->downloadGravatarToUserAvatar($user); + $this->downloadAndAssignUserAvatar($user); return $user; } @@ -238,25 +236,24 @@ class UserRepo } /** - * Get a gravatar image for a user and set it as their avatar. - * Does not run if gravatar disabled in config. + * Get an avatar image for a user and set it as their avatar. + * Returns early if avatars disabled or not set in config. * @param User $user * @return bool */ - public function downloadGravatarToUserAvatar(User $user) + public function downloadAndAssignUserAvatar(User $user) { - // Get avatar from gravatar and save - if (!config('services.gravatar')) { + if (!Images::avatarFetchEnabled()) { return false; } try { - $avatar = Images::saveUserGravatar($user, config('services.gravatar_url')); + $avatar = Images::saveUserAvatar($user); $user->avatar()->associate($avatar); $user->save(); return true; } catch (Exception $e) { - \Log::error('Failed to save user gravatar image'); + \Log::error('Failed to save user avatar image'); return false; } } diff --git a/app/Console/Commands/CreateAdmin.php b/app/Console/Commands/CreateAdmin.php index 6bfc54469..90c1ddb1c 100644 --- a/app/Console/Commands/CreateAdmin.php +++ b/app/Console/Commands/CreateAdmin.php @@ -76,7 +76,7 @@ class CreateAdmin extends Command $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]); $this->userRepo->attachSystemRole($user, 'admin'); - $this->userRepo->downloadGravatarToUserAvatar($user); + $this->userRepo->downloadAndAssignUserAvatar($user); $user->email_confirmed = true; $user->save(); diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 5f5c8365e..24f8b67cb 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -92,7 +92,7 @@ class UserController extends Controller $user->roles()->sync($roles); } - $this->userRepo->downloadGravatarToUserAvatar($user); + $this->userRepo->downloadAndAssignUserAvatar($user); return redirect('/settings/users'); } diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index b65a476f4..d5f4068ef 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -279,30 +279,51 @@ class ImageService extends UploadService } /** - * Save a gravatar image and set a the profile image for a user. + * Save an avatar image from an external service. * @param \BookStack\Auth\User $user - * @param null|string $gravatarUrl * @param int $size - * @return mixed + * @return Image * @throws Exception */ - public function saveUserGravatar(User $user, $gravatarUrl, $size = 500) + public function saveUserAvatar(User $user, $size = 500) { - if (!is_string($gravatarUrl) || empty($gravatarUrl)) { - $gravatarUrl = 'https://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'; - } + $avatarUrl = $this->getAvatarUrl(); $email = strtolower(trim($user->email)); - $gravatarUrl = str_replace('%{hash}', md5($email), $gravatarUrl); - $gravatarUrl = str_replace('%{size}', $size, $gravatarUrl); - $gravatarUrl = str_replace('%{email}', urlencode($email), $gravatarUrl); - $imageName = str_replace(' ', '-', $user->name . '-gravatar.png'); - $image = $this->saveNewFromUrl($gravatarUrl, 'user', $imageName); + + $replacements = [ + '${hash}' => md5($email), + '${size}' => $size, + '${email}' => urlencode($email), + ]; + + $userAvatarUrl = strtr($avatarUrl, $replacements); + $imageName = str_replace(' ', '-', $user->name . '-avatar.png'); + $image = $this->saveNewFromUrl($userAvatarUrl, 'user', $imageName); $image->created_by = $user->id; $image->updated_by = $user->id; $image->save(); + return $image; } + /** + * Check if fetching external avatars is enabled. + * @return bool + */ + public function avatarFetchEnabled() + { + $fetchUrl = $this->getAvatarUrl(); + return is_string($fetchUrl) && strpos($fetchUrl, 'http') === 0; + } + + /** + * Get the URL to fetch avatars from. + * @return string|mixed + */ + protected function getAvatarUrl() + { + return trim(config('services.avatar_url')); + } /** * Delete gallery and drawings that are not within HTML content of pages or page revisions. diff --git a/config/services.php b/config/services.php index 310ea295f..7b9cf4e74 100644 --- a/config/services.php +++ b/config/services.php @@ -16,11 +16,16 @@ return [ // Single option to disable non-auth external services such as Gravatar and Draw.io 'disable_services' => env('DISABLE_EXTERNAL_SERVICES', false), - 'gravatar' => env('GRAVATAR', !env('DISABLE_EXTERNAL_SERVICES', false)), + + // Draw.io integration active 'drawio' => env('DRAWIO', !env('DISABLE_EXTERNAL_SERVICES', false)), - 'gravatar_url' => env('GRAVATAR_URL', false), + // URL for fetching avatars + 'avatar_url' => env('AVATAR_URL', + env('DISABLE_EXTERNAL_SERVICES', false) ? false : 'https://www.gravatar.com/avatar/${hash}?s=${size}&d=identicon' + ), + // Callback URL for social authentication methods 'callback_url' => env('APP_URL', false), 'mailgun' => [