Why my middleware is not working,I try to put some parameter inside the middleware and its not working - laravel-5.7

My middleware should block user with restric_desc = Revoke Student Portal Access. But it end up blocking all user from accessing the tab.
Route::group(['middleware' => ['auth'], 'request' =>App\Models\BlockReason::where('IS_ACTIVE','0')->pluck('ID')], function () {
Route::group(['middleware' => 'block', 'request' => App\Models\BlockRestricType::where('RESTRIC_DESC', 'Revoke Student Portal Access')->pluck('ID')],function(){
My middleware
public function handle($request, Closure $next)
{
$var= $request->route()->getAction();
if($request->IS_ACTIVE != 0){
if($request->RESTRIC_DESC == 'Revoke Student Portal Access'){
return redirect('/');
}
}
return $next($request);
}

Related

Trigger a action upon success full response of another action ngrx

I created a ngrx effect that's responsible for sending a POST request to a back end. now i want to change the implementation little bit. if the post request is successful I want to trigger another action that responsible update my ngrx store. but I couldn't figure out how to do that.
I tried to use switch map and merge map but didn't work.
creatTour$ = createEffect(() =>
this.actions$.pipe(
ofType(TourAction.createTour),
mergeMap((action) => {
const payload = action.tour;
const endpoint = environment.urls.tour.replace("{tourProviderId}", "1");
const request = new ServiceRequest(endpoint, 'POST', payload, options);
return this.requestHandlerService.invoke(request).pipe(
map((sucessResponce) => {
if (sucessResponce.code === 200) {
TourListAction.updateTourList({ tour: [tour] }) // i want to trigger this action and
// below action
}
return TourAction.createTourSucess({ responce: sucessResponce.message })
}),
catchError(err => {
const errorMessage = JSON.stringify(err);
console.log(errorMessage);
return of(TourAction.createTourFail({ errorMessage }))
})
)
})
)
);
i tried this way too
return [TourAction.createTourSucess({ responce: sucessResponce.message }
TourListAction.updateTourList({ tour: [tour] })]
it throws this error
Property 'type' is missing in type '(({ responce: string; }
& TypedAction<"[Tour] Create Tour Success">) | ({ tour: Tours[]; } &
TypedAction<"[Tour List] Tour List Update">))[]' but required in type
'Action'.
is this the better way to do this.i saw there is new thing called entity should I use that for this implementation?
Why not update your state on the createTourSucess action?
You can also return multiple actions:
.pipe(
switchMap(() =>
return [
TourListAction.updateTourList({ tour: [tour] }) ,
TourAction.createTourSucess({ responce: sucessResponce.message })
]
)
)
https://medium.com/#amcdnl/dispatching-multiple-actions-from-ngrx-effects-c1447ceb6b22
You can return multiple actions from your effect, they will all be dispatched.
See https://medium.com/#tanya/understanding-ngrx-effects-and-the-action-stream-1a74996a0c1c
For your code:
return successResponse.code === 200 ? [
createTourUpdateAction(tour),
TourAction.createTourSuccess
] : [TourAction.createTourSuccess]

How to validate a claim in id_token when using OpenIdConnect middleware?

I'm using Oath2 with Google authentication in my ASP.NET Core MVC app. I want to restrict logged in users to a certain G Suite domain which according to the docs is done using the "hd" (hosted domain) claim. I have it working but as it's authentication and I'm not familiar would like input. Am I doing this correctly? Is there a way to instead return a 401 status code instead of calling Fail() which results in a 500 error?
public void ConfigureServices(IServiceCollection services)
{
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
.AddCookie()
.AddOpenIdConnect(o =>
{
var hostedDomain = new KeyValuePair<string, string>("hd", "mysite.com");
o.ClientId = "...";
o.ClientSecret = "...";
o.Authority = "https://accounts.google.com";
o.ResponseType = "id_token token";
o.Scope.Add("openid");
o.Scope.Add("email");
o.Scope.Add("profile");
o.GetClaimsFromUserInfoEndpoint = true;
o.SaveTokens = true;
o.Events = new OpenIdConnectEvents()
{
OnRedirectToIdentityProvider = (context) =>
{
// Add domain limiting using 'hd' or 'hosted domain' parameter
// Docs: https://developers.google.com/identity/protocols/OpenIDConnect#hd-param
//context.ProtocolMessage.SetParameter(hostedDomain.Key, "asdf.com");
// Set up redirect URLs
if (context.Request.Path != "/account/external")
{
context.Response.Redirect("/account/login");
context.HandleResponse();
}
return Task.FromResult(0);
},
OnTokenValidated = (c) =>
{
var hdClaim = c.SecurityToken.Claims.FirstOrDefault(claim => claim.Type == hostedDomain.Key);
if(hdClaim?.Value == null || hdClaim.Value != hostedDomain.Value)
{
// The claim is null or value is not the trusted google domain - do not authenticate!
c.Fail($"Invalid claim for '{hostedDomain.Key}'! User does not belong to trusted G Suite Domain");
}
return Task.FromResult(0);
}
};
});
services.AddMvc();
}
The above works when an incorrect or null hd claim is given which is done by logging in with an account not in the domain name in the hostedDomain.Value. I tried setting the c.Response.StatusCode = 401; but the user still logs in.
Another way to do this would be to use authorization.
You can set up a default authorization policy that requires the presence of the claim you test for. Then any caller that does not have the claim would get redirected to an access denied page. Something like:
services.AddAuthorization(o =>
{
o.AddPolicy("default", policy =>
{
policy.RequireAuthenticatedUser()
.RequireClaim("hd", "mysite.com");
});
});
services.AddMvc(o =>
{
o.Filters.Add(new AuthorizeFilter("default"));
});

How to return an observable from a http service in angular2

Unfortunately as I was storing many results on the service, I'm now stuck with many {{myservice.somevalue}} (and myservice.someother) etc. sprinkled over my other components.
I believe it would be nicer to return from the service to a component.
This is the code that I have on the service:
getIssue(issueName: string) {
return this.http.post(this.URL + 'issue/all', JSON.stringify({'issueName': issueName}))
.subscribe(data => this.somevalue = data.json(),
err => console.log(err));
}
So then on several other components I call functions like this.myservice.getIssue(issueName).
In the HTML I'd prefer to use {{somevalue}}.
What can I do to return a http observable from the http service?
class SomeService {
someValue = new BehaviorSubject();
getIssue(issueName: string) {
return this.http.post(this.URL + 'issue/all', JSON.stringify({'issueName': issueName}))
.subscribe(data => this.somevalue.next(data.json()),
err => console.log(err));
}
}
In your component
class MyComponent {
constructor(someService:SomeService) {
someService.someValue.subscribe(val => {
this.someValue = val;
});
}
}
For an alternative approach see also https://stackoverflow.com/a/36291681/217408

Angular2 - How to chain async service calls (http requests) in a component?

I have a component which first need to call a service that POST something. Then in the same component I want to wait until the POST is done, to call another service which GETs data.
How can I make the GET call wait for the POST call to finish?
In new-version.component.ts:
private createNewVersion(value) {
...
// create new version, then call on all available versions
// POST call
this._newVersionService.createNewVersion(vnr);
// GET call
this._versionService.getAvailableVersions();
...
}
In new-version.service.ts:
export class NewVersionService {
response$: Subject<any>;
constructor(private _http: Http) {
this.response$ = new BehaviorSubject<any>(null);
}
public createNewVersion(versionNr) {
this._http.post('http://localhost:8080/services/' + versionNr, null, {
method: 'POST',
})
.subscribe(response => {
this.response$.next(response.status);
},
error => console.error(error));
}
Thanks!
When a call returns a Promise chain the calls with
someFunction() {
return returnsPromise()
.then(result => doSomethingNext())
.then(result => doSomethingAfterThat());
}
Ensure you have a return that returns the Promise of that chain so the caller of someFunc() also has a chance to time additional work to execute after doSomethingAfterThat() is completed.
When a call returns an Observable then use the complete callback
someFunction() {
return returnsObservable()
.subscribe(
event => doForEachEvent(),
error => handleError(),
() => doSomethingNext()
.then(result => doSomethingAfterThat());
}
doSomethingNext() is executed after the last event and doSomethingAfterThat() is again chained with then() to show how to mix observable and promise. doSomething().
You should be able to concat to achieve sequence, and reduce to collect the emitted values:
var a = this._newVersionService.createNewVersion(vnr);
var b = this._versionService.getAvailableVersions();
Rx.Observable.concat(a, b).reduce((acc:Array<any>, x:any) => {
acc.push(x); return acc;
}, []).subscribe(t=> {
var firstEmitted = t[0];
var secondEmitted = t[1];
});
You can do like this:
Change createNewVersion to:
public createNewVersion(versionNr) {
return this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
method: 'POST',
});
}
Then in your call:
this._newVersionService.createNewVersion(vnr).subscribe(response=> {
this._versionService.getAvailableVersions();
}, error => console.error(error));
Another way to do the same is to subscribe in the new-version.component.ts and call you GET request from within the POST request i.e check whether your POST request is done Correctly or not
if yes POST is done Properly then call you GET request. As below:
In new-version.component.ts:
private createNewVersion(value) {
...
// create new version, then call on all available versions
// POST call
this._newVersionService.createNewVersion(vnr)
.subscribe((res) => {
if(res){
console.log(res);
if (---Post request done properly check via status or something else here----{
CALL YOUR GET REQUEST HERE.....
// GET call
this._versionService.getAvailableVersions();
}
else {
DO something else whatever you want....
}
}
});
...
}
In new-version.service.ts:
export class NewVersionService {
response$: Subject<any>;
constructor(private _http: Http) {
this.response$ = new BehaviorSubject<any>(null);
}
public createNewVersion(versionNr) {
this._http.post('http://localhost:8080/nod_inspection_plugin/services/' + versionNr, null, {
method: 'POST',
})
.map(response => {
return [{status: response.status, json: response.json()}];
},
error => console.error(error));
}
for more info related to http request you can read here.
Better use switchMap() here.
const versions$ = this._newVersionService.createNewVersion(vnr)
.switchMap(response => this._versionService.getAvailableVersions());
versions$.subscribe(response2 => this.versions = response2)
But the problem will be if you make another POST request before first has been resolved, the previous request will get cancelled.

Observing Store State Changes in Middleware

I'm writing a piece of Redux Middleware which is responsbile for adding the user's OAuth AccessToken to API_CALL cations before they hit the redux-api-middleware.
// sign appends the `Authorization` HTTP Header to an API_CALL action
function sign(action) {
action[CALL_API].headers = {
...action[CALL_API].headers,
Authorization: `Bearer ${getState()auth.accessToken}`;
}
}
// Redux middleware signature.
return ({dispatch, getState}) => {
return next => action => {
if (action[CALL_API]) {
sign(action);
}
return next(action);
}
}
However, I also want this middleware to detect when the User's AccesToken has expired...
function tokenExpired() {
return (Date.now() > getState().auth.expirationTime);
}
When this happens, the middleware detains the action (prevents it from being passed to the next middleware in the chain) and stores it in an internal list. It then kicks off the async. Token refresh process by dispatching a 'refresh access token' FSA:
if (tokenExpired()) {
// detainActions is an array, declared outside
// of the middleware's scope.
detainActions.push(action);
dispatch(refreshAccessToken());
}
else {
next(sign(action));
}
Finally, I want to listen for when the 'refresh access token' flow has completed and flush (re-dispatch) all detained actions. Currently I am doing this by looking out for AUTHENTICATION_RESPONSE FSA's as they flow through my middleware (the AUTHENTICATION_RESPONSE action is dispatched as as side-effect of the refreshAccessToken thunk.
// Redux middleware signature.
return ({dispatch, getState}) => {
return next => action => {
if (action.type === AUTHENTICATION_RESPONSE && !action.error) {
// Let the AuthResponse action pass to the store.
next(action);
// Flush detained actions now we have a new grant.
return flushAndRedispatchDetainedActions(dispatch);
}
else {
// Sign CALL_API requests logic as above.
}
}
}
However I am not happy with this approach as there is no certainty that the AUTHENTICATION_RESPONSE FSA will actually hit the reducers (it may be intercepted by other middleware, or be further defered).
Possible alternative approaches I have considered are having the refreshAccessToken actionCreator return a thunk which returns a Promise; that way my middleware can wait for that promise to resolve before flushing and replaying all requests, ie:
if (tokenExpired()) {
// refreshAccessToken thunk returns a Promise.
dispatch(refreshAccessToken());
.then(flushAndRedispatchDetainedActions();
}
Or alternativley I could have my middleware observe the store directly and trigger an action when the auth.accessToken value changes - however, I'm not clear on what the guidance is for middleware observing the store (I'm guessing it's not possible as middleware needs to be instantiated before the final store object is created.)
Thanks :)
Update
Thinking about the problem on the way home; if I were to move the actual authentication logic out of refreshAccessToken (a thunk'd action creator), and into the middleware itself then I would save a lot of pain:
// Redux middleware signature.
return ({dispatch, getState}) => {
return next => action => {
if (action[CALL_AUTH]) {
authHelper.refreshGrant()
.then(grant => dispatch(processGrant(newGrant));
}
else {
// Sign CALL_API requests logic as above.
}
}
}

Resources