pass collection of records to policy - laravel

this is my tables structure :
i want to get all Request State Records where Request_status.Department_id equals with User.Department_id . and user only can see own request_state records i defined a policy to handle this job but this policy only can handle 1 request_state record . this policy can't handle array of request_state Model ! how can i use get() instead of first()
Policy :
public function view(User $user, RequestState $requestState)
{
return$user->department_id===$requestState->department_id&&$user->hasRole('department');
}
Controller :
public function show_request()
{
$RequestState=RequestState::where('department_id',auth()->user()->department_id)->first();
nullable($RequestState)->getOrSend(function (){
return Responder::requestDoesNotFound();
});
if(auth()->user()->can('view',$RequestState)){
return 'ok';
}
}

The policy is fine as-is. The changes should be in the controller.
Your controller method is called show_request(). The name implies it is showing a single request. But the controller logic shows it is showing all the requests for the user. You need to either validate each request individually, or assume that all the requests have the same department_id, since that is what your query pulls. Assuming you want to check all the RequestStates in the collection, you can them to a single TRUE/FALSE;
public function show_request()
{
$requestStates = RequestState::where('department_id', auth()->user()->department_id)->fget();
nullable($RequestState)->getOrSend(function (){
return Responder::requestDoesNotFound();
});
return $requestStates->reduce(function ($accumulator, $requestState) {
return $accumulator and auth()->user()->can('view', $requestState);
}, TRUE);
}

As I can see, you want lo allow the users to see the list of request they have access. You can create a new method in your controller method to validate all the requests.
It should be something like this:
public function show_requests()
{
$requestStates = RequestState::where('department_id',auth()->user()->department_id)->get();
if(sizeof($requestStates) > 0 ){
for($i = 0; $i < size($requestStates); $i++ ) {
if (!(auth()->user()->can('view', $requestStates[$i]))) {
//Unset the record the user can't see
unset($requestStates[$i]);
}
}
//Return all records the user can see
return $requestStates;
}
else {
return Responder::requestDoesNotFound();
}
}

Related

Is it possible to retrieve a value from a redirect in another class before performing the redirect?

I am currently working with a controller, OnboardingController.php. This controller calls another method in a different class, let's call it OnboardingService.php, so for example:
OnboardingController
public function doThing()
{
return $this->doAnotherThing();
}
OnboardingService
public function doAnotherThing()
{
return redirect('/')->with(['propertyA' => 'valueA']);
}
Would I be able to access propertyA in OnboardingController before returning the redirect? And if so, how would I access that property?
e.g.
OnboardingController
public function doThing()
{
$doAnotherThing = $this->doAnotherThing();
Log::info($doAnotherThing->propertyA);
return $doAnotherThing;
}
I am currently using Laravel 6.
You're using redirect(...)->with(...) to flash propertyA, so propertyA should be accessible from the session
public function doThing()
{
$doAnotherThing = $this->doAnotherThing();
Log::info(session()->get('propertyA'));
return $doAnotherThing;
}

laravel social login for multiple user session getting lost on callback url

public function SocialRedirectEmployer($provider)
{
session()->set('role_id', request()->segment(3));
return Socialite::driver($provider)->redirect();
}
public function SocialRedirectEmp($provider)
{
session()->put('role_id', request()->segment(3));
session(['my_variable' => "lll"]);
return Socialite::driver($provider)->redirect();
}
Routes are
Route::get('loginEmployer/{provider}/rec', [App\Http\Controllers\Auth\LoginController::class, 'SocialRedirectEmployer']);
Route::get('loginEmp/{provider}/emp', [App\Http\Controllers\Auth\LoginController::class, 'SocialRedirectEmp']);
Route::get('login/{provider}/callback',[App\Http\Controllers\Auth\LoginController::class, 'SocialCallback']);
Afer call back url session is lost getting null
public function SocialCallback($provider){
$userSocial = Socialite::driver($provider)->stateless()->user();
$role = session()->get('role_id');
var_dump("role = ".$role);
dd(session('my_variable'));
dd(\request()->segment(3));
}
and request segment also not getting no callback url
For Session, You can use
use Session;
where library define
And for callback url you can this

Understanding Get Method Overrides

I am totally new to Web API an am not understanding how to Filter get calls.
This method returns all items in my database.
// GET: api/LogEntries
public IQueryable<LogEntry> GetLogEntries()
{
return db.LogEntries;
}
This method returns a specific item in my database.
// GET: api/LogEntries/5
[ResponseType(typeof(LogEntry))]
public IHttpActionResult GetLogEntry(int id)
{
LogEntry logEntry = db.LogEntries.Find(id);
if (logEntry == null)
{
return NotFound();
}
return Ok(logEntry);
}
So now I want to filter the returned records so I created this method but it won't work because the specific item method gets called. I seem to be missing a concept and am hoping you can point me to more clear understanding. Thanks
// GET: api/LogEntries
public IQueryable<LogEntry> GetLogEntries(string levelID)
{
int levIdInt;
if (Int32.TryParse(levelID, out levIdInt))
{
return db.LogEntries.Take(300).Where(l => (int)l.Level == levIdInt).OrderByDescending(d => d.TimeStamp);
}
return db.LogEntries.Where(i => i.ID < 0);
}
You need to specify the route for that method
[Route("api/LogEntries/Level/{levelID}"]
public IQueryable<LogEntry> GetLogEntries(string levelID)
{}
More on routing is available here http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

Is there a way to send CakeResponse from blackhole callback

I am trying to make the ajax request more user friendly. It is a scenario that using a token which can be reuse in a period of time. However in time that a user has inactive for a certain time and tried to use the form, user will observe that the ajax not working but donno why. What I'm gonna do here is to display the message.
Using my testing code, doing return new CakeResponse seems to be return true in blackhole and therefore the $result is true although the User edit should not be triggered
public function beforeFilter() {
$this->Security->blackHoleCallback = 'blackhole';
}
public function blackhole($type) {
if ($this->request->is('ajax')) {
$this->log('blackhole here','debug');
return new CakeResponse(array('body'=> json_encode(array('data'=>'The request has been blackholed')),'status'=>500));
}else{
$this->log('blackhole there','debug');
return new CakeResponse(array('body'=> json_encode(array('data'=>'The request has been blackholed')),'status'=>500));
}
}
in the userapp
public function edit() {
$userId=$this->Auth->user('id');
if (empty($this->request->data)) {
$this->request->data = $this->User->read(null, $userId);
}
if ($this->request->is('ajax')) {
if($result = $this->{$this->modelClass}->edit($userId, $this->request->data)){
$this->Session->write('Auth', $this->User->read(null, $userId));
return new CakeResponse(array('body'=> json_encode(array('data'=>'saved')),'status'=>200));
}else{
return new CakeResponse(array('body'=> json_encode(array('data'=>'error')),'status'=>500));
}
}
}
Progress 1:
Unsolved, perhaps needed to use event handler or exception, though it will be somehow complicated . Still thinking while refining other plugin feature.

Extbase - Store Domain Objects into TYPO3 session

Usually it is possible to put any domain object into session ($GLOBALS['TSFE']->fe_user) as they get automatically serialized and deserialized correctly. But in some cases this fails (i suppose caused by circurlar references or the serialized data exceeds the limit of the database blob field).
I found a better approach, converting the domain objects to integer "ids" on serialization and getting the real domain objects back from repository on deserialization:
class PutMeIntoSession implements \Serializable {
protected $project = null;
public function getProject() {
return $this->project;
}
public function setProject(\Vendor\Ext\Domain\Model\Project $project = NULL) {
$this->project = $project;
}
public function serialize() {
$serialized = serialize(array(
'project' => $this->project ? $this->project->getUid() : 0
));
return $serialized;
}
public function unserialize($serialized) {
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$unserialized = unserialize($serialized);
$this->project = $objectManager->get(ProjectRepository::class)->findByUid($unserialized['project']);
}
}
This seems to work fine. But i don't know if there are smarter ways to achieve this or if there are any possible problems with my approach?

Resources