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
This commit is contained in:
Dan Brown 2018-12-22 19:29:19 +00:00
parent d673bf61c2
commit b56fc21aaf
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
6 changed files with 55 additions and 32 deletions

View File

@ -60,13 +60,13 @@ GITLAB_BASE_URI=false
DISCORD_APP_ID=false DISCORD_APP_ID=false
DISCORD_APP_SECRET=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 DISABLE_EXTERNAL_SERVICES=false
# Default GRAVATAR_URL set to Gravatar service # Use custom avatar service, Sets fetch URL
GRAVATAR_URL=false # Possible placeholders: ${hash} ${size} ${email}
# To use a different service to get user's avatar like libravatar # If set, Avatars will be fetched regardless of DISABLE_EXTERNAL_SERVICES option.
# Possible placeholders: %{hash} %{size} %{email} # AVATAR_URL=https://seccdn.libravatar.org/avatar/${hash}?s=${size}&d=identicon
#GRAVATAR_URL=https://seccdn.libravatar.org/avatar/%{hash}?s=%{size}&d=identicon
# LDAP Settings # LDAP Settings
LDAP_SERVER=false LDAP_SERVER=false

View File

@ -85,9 +85,7 @@ class UserRepo
{ {
$user = $this->create($data, $verifyEmail); $user = $this->create($data, $verifyEmail);
$this->attachDefaultRole($user); $this->attachDefaultRole($user);
$this->downloadAndAssignUserAvatar($user);
// Get avatar from gravatar and save
$this->downloadGravatarToUserAvatar($user);
return $user; return $user;
} }
@ -238,25 +236,24 @@ class UserRepo
} }
/** /**
* Get a gravatar image for a user and set it as their avatar. * Get an avatar image for a user and set it as their avatar.
* Does not run if gravatar disabled in config. * Returns early if avatars disabled or not set in config.
* @param User $user * @param User $user
* @return bool * @return bool
*/ */
public function downloadGravatarToUserAvatar(User $user) public function downloadAndAssignUserAvatar(User $user)
{ {
// Get avatar from gravatar and save if (!Images::avatarFetchEnabled()) {
if (!config('services.gravatar')) {
return false; return false;
} }
try { try {
$avatar = Images::saveUserGravatar($user, config('services.gravatar_url')); $avatar = Images::saveUserAvatar($user);
$user->avatar()->associate($avatar); $user->avatar()->associate($avatar);
$user->save(); $user->save();
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {
\Log::error('Failed to save user gravatar image'); \Log::error('Failed to save user avatar image');
return false; return false;
} }
} }

View File

@ -76,7 +76,7 @@ class CreateAdmin extends Command
$user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]); $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]);
$this->userRepo->attachSystemRole($user, 'admin'); $this->userRepo->attachSystemRole($user, 'admin');
$this->userRepo->downloadGravatarToUserAvatar($user); $this->userRepo->downloadAndAssignUserAvatar($user);
$user->email_confirmed = true; $user->email_confirmed = true;
$user->save(); $user->save();

View File

@ -92,7 +92,7 @@ class UserController extends Controller
$user->roles()->sync($roles); $user->roles()->sync($roles);
} }
$this->userRepo->downloadGravatarToUserAvatar($user); $this->userRepo->downloadAndAssignUserAvatar($user);
return redirect('/settings/users'); return redirect('/settings/users');
} }

View File

@ -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 \BookStack\Auth\User $user
* @param null|string $gravatarUrl
* @param int $size * @param int $size
* @return mixed * @return Image
* @throws Exception * @throws Exception
*/ */
public function saveUserGravatar(User $user, $gravatarUrl, $size = 500) public function saveUserAvatar(User $user, $size = 500)
{ {
if (!is_string($gravatarUrl) || empty($gravatarUrl)) { $avatarUrl = $this->getAvatarUrl();
$gravatarUrl = 'https://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon';
}
$email = strtolower(trim($user->email)); $email = strtolower(trim($user->email));
$gravatarUrl = str_replace('%{hash}', md5($email), $gravatarUrl);
$gravatarUrl = str_replace('%{size}', $size, $gravatarUrl); $replacements = [
$gravatarUrl = str_replace('%{email}', urlencode($email), $gravatarUrl); '${hash}' => md5($email),
$imageName = str_replace(' ', '-', $user->name . '-gravatar.png'); '${size}' => $size,
$image = $this->saveNewFromUrl($gravatarUrl, 'user', $imageName); '${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->created_by = $user->id;
$image->updated_by = $user->id; $image->updated_by = $user->id;
$image->save(); $image->save();
return $image; 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. * Delete gallery and drawings that are not within HTML content of pages or page revisions.

View File

@ -16,11 +16,16 @@ return [
// Single option to disable non-auth external services such as Gravatar and Draw.io // Single option to disable non-auth external services such as Gravatar and Draw.io
'disable_services' => env('DISABLE_EXTERNAL_SERVICES', false), '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)), '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), 'callback_url' => env('APP_URL', false),
'mailgun' => [ 'mailgun' => [