Dan Brown

Refactored Social auth into service, Made entity an abstract class

1 -APP_ENV=local 1 +# Environment
2 -APP_DEBUG=true 2 +APP_ENV=production
3 +APP_DEBUG=false
3 APP_KEY=SomeRandomString 4 APP_KEY=SomeRandomString
4 5
6 +# Database details
5 DB_HOST=localhost 7 DB_HOST=localhost
6 -DB_DATABASE=homestead 8 +DB_DATABASE=database_database
7 -DB_USERNAME=homestead 9 +DB_USERNAME=database_username
8 -DB_PASSWORD=secret 10 +DB_PASSWORD=database__user_password
9 11
12 +# Cache and session
10 CACHE_DRIVER=file 13 CACHE_DRIVER=file
11 SESSION_DRIVER=file 14 SESSION_DRIVER=file
12 QUEUE_DRIVER=sync 15 QUEUE_DRIVER=sync
13 16
17 +# Social Authentication
18 +GITHUB_APP_ID=false
19 +GITHUB_APP_SECRET=false
20 +GOOGLE_APP_ID=false
21 +GOOGLE_APP_SECRET=false
22 +# URL for social login redirects, NO TRAILING SLASH
23 +APP_URL=http://bookstack.dev
24 +
25 +# Mail settings
14 MAIL_DRIVER=smtp 26 MAIL_DRIVER=smtp
15 -MAIL_HOST=mailtrap.io 27 +MAIL_HOST=localhost
16 -MAIL_PORT=2525 28 +MAIL_PORT=1025
17 MAIL_USERNAME=null 29 MAIL_USERNAME=null
18 MAIL_PASSWORD=null 30 MAIL_PASSWORD=null
19 MAIL_ENCRYPTION=null 31 MAIL_ENCRYPTION=null
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -4,7 +4,7 @@ namespace Oxbow; ...@@ -4,7 +4,7 @@ namespace Oxbow;
4 4
5 use Illuminate\Database\Eloquent\Model; 5 use Illuminate\Database\Eloquent\Model;
6 6
7 -class Entity extends Model 7 +abstract class Entity extends Model
8 { 8 {
9 /** 9 /**
10 * Relation for the user that created this entity. 10 * Relation for the user that created this entity.
...@@ -86,4 +86,10 @@ class Entity extends Model ...@@ -86,4 +86,10 @@ class Entity extends Model
86 return $search->get(); 86 return $search->get();
87 } 87 }
88 88
89 + /**
90 + * Get the url for this item.
91 + * @return string
92 + */
93 + abstract public function getUrl();
94 +
89 } 95 }
......
...@@ -2,15 +2,13 @@ ...@@ -2,15 +2,13 @@
2 2
3 namespace Oxbow\Http\Controllers\Auth; 3 namespace Oxbow\Http\Controllers\Auth;
4 4
5 -use Oxbow\Exceptions\SocialDriverNotConfigured;
6 use Oxbow\Exceptions\UserNotFound; 5 use Oxbow\Exceptions\UserNotFound;
7 -use Oxbow\Repos\UserRepo; 6 +use Oxbow\Services\SocialAuthService;
8 use Oxbow\User; 7 use Oxbow\User;
9 use Validator; 8 use Validator;
10 use Oxbow\Http\Controllers\Controller; 9 use Oxbow\Http\Controllers\Controller;
11 use Illuminate\Foundation\Auth\ThrottlesLogins; 10 use Illuminate\Foundation\Auth\ThrottlesLogins;
12 use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers; 11 use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
13 -use Laravel\Socialite\Contracts\Factory as Socialite;
14 12
15 class AuthController extends Controller 13 class AuthController extends Controller
16 { 14 {
...@@ -31,21 +29,16 @@ class AuthController extends Controller ...@@ -31,21 +29,16 @@ class AuthController extends Controller
31 protected $redirectPath = '/'; 29 protected $redirectPath = '/';
32 protected $redirectAfterLogout = '/login'; 30 protected $redirectAfterLogout = '/login';
33 31
34 - protected $validSocialDrivers = ['google', 'github']; 32 + protected $socialAuthService;
35 -
36 - protected $socialite;
37 - protected $userRepo;
38 33
39 /** 34 /**
40 * Create a new authentication controller instance. 35 * Create a new authentication controller instance.
41 - * @param Socialite $socialite 36 + * @param SocialAuthService $socialAuthService
42 - * @param UserRepo $userRepo
43 */ 37 */
44 - public function __construct(Socialite $socialite, UserRepo $userRepo) 38 + public function __construct(SocialAuthService $socialAuthService)
45 { 39 {
46 $this->middleware('guest', ['except' => 'getLogout']); 40 $this->middleware('guest', ['except' => 'getLogout']);
47 - $this->socialite = $socialite; 41 + $this->socialAuthService = $socialAuthService;
48 - $this->userRepo = $userRepo;
49 } 42 }
50 43
51 /** 44 /**
...@@ -90,7 +83,7 @@ class AuthController extends Controller ...@@ -90,7 +83,7 @@ class AuthController extends Controller
90 return view('auth.authenticate'); 83 return view('auth.authenticate');
91 } 84 }
92 85
93 - $socialDrivers = $this->getActiveSocialDrivers(); 86 + $socialDrivers = $this->socialAuthService->getActiveDrivers();
94 87
95 return view('auth.login', ['socialDrivers' => $socialDrivers]); 88 return view('auth.login', ['socialDrivers' => $socialDrivers]);
96 } 89 }
...@@ -102,8 +95,7 @@ class AuthController extends Controller ...@@ -102,8 +95,7 @@ class AuthController extends Controller
102 */ 95 */
103 public function getSocialLogin($socialDriver) 96 public function getSocialLogin($socialDriver)
104 { 97 {
105 - $driver = $this->validateSocialDriver($socialDriver); 98 + return $this->socialAuthService->logIn($socialDriver);
106 - return $this->socialite->driver($driver)->redirect();
107 } 99 }
108 100
109 /** 101 /**
...@@ -115,61 +107,9 @@ class AuthController extends Controller ...@@ -115,61 +107,9 @@ class AuthController extends Controller
115 */ 107 */
116 public function socialCallback($socialDriver) 108 public function socialCallback($socialDriver)
117 { 109 {
118 - $driver = $this->validateSocialDriver($socialDriver); 110 + $user = $this->socialAuthService->getUserFromCallback($socialDriver);
119 - // Get user details from social driver
120 - $socialUser = $this->socialite->driver($driver)->user();
121 - $user = $this->userRepo->getByEmail($socialUser->getEmail());
122 -
123 - // Redirect if the email is not a current user.
124 - if ($user === null) {
125 - throw new UserNotFound('A user with the email ' . $socialUser->getEmail() . ' was not found.', '/login');
126 - }
127 -
128 \Auth::login($user, true); 111 \Auth::login($user, true);
129 return redirect($this->redirectPath); 112 return redirect($this->redirectPath);
130 } 113 }
131 114
132 - /**
133 - * Ensure the social driver is correct and supported.
134 - *
135 - * @param $socialDriver
136 - * @return string
137 - * @throws SocialDriverNotConfigured
138 - */
139 - protected function validateSocialDriver($socialDriver)
140 - {
141 - $driver = trim(strtolower($socialDriver));
142 -
143 - if (!in_array($driver, $this->validSocialDrivers)) abort(404, 'Social Driver Not Found');
144 - if(!$this->checkSocialDriverConfigured($driver)) throw new SocialDriverNotConfigured;
145 -
146 - return $driver;
147 - }
148 -
149 - /**
150 - * Check a social driver has been configured correctly.
151 - * @param $driver
152 - * @return bool
153 - */
154 - protected function checkSocialDriverConfigured($driver)
155 - {
156 - $upperName = strtoupper($driver);
157 - $config = [env($upperName . '_APP_ID', false), env($upperName . '_APP_SECRET', false), env('APP_URL', false)];
158 - return (!in_array(false, $config) && !in_array(null, $config));
159 - }
160 -
161 - /**
162 - * Gets the names of the active social drivers.
163 - * @return array
164 - */
165 - protected function getActiveSocialDrivers()
166 - {
167 - $activeDrivers = [];
168 - foreach($this->validSocialDrivers as $driverName) {
169 - if($this->checkSocialDriverConfigured($driverName)) {
170 - $activeDrivers[$driverName] = true;
171 - }
172 - }
173 - return $activeDrivers;
174 - }
175 } 115 }
......
...@@ -144,6 +144,7 @@ class BookController extends Controller ...@@ -144,6 +144,7 @@ class BookController extends Controller
144 $this->checkPermission('book-delete'); 144 $this->checkPermission('book-delete');
145 $book = $this->bookRepo->getBySlug($bookSlug); 145 $book = $this->bookRepo->getBySlug($bookSlug);
146 Activity::addMessage('book_delete', 0, $book->name); 146 Activity::addMessage('book_delete', 0, $book->name);
147 + Activity::removeEntity($book);
147 $this->bookRepo->destroyBySlug($bookSlug); 148 $this->bookRepo->destroyBySlug($bookSlug);
148 return redirect('/books'); 149 return redirect('/books');
149 } 150 }
......
...@@ -100,7 +100,7 @@ class UserController extends Controller ...@@ -100,7 +100,7 @@ class UserController extends Controller
100 }); 100 });
101 $this->validate($request, [ 101 $this->validate($request, [
102 'name' => 'required', 102 'name' => 'required',
103 - 'email' => 'required|email', 103 + 'email' => 'required|email|unique:users,email,' . $id,
104 'password' => 'min:5', 104 'password' => 'min:5',
105 'password-confirm' => 'same:password', 105 'password-confirm' => 'same:password',
106 'role' => 'exists:roles,id' 106 'role' => 'exists:roles,id'
......
...@@ -13,4 +13,12 @@ class Image extends Entity ...@@ -13,4 +13,12 @@ class Image extends Entity
13 return storage_path() . $this->url; 13 return storage_path() . $this->url;
14 } 14 }
15 15
16 + /**
17 + * Get the url for this item.
18 + * @return string
19 + */
20 + public function getUrl()
21 + {
22 + return public_path() . $this->url;
23 + }
16 } 24 }
......
...@@ -54,9 +54,11 @@ class BookRepo ...@@ -54,9 +54,11 @@ class BookRepo
54 { 54 {
55 $book = $this->getBySlug($bookSlug); 55 $book = $this->getBySlug($bookSlug);
56 foreach($book->pages as $page) { 56 foreach($book->pages as $page) {
57 + \Activity::removeEntity($page);
57 $page->delete(); 58 $page->delete();
58 } 59 }
59 foreach($book->chapters as $chapter) { 60 foreach($book->chapters as $chapter) {
61 + \Activity::removeEntity($chapter);
60 $chapter->delete(); 62 $chapter->delete();
61 } 63 }
62 $book->delete(); 64 $book->delete();
......
1 +<?php namespace Oxbow\Services;
2 +
3 +use Laravel\Socialite\Contracts\Factory as Socialite;
4 +use Oxbow\Exceptions\SocialDriverNotConfigured;
5 +use Oxbow\Exceptions\UserNotFound;
6 +use Oxbow\Repos\UserRepo;
7 +
8 +class SocialAuthService
9 +{
10 +
11 + protected $userRepo;
12 + protected $socialite;
13 +
14 + protected $validSocialDrivers = ['google', 'github'];
15 +
16 + /**
17 + * SocialAuthService constructor.
18 + * @param $userRepo
19 + * @param $socialite
20 + */
21 + public function __construct(UserRepo $userRepo, Socialite $socialite)
22 + {
23 + $this->userRepo = $userRepo;
24 + $this->socialite = $socialite;
25 + }
26 +
27 + public function logIn($socialDriver)
28 + {
29 + $driver = $this->validateDriver($socialDriver);
30 + return $this->socialite->driver($driver)->redirect();
31 + }
32 +
33 + /**
34 + * Get a user from socialite after a oAuth callback.
35 + *
36 + * @param $socialDriver
37 + * @return mixed
38 + * @throws SocialDriverNotConfigured
39 + * @throws UserNotFound
40 + */
41 + public function getUserFromCallback($socialDriver)
42 + {
43 + $driver = $this->validateDriver($socialDriver);
44 + // Get user details from social driver
45 + $socialUser = $this->socialite->driver($driver)->user();
46 + $user = $this->userRepo->getByEmail($socialUser->getEmail());
47 +
48 + // Redirect if the email is not a current user.
49 + if ($user === null) {
50 + throw new UserNotFound('A user with the email ' . $socialUser->getEmail() . ' was not found.', '/login');
51 + }
52 +
53 + return $user;
54 + }
55 +
56 + /**
57 + * Ensure the social driver is correct and supported.
58 + *
59 + * @param $socialDriver
60 + * @return string
61 + * @throws SocialDriverNotConfigured
62 + */
63 + private function validateDriver($socialDriver)
64 + {
65 + $driver = trim(strtolower($socialDriver));
66 +
67 + if (!in_array($driver, $this->validSocialDrivers)) abort(404, 'Social Driver Not Found');
68 + if (!$this->checklDriverConfigured($driver)) throw new SocialDriverNotConfigured;
69 +
70 + return $driver;
71 + }
72 +
73 + /**
74 + * Check a social driver has been configured correctly.
75 + * @param $driver
76 + * @return bool
77 + */
78 + private function checklDriverConfigured($driver)
79 + {
80 + $upperName = strtoupper($driver);
81 + $config = [env($upperName . '_APP_ID', false), env($upperName . '_APP_SECRET', false), env('APP_URL', false)];
82 + return (!in_array(false, $config) && !in_array(null, $config));
83 + }
84 +
85 + /**
86 + * Gets the names of the active social drivers.
87 + * @return array
88 + */
89 + public function getActiveDrivers()
90 + {
91 + $activeDrivers = [];
92 + foreach ($this->validSocialDrivers as $driverName) {
93 + if ($this->checklDriverConfigured($driverName)) {
94 + $activeDrivers[$driverName] = true;
95 + }
96 + }
97 + return $activeDrivers;
98 + }
99 +
100 +
101 +}
...\ No newline at end of file ...\ No newline at end of file