It is not working. I want to index method deny for particular role and redirect on other page.
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->deny(['index']); // it's not working
}
you should do the tutorial:
http://book.cakephp.org/3.0/en/tutorials-and-examples/blog-auth-example/auth.html
and then you will stumble on something like this in your controller:
public function isAuthorized($user)
{
// deny index action for certain role
if ($this->request->action === 'index' && $user['role'] === 'particular_role') {
return false;
}
return parent::isAuthorized($user);
}
and this in your appController:
public function isAuthorized($user)
{
// Everyone can access everything
return true;
}
Related
I have a code for checking a session isset or not in Yii2, I added the code inside a function in a controller, this is the code
if(!isset($session['selectedMonth'])){
return $this->redirect(['select-period/month']);
return false;
}
I have over than 50 functions in 10 controllers, I want every function use that code, how do I can make it without put that code in every function one by one?
You could create base controller for your app, and extend all other controllers from it. Then you could add beforeAction() method in this base controller, so it will be used by all controllers that inherit from base controller:
public function beforeAction($action) {
// initialize $session here
if(!isset($session['selectedMonth'])){
Yii::$app->response->redirect(['select-period/month']);
return false;
}
return parent::beforeAction($action);
}
You can create simple behavior that will handle 'before action' event, for example:
use Yii;
use yii\base\Behavior;
use yii\base\Controller;
class RedirectBehavior extends Behavior
{
public function events()
{
return [
Controller::EVENT_BEFORE_ACTION => 'beforeAction',
];
}
public function beforeAction($event)
{
if (Yii::$app->session->has('selectedMonth')){
return;
}
Yii::$app->getResponse()->redirect(['select-period/month'])->send();
}
}
and attach it to your controllers
public function behaviors()
{
return [
'redirect' => [
'class' => RedirectBehavior::className(),
],
];
}
I'm using dectrium rbac. I created the following rule:
<?php
namespace common\rbac;
use yii\rbac\Rule;
class OwnerRule extends Rule
{
public $name = 'isOwner';
public function execute($user, $items, $params) {
if (!isset($params['object'])) return false;
if (!isset($params['object']->author_id)) return false;
return $params['object']->author_id == $user;
}
}
Then I tried to create the rule in the backend, dectrium rbac provides. Doing this I get the error message "Class OwnerRule does not exist". Obviously
if (!class_exists($this->class))
returns true. What might be the reason?
I have a button on my nav bar (app.component.html) that I want to only show when the user is logged in.
This is my current approach that does not work for obvious reasons explained later. I want to find out how I can modify it to work.
Inside my app.component.html, I have the following button
<button *ngIf="isCurrentUserExist">MyButton</button>
Inside my app.component.ts, I am trying to bound the variable isCurrentUserExist to a function that returns true if the user exists.
I believe this is the problem because this code is only executed once at OnInit as oppose to somehow keeping the view updated
ngOnInit() {
this.isCurrentUserExist = this.userService.isCurrentUserExist();
}
For reference, inside my UserService.ts
export class UserService {
private currentUser: User
constructor(private http: Http,private angularFire: AngularFire) { }
getCurrentUser(): User {
return this.currentUser
}
setCurrentUser(user: User) {
this.currentUser = user;
}
isCurrentUserExist(): boolean {
if (this.currentUser) {
return true
}
return false
}
}
A bit more information about my app...
Upon start up when the user does not exist, I have a login screen (login component).
When the user logs in, it goes to firebase and grab the user information (async) and store it to my user service via
setCurrentUser(user: User)
So at this point, I like to update the button in my nav bar (which exists in app.component.html) and show the button.
What can I do to achieve this?
let's try this:
using BehaviorSubject
UserService.ts
import { Subject, BehaviorSubject} from 'rxjs';
export class UserService {
private currentUser: User;
public loggedIn: Subject = new BehaviorSubject<boolean>(false);
constructor(private http: Http,private angularFire: AngularFire) { }
getCurrentUser(): User {
return this.currentUser
}
setCurrentUser(user: User) { // this method must call when async process - grab firebase info - finished
this.currentUser = user;
this.loggedIn.next(true);
}
isCurrentUserExist(): boolean {
if (this.currentUser) {
return true
}
return false
}
}
app.component.ts
ngOnInit() {
this.userService.loggedIn.subscribe(response => this.isCurrentUserExist = response);
}
in app.component.ts you are assigned value from function once. So it will never change. To resolve this problem and to real time update use assign function instance of boolean variable this.isCurrentUserExist = this.userService.isCurrentUserExist;. And in view change change *ngIf expression as function isCurrentUserExist().
I wonder which one of these methods is the best when trying get a variable from anotherClass to the Main-document-class, and why? Are there any more, even better ways?
In example no 1, and the Main-function, can the if-else statement be triggered before the checkLogin function was completely done? Thanks!
My no 1. way
public class Main extends MovieClip {
// Declaring other classes.
private var checkLogin:CheckLogin;
public function Main() {
checkLogin = new CheckLogin();
if(checkLogin.isLoggedIn == true) {
trace("Is logged in");
} else {
trace("Not logged in");
}
}
}
and
public class CheckLogin {
public var isLoggedIn:Boolean;
public function CheckLogin() {
isLoggedIn = false;
}
}
Or is it a lot better to do it this way,
(Way no 2):
public class Main extends MovieClip {
// Declaring other classes.
private var checkLogin:CheckLogin;
public function Main() {
checkLogin = new CheckLogin();
checkLogin.addEventListener("checkLogin.go.ready", checkLoginReady);
checkLogin.go();
}
public function checkLoginReady(event = null) {
if(checkLogin.isLoggedIn == true) {
trace("Is logged in");
} else {
trace("Not logged in");
}
}
}
and
public class CheckLogin extends EventDispatcher {
public var isLoggedIn:Boolean;
public function CheckLogin() {
isLoggedIn = true;
}
public function go() {
this.dispatchEvent(new Event("checkLogin.go.ready"));
}
}
Generally, using events will make your code easier to maintain.
The login check you describe seems to be instant, so approach number 1 would be ok for such a simple case.
Often the login check (or whatever process) may not be instant, for example if the CheckLogin class sent a server request and waited for the response. In this case using events is better. The Main class can listen for a LOGIN_SUCCESS or LOGIN_FAIL event and handle it when the event occurs. All the login logic stays within CheckLogin.
Also, using events will allow multiple interested classes to react, without them knowing any of the inside login process.
In Flash I'm calling authenticate first after constructing, how to avoid popup blocker.
public function FacebookProxy(appID:String, permissions:Object) {
this.appID = appID;
this.permissions = permissions;
}
public function authenticate():void {
var response:FacebookAuthResponse = Facebook.getAuthResponse();
if(response && response.uid) {
this.success(response);
} else {
this.init();
}
}
protected function init():void {
Security.loadPolicyFile("https://fbcdn-profile-a.akamaihd.net/crossdomain.xml");
Facebook.init(this.appID, this.initHandler);
}
protected function initHandler(response:FacebookAuthResponse, fail:Object):void {
if(response && response.uid){
this.success(response);
} else {
setTimeout(this.login, 200);
}
}
protected function login():void {
Facebook.login(loginHandler, this.permissions);
}
protected function loginHandler(response:FacebookAuthResponse, fail:Object):void {
if(response && response.uid) {
this.success(response);
} else {
//ExternalInterface.call("trace", "code:" + fail.error.code + ", message:" + fail.error.message + ", type:" + fail.error.type);
}
}
protected function success(response:FacebookAuthResponse):void {
}
I dont know flash, but you cant call Facebook.init, Facebook.login automatically, it will be caught by popup blockers.
Fire these two methods on users activity only i.e. on a click of user.
From what I remember, the most frictionless way of logging into Facebook (going by game apps, no popular, and one permissions screen) is to log in using the js api and pass the details into flash