diff --git a/.env.example b/.env.example index 214b4621d..b48465052 100644 --- a/.env.example +++ b/.env.example @@ -1,19 +1,31 @@ -APP_ENV=local -APP_DEBUG=true +# Environment +APP_ENV=production +APP_DEBUG=false APP_KEY=SomeRandomString +# Database details DB_HOST=localhost -DB_DATABASE=homestead -DB_USERNAME=homestead -DB_PASSWORD=secret +DB_DATABASE=database_database +DB_USERNAME=database_username +DB_PASSWORD=database__user_password +# Cache and session CACHE_DRIVER=file SESSION_DRIVER=file QUEUE_DRIVER=sync +# Social Authentication +GITHUB_APP_ID=false +GITHUB_APP_SECRET=false +GOOGLE_APP_ID=false +GOOGLE_APP_SECRET=false +# URL for social login redirects, NO TRAILING SLASH +APP_URL=http://bookstack.dev + +# Mail settings MAIL_DRIVER=smtp -MAIL_HOST=mailtrap.io -MAIL_PORT=2525 +MAIL_HOST=localhost +MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null \ No newline at end of file diff --git a/app/Entity.php b/app/Entity.php index 23b61e417..d2c5bd5c1 100644 --- a/app/Entity.php +++ b/app/Entity.php @@ -4,7 +4,7 @@ namespace Oxbow; use Illuminate\Database\Eloquent\Model; -class Entity extends Model +abstract class Entity extends Model { /** * Relation for the user that created this entity. @@ -86,4 +86,10 @@ class Entity extends Model return $search->get(); } + /** + * Get the url for this item. + * @return string + */ + abstract public function getUrl(); + } diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php index eacbe2bb9..c207f404c 100644 --- a/app/Http/Controllers/Auth/AuthController.php +++ b/app/Http/Controllers/Auth/AuthController.php @@ -2,15 +2,13 @@ namespace Oxbow\Http\Controllers\Auth; -use Oxbow\Exceptions\SocialDriverNotConfigured; use Oxbow\Exceptions\UserNotFound; -use Oxbow\Repos\UserRepo; +use Oxbow\Services\SocialAuthService; use Oxbow\User; use Validator; use Oxbow\Http\Controllers\Controller; use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; -use Laravel\Socialite\Contracts\Factory as Socialite; class AuthController extends Controller { @@ -31,21 +29,16 @@ class AuthController extends Controller protected $redirectPath = '/'; protected $redirectAfterLogout = '/login'; - protected $validSocialDrivers = ['google', 'github']; - - protected $socialite; - protected $userRepo; + protected $socialAuthService; /** * Create a new authentication controller instance. - * @param Socialite $socialite - * @param UserRepo $userRepo + * @param SocialAuthService $socialAuthService */ - public function __construct(Socialite $socialite, UserRepo $userRepo) + public function __construct(SocialAuthService $socialAuthService) { $this->middleware('guest', ['except' => 'getLogout']); - $this->socialite = $socialite; - $this->userRepo = $userRepo; + $this->socialAuthService = $socialAuthService; } /** @@ -90,7 +83,7 @@ class AuthController extends Controller return view('auth.authenticate'); } - $socialDrivers = $this->getActiveSocialDrivers(); + $socialDrivers = $this->socialAuthService->getActiveDrivers(); return view('auth.login', ['socialDrivers' => $socialDrivers]); } @@ -102,8 +95,7 @@ class AuthController extends Controller */ public function getSocialLogin($socialDriver) { - $driver = $this->validateSocialDriver($socialDriver); - return $this->socialite->driver($driver)->redirect(); + return $this->socialAuthService->logIn($socialDriver); } /** @@ -115,61 +107,9 @@ class AuthController extends Controller */ public function socialCallback($socialDriver) { - $driver = $this->validateSocialDriver($socialDriver); - // Get user details from social driver - $socialUser = $this->socialite->driver($driver)->user(); - $user = $this->userRepo->getByEmail($socialUser->getEmail()); - - // Redirect if the email is not a current user. - if ($user === null) { - throw new UserNotFound('A user with the email ' . $socialUser->getEmail() . ' was not found.', '/login'); - } - + $user = $this->socialAuthService->getUserFromCallback($socialDriver); \Auth::login($user, true); return redirect($this->redirectPath); } - /** - * Ensure the social driver is correct and supported. - * - * @param $socialDriver - * @return string - * @throws SocialDriverNotConfigured - */ - protected function validateSocialDriver($socialDriver) - { - $driver = trim(strtolower($socialDriver)); - - if (!in_array($driver, $this->validSocialDrivers)) abort(404, 'Social Driver Not Found'); - if(!$this->checkSocialDriverConfigured($driver)) throw new SocialDriverNotConfigured; - - return $driver; - } - - /** - * Check a social driver has been configured correctly. - * @param $driver - * @return bool - */ - protected function checkSocialDriverConfigured($driver) - { - $upperName = strtoupper($driver); - $config = [env($upperName . '_APP_ID', false), env($upperName . '_APP_SECRET', false), env('APP_URL', false)]; - return (!in_array(false, $config) && !in_array(null, $config)); - } - - /** - * Gets the names of the active social drivers. - * @return array - */ - protected function getActiveSocialDrivers() - { - $activeDrivers = []; - foreach($this->validSocialDrivers as $driverName) { - if($this->checkSocialDriverConfigured($driverName)) { - $activeDrivers[$driverName] = true; - } - } - return $activeDrivers; - } } diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php index edad13636..7f8bada8c 100644 --- a/app/Http/Controllers/BookController.php +++ b/app/Http/Controllers/BookController.php @@ -144,6 +144,7 @@ class BookController extends Controller $this->checkPermission('book-delete'); $book = $this->bookRepo->getBySlug($bookSlug); Activity::addMessage('book_delete', 0, $book->name); + Activity::removeEntity($book); $this->bookRepo->destroyBySlug($bookSlug); return redirect('/books'); } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 0266d2671..63c27fa0b 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -100,7 +100,7 @@ class UserController extends Controller }); $this->validate($request, [ 'name' => 'required', - 'email' => 'required|email', + 'email' => 'required|email|unique:users,email,' . $id, 'password' => 'min:5', 'password-confirm' => 'same:password', 'role' => 'exists:roles,id' diff --git a/app/Image.php b/app/Image.php index f80f33fff..cb8ee7c59 100644 --- a/app/Image.php +++ b/app/Image.php @@ -13,4 +13,12 @@ class Image extends Entity return storage_path() . $this->url; } + /** + * Get the url for this item. + * @return string + */ + public function getUrl() + { + return public_path() . $this->url; + } } diff --git a/app/Repos/BookRepo.php b/app/Repos/BookRepo.php index 7f7517e92..5a5da5138 100644 --- a/app/Repos/BookRepo.php +++ b/app/Repos/BookRepo.php @@ -54,9 +54,11 @@ class BookRepo { $book = $this->getBySlug($bookSlug); foreach($book->pages as $page) { + \Activity::removeEntity($page); $page->delete(); } foreach($book->chapters as $chapter) { + \Activity::removeEntity($chapter); $chapter->delete(); } $book->delete(); diff --git a/app/Services/SocialAuthService.php b/app/Services/SocialAuthService.php new file mode 100644 index 000000000..c8f3278c5 --- /dev/null +++ b/app/Services/SocialAuthService.php @@ -0,0 +1,101 @@ +userRepo = $userRepo; + $this->socialite = $socialite; + } + + public function logIn($socialDriver) + { + $driver = $this->validateDriver($socialDriver); + return $this->socialite->driver($driver)->redirect(); + } + + /** + * Get a user from socialite after a oAuth callback. + * + * @param $socialDriver + * @return mixed + * @throws SocialDriverNotConfigured + * @throws UserNotFound + */ + public function getUserFromCallback($socialDriver) + { + $driver = $this->validateDriver($socialDriver); + // Get user details from social driver + $socialUser = $this->socialite->driver($driver)->user(); + $user = $this->userRepo->getByEmail($socialUser->getEmail()); + + // Redirect if the email is not a current user. + if ($user === null) { + throw new UserNotFound('A user with the email ' . $socialUser->getEmail() . ' was not found.', '/login'); + } + + return $user; + } + + /** + * Ensure the social driver is correct and supported. + * + * @param $socialDriver + * @return string + * @throws SocialDriverNotConfigured + */ + private function validateDriver($socialDriver) + { + $driver = trim(strtolower($socialDriver)); + + if (!in_array($driver, $this->validSocialDrivers)) abort(404, 'Social Driver Not Found'); + if (!$this->checklDriverConfigured($driver)) throw new SocialDriverNotConfigured; + + return $driver; + } + + /** + * Check a social driver has been configured correctly. + * @param $driver + * @return bool + */ + private function checklDriverConfigured($driver) + { + $upperName = strtoupper($driver); + $config = [env($upperName . '_APP_ID', false), env($upperName . '_APP_SECRET', false), env('APP_URL', false)]; + return (!in_array(false, $config) && !in_array(null, $config)); + } + + /** + * Gets the names of the active social drivers. + * @return array + */ + public function getActiveDrivers() + { + $activeDrivers = []; + foreach ($this->validSocialDrivers as $driverName) { + if ($this->checklDriverConfigured($driverName)) { + $activeDrivers[$driverName] = true; + } + } + return $activeDrivers; + } + + +} \ No newline at end of file