Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
immerda
Immerda Apps
Schichtplan
Commits
95525769
Commit
95525769
authored
Oct 30, 2022
by
o@ungehorsam.ch
Browse files
Merge branch '8-shift-enumeration' into 'main'
Resolve "shift enumeration" Closes
#8
See merge request
!7
parents
bb3e5752
8ad9b5d2
Changes
7
Hide whitespace changes
Inline
Side-by-side
app/Http/Controllers/Controller.php
View file @
95525769
...
...
@@ -2,17 +2,42 @@
namespace
App\Http\Controllers
;
use
App\Models\Plan
;
use
App\Models\Shift
;
use
Illuminate\Foundation\Auth\Access\AuthorizesRequests
;
use
Illuminate\Foundation\Bus\DispatchesJobs
;
use
Illuminate\Foundation\Validation\ValidatesRequests
;
use
Illuminate\Routing\Controller
as
BaseController
;
use
Illuminate\Support\Facades\Auth
;
class
Controller
extends
BaseController
{
use
DispatchesJobs
,
ValidatesRequests
;
use
AuthorizesRequests
,
DispatchesJobs
,
ValidatesRequests
;
protected
function
auth
(
\
App\Models\Plan
$plan
)
{
if
(
!
strpos
(
\
Request
::
url
(),
$plan
->
edit_id
))
/**
* Auth a plan over by the secrete Plan edit_id
* @param Plan $plan
*/
protected
function
auth
(
Plan
$plan
)
{
if
(
!
strpos
(
\
Request
::
url
(),
$plan
->
edit_id
))
{
abort
(
401
);
}
// login the plan as a user. This is a hack to work with edit_id tokens only and the laravel auth Policies
Auth
::
login
(
$plan
,
false
);
}
/**
* Anonymous user can just subscribe to a known plan and shift
* @param Plan $plan
* @param Shift $shift
*/
protected
function
authSubscriber
(
Plan
$plan
,
Shift
$shift
)
{
// anonymous user can subscribe to the plan they have the link to
// we can't use auth Policies to check this
if
(
$shift
->
plan
->
id
!==
$plan
->
id
)
{
abort
(
403
);
}
}
}
app/Http/Controllers/PlanController.php
View file @
95525769
...
...
@@ -83,6 +83,7 @@ class PlanController extends Controller
$plans
=
Plan
::
where
(
'owner_email'
,
$email
)
->
get
();
if
(
count
(
$plans
)
>
0
)
{
foreach
(
$plans
as
$plan
)
{
// todo: send just one email
$plan
->
sendLinksNotification
();
}
}
...
...
@@ -93,7 +94,7 @@ class PlanController extends Controller
/**
* Cleanup old plans.
*
*
todo: we may want to delete this
*/
public
function
cron
()
{
...
...
@@ -118,6 +119,7 @@ class PlanController extends Controller
public
function
admin
(
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"view"
,
$plan
);
return
view
(
'plan.admin'
)
->
with
([
'plan'
=>
$plan
]);
}
...
...
@@ -130,6 +132,7 @@ class PlanController extends Controller
public
function
admin_subscriptions
(
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"view"
,
$plan
);
return
view
(
'plan.admin_subscriptions'
)
->
with
([
'plan'
=>
$plan
]);
}
...
...
@@ -142,6 +145,7 @@ class PlanController extends Controller
public
function
edit
(
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"update"
,
$plan
);
return
view
(
'plan.create'
,
[
'plan'
=>
$plan
]);
}
...
...
@@ -155,11 +159,8 @@ class PlanController extends Controller
public
function
update
(
UpdatePlanRequest
$request
,
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"update"
,
$plan
);
$data
=
$request
->
validated
();
// prevent to be overridden
unset
(
$data
[
'edit_id'
]);
unset
(
$data
[
'view_id'
]);
unset
(
$data
[
'id'
]);
$plan
->
update
(
$data
);
// redirect to shifts overview
Session
::
flash
(
'info'
,
__
(
'plan.successfullyUpdated'
));
...
...
@@ -175,6 +176,7 @@ class PlanController extends Controller
public
function
destroy
(
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"forceDelete"
,
$plan
);
$plan
->
forceDelete
();
Session
::
flash
(
'info'
,
__
(
'plan.successfullyDestroyed'
));
return
\
redirect
()
->
route
(
'home'
);
...
...
app/Http/Controllers/ShiftController.php
View file @
95525769
...
...
@@ -4,7 +4,6 @@ namespace App\Http\Controllers;
use
App\Http\Requests\StoreShiftRequest
;
use
App\Http\Requests\RepetitionType
;
use
App\Http\Requests\UpdateShiftRequest
;
use
App\Models\Plan
;
use
App\Models\Shift
;
use
Illuminate\Http\Response
;
...
...
@@ -15,12 +14,15 @@ class ShiftController extends Controller
/**
* Show the form for creating a new shift.
*
* @param Plan $plan
* @return Response
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
public
function
create
(
Plan
$plan
)
{
$this
->
auth
(
$plan
);
// user needs access to plan to create a new shift
$this
->
auth
(
$plan
);
$this
->
authorize
(
"create"
,
Shift
::
class
);
$groups
=
$this
->
getGroups
(
$plan
);
$shift
=
new
Shift
();
return
view
(
'shift.create'
,
[
'plan'
=>
$plan
,
'shift'
=>
$shift
,
'groups'
=>
$groups
,
...
...
@@ -37,6 +39,7 @@ class ShiftController extends Controller
public
function
store
(
StoreShiftRequest
$request
,
Plan
$plan
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
"create"
,
Shift
::
class
);
$data
=
$request
->
validated
();
$plan
->
shifts
()
->
create
(
$data
);
if
(
$data
[
'repetition_type'
]
!=
RepetitionType
::
None
)
{
...
...
@@ -60,6 +63,7 @@ class ShiftController extends Controller
public
function
edit
(
Plan
$plan
,
Shift
$shift
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'update'
,
$shift
);
$groups
=
$this
->
getGroups
(
$plan
);
return
view
(
'shift.create'
,
[
'shift'
=>
$shift
,
'plan'
=>
$plan
,
'groups'
=>
$groups
]);
}
...
...
@@ -75,6 +79,7 @@ class ShiftController extends Controller
public
function
update
(
StoreShiftRequest
$request
,
Plan
$plan
,
Shift
$shift
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'update'
,
$shift
);
$data
=
$request
->
validated
();
$shift
->
update
(
$data
);
Session
::
flash
(
'info'
,
__
(
'shift.successfullyUpdated'
));
...
...
@@ -91,6 +96,7 @@ class ShiftController extends Controller
public
function
destroy
(
Plan
$plan
,
Shift
$shift
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'forceDelete'
,
$shift
);
$shift
->
forceDelete
();
Session
::
flash
(
'info'
,
__
(
'shift.successfullyDestroyed'
));
return
redirect
()
->
route
(
'plan.admin'
,
[
'plan'
=>
$plan
]);
...
...
app/Http/Controllers/SubscriptionController.php
View file @
95525769
...
...
@@ -7,7 +7,6 @@ use App\Models\Plan;
use
App\Models\Shift
;
use
App\Models\Subscription
;
use
Illuminate\Http\Response
;
use
Illuminate\Support\Facades\Log
;
use
Illuminate\Support\Facades\Session
;
class
SubscriptionController
extends
Controller
...
...
@@ -21,6 +20,8 @@ class SubscriptionController extends Controller
* @return Response
*/
public
function
create
(
Plan
$plan
,
Shift
$shift
)
{
// anonymous users can just add a shift for the authorized plan
$this
->
authSubscriber
(
$plan
,
$shift
);
$subscription
=
new
Subscription
();
return
view
(
'subscription.create'
,
[
'plan'
=>
$plan
,
'shift'
=>
$shift
,
'subscription'
=>
$subscription
]);
}
...
...
@@ -35,17 +36,15 @@ class SubscriptionController extends Controller
*/
public
function
store
(
StoreSubscriptionRequest
$request
,
Plan
$plan
,
Shift
$shift
)
{
// anonymous users can just add a shift for the authorized plan
$this
->
authSubscriber
(
$plan
,
$shift
);
// check if there are already enough subscriptions
if
(
$shift
->
team_size
<=
$shift
->
subscriptions
()
->
count
())
{
Session
::
flash
(
'fail'
,
__
(
'subscription.enoughSubscription'
));
return
redirect
()
->
route
(
'plan.show'
,
[
'plan'
=>
$plan
]);
}
// no specific authorization - everybody with the link can create a subscription
$data
=
$request
->
validated
();
$subscription
=
$shift
->
subscriptions
()
->
create
(
$data
);
// An anonymous user can edit her/his subscription as long as he/she use the same session
// For that reason we save those subscription in a session
Session
::
push
(
'subscriptions'
,
$subscription
->
id
);
$shift
->
subscriptions
()
->
create
(
$data
);
Session
::
flash
(
'info'
,
__
(
'subscription.successfullyCreated'
));
return
redirect
()
->
route
(
'plan.show'
,
[
'plan'
=>
$plan
]);
}
...
...
@@ -61,6 +60,7 @@ class SubscriptionController extends Controller
public
function
edit
(
Plan
$plan
,
Shift
$shift
,
Subscription
$subscription
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'update'
,
$subscription
);
return
view
(
'subscription.create'
,
[
'plan'
=>
$plan
,
'shift'
=>
$shift
,
'subscription'
=>
$subscription
]);
}
...
...
@@ -76,6 +76,7 @@ class SubscriptionController extends Controller
public
function
update
(
StoreSubscriptionRequest
$request
,
Plan
$plan
,
Shift
$shift
,
Subscription
$subscription
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'update'
,
$subscription
);
$data
=
$request
->
validated
();
$subscription
->
update
(
$data
);
Session
::
flash
(
'info'
,
__
(
'subscription.successfullyUpdated'
));
...
...
@@ -93,9 +94,8 @@ class SubscriptionController extends Controller
public
function
destroy
(
Plan
$plan
,
Shift
$shift
,
Subscription
$subscription
)
{
$this
->
auth
(
$plan
);
$this
->
authorize
(
'forceDelete'
,
$subscription
);
$subscription
->
forceDelete
();
// todo: check if this is working
Session
::
forget
(
'subscriptions.'
.
$subscription
->
id
);
Session
::
flash
(
'info'
,
__
(
'subscription.successfullyDestroyed'
));
return
redirect
()
->
route
(
'plan.admin'
,
[
'plan'
=>
$plan
]);
}
...
...
app/Models/Plan.php
View file @
95525769
...
...
@@ -5,12 +5,18 @@ namespace App\Models;
use
App\Notifications\SendLinksNotification
;
use
Illuminate\Database\Eloquent\Factories\HasFactory
;
use
Illuminate\Database\Eloquent\Model
;
use
Illuminate\Contracts\Auth\Authenticatable
;
use
Illuminate\Foundation\Auth\Access\Authorizable
;
use
Illuminate\Contracts\Auth\Access\Authorizable
as
AuthorizableContract
;
use
Illuminate\Contracts\Auth\Authenticatable
as
AuthenticatableContract
;
use
Illuminate\Notifications\Notifiable
;
use
Illuminate\Support\Str
;
class
Plan
extends
Model
{
use
HasFactory
,
Notifiable
;
class
Plan
extends
Model
implements
AuthenticatableContract
,
AuthorizableContract
{
use
Authorizable
,
HasFactory
,
Notifiable
;
/**
* The attributes that are mass assignable.
...
...
@@ -95,4 +101,33 @@ class Plan extends Model
$viewLink
=
route
(
'plan.show'
,
[
'plan'
=>
$this
->
view_id
]);
$this
->
notify
(
new
SendLinksNotification
(
$this
->
title
,
$adminLink
,
$viewLink
));
}
public
function
getAuthIdentifierName
()
{
$this
->
edit_id
;
}
public
function
getAuthIdentifier
()
{
$this
->
edit_id
;
}
public
function
getAuthPassword
()
{
return
null
;
}
public
function
getRememberToken
()
{
return
null
;
}
public
function
setRememberToken
(
$value
)
{
}
public
function
getRememberTokenName
()
{
return
null
;
}
}
app/Policies/ShiftPolicy.php
View file @
95525769
...
...
@@ -13,6 +13,17 @@ class ShiftPolicy
{
use
HandlesAuthorization
;
/**
* Determine whether the user can create a shit.
*
* @param \App\Models\Plan $plan
* @return \Illuminate\Auth\Access\Response|bool
*/
public
function
create
(
Plan
$plan
)
{
return
true
;
}
/**
* Determine whether the user can update the model.
*
...
...
app/Policies/SubscriptionPolicy.php
0 → 100644
View file @
95525769
<?php
namespace
App\Policies
;
use
App\Models\Plan
;
use
App\Models\Shift
;
use
App\Models\Subscription
;
use
Illuminate\Auth\Access\HandlesAuthorization
;
use
Illuminate\Support\Facades\Log
;
class
SubscriptionPolicy
{
use
HandlesAuthorization
;
/**
* Determine whether the user can update the model.
*
* @param \App\Models\Plan $plan
* @param \App\Models\Subscription $subscription
* @return \Illuminate\Auth\Access\Response|bool
*/
public
function
update
(
Plan
$plan
,
Subscription
$subscription
)
{
return
$subscription
->
shift
->
plan
->
id
===
$plan
->
id
;
}
/**
* Determine whether the user can permanently delete the model.
*
* @param \App\Models\Plan $plan
* @param \App\Models\Subscription $subscription
* @return \Illuminate\Auth\Access\Response|bool
*/
public
function
forceDelete
(
Plan
$plan
,
Subscription
$subscription
)
{
return
$subscription
->
shift
->
plan
->
id
===
$plan
->
id
;
}
}
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment