silverstripe external authentification - content-management-system

there is a custom login form that should give users access to certain contents on the same page. That works so far with Users stored as Members in the SS database and I was checking after Login if the user has permissions like this in the Page Class:
function isAllowed() {
if (Member::currentUser()) {
$PresseGroup = DataObject::get_one('Group', "Code = 'presse'");
$AdminGroup = DataObject::get_one('Group', "Code = 'administrators'");
if (Member::currentUser()->inGroup($PresseGroup->ID) || Member::currentUser()->inGroup($AdminGroup->ID)) {
return true;
}
}
}
in the Template I just did this:
<% if isAllowed %>
SecretContent
<% end_if %>
OK so far, but now the users will not be stored in the silverstripe database - they are stored on a another server.
On that external server is running a little php script accepting the username and password. The script just returns user has permission: true or false.
I´m calling that script via cURL.
I planned to overwrite the dologin Function of MemberLoginForm. Now I just wonder how to check after Login that the User got the permission and display the contents... I tried to set a variable in the controller of the Page or should I set a session Variable? Thats my attempt (CustomLoginForm extends MemberLoginForm):
public function dologin($data) {
if(userHasPermission("user1", "pw")==true){
$this->controller->Test("test");
}
$link = $this->controller->Link();
$this->performLogin($data);
$this->controller->redirect($link);
}
I hope someone can help me with that - I know very specific - problem.
Many thanx,
Florian

In SilverStripe you can create a custom authenticator, which means users can log in on your website with accounts that are stored somewhere else, or even just a hard coded user and password.
You can check out the OpenID Authentication Module for example code on how to do it
But for your task this might even be to complex of a solution, how about after login just do something like Session::set('isAllowed', true); and to check if the user is allowed to view:
function isAllowed() {
if (Member::currentUser()) {
$PresseGroup = DataObject::get_one('Group', "Code = 'presse'");
$AdminGroup = DataObject::get_one('Group', "Code = 'administrators'");
if (Member::currentUser()->inGroup($PresseGroup->ID) || Member::currentUser()->inGroup($AdminGroup->ID)) {
return true;
}
}
// if Member::currentUser() is not allowed to view,
// return the session, which is either set to true or it returns null if not set
return Session::get('isAllowed');
}

Related

How to block url that customer type on browser in codeigniter?

I have created a website, And I don't to allowed customer to type link in browser.
I just want to allow customer click link on the website only.
please provide me a solution !!!
thank for help !!!
use token for in hyperlinks . deny if token wont match to value in session.
try the following:
in controller check if session['token'] is set,
if not set session['token'] to a rendom value.
if token not set or won't match to $_GET['token'] variable redirect to error page.
if token match to get variable (ie. $_GET['token']) then , pass that value to view.
i don't recomend this because doing this might affect the browser cache.
Controller constructor
function __construct()
{
parent::__construct();
$this->load->library('session');
if(!isset($_SESSION['token']))
{
$_SESSION['token'] = rand();
}
if((!$this->input->get('token')) || ($this->input->get('token') != $_SESSION['token']))
{
redirect('error_page');
}
// to pass to vew
$data['token'] = $_SESSION['token'];
$this->load->view('view_page',$data);
}
in view_page.php (view) replace links like this
Gallery link

Codeigniter - Form validation callback not working on server, but OK on WAMP

I've developed a CI site on my local machine using WAMP. I'm using CI 3 with the HMVC extension and it all works fine.
I've just uploaded the site to the production server and changed the config files etc to get it working. However, form validation callbacks are not working on the production server.
Here's an example from a login form:
// Process login form
public function submit()
{
$this->load->library('form_validation');
$username = $this->input->post('username', TRUE);
$this->form_validation->set_rules('username', 'Username', 'required');
$this->form_validation->set_rules('password', 'Password', 'required|callback_do_login');
if($this->form_validation->run($this) == FALSE)
{
$this->login();
}
else
{
// Set login session
...
}
}
This is the callback function do_login:
public function do_login($password)
{
// Get user / pass from POST
$submitted_password = $this->input->post('password', TRUE);
$username = $this->input->post('username', TRUE);
$this->crud->setTable($this->table);
$this->load->model('mdl_users');
// Check User Exists
$query = $this->mdl_users->getUser($username);
if($query->num_rows() == 1)
{
// Get stored password
$row = $query->row();
$stored_password = $row->password;
// Check password
$this->load->module('mod_security');
$result = $this->mod_security->login($username, $submitted_password, $stored_password); // Returns false if no match
return ($result) ? TRUE : FALSE;
}
else
{
return FALSE;
}
}
On my local WAMP setup, this all works fine. But on the server
$this->form_validation->run($this)
always returns false.
To eliminate any errors with the callback function itself, I changed it to the following as a test:
public function do_login($password)
{
return TRUE;
}
... which will obviously always return TRUE, however when $this->form_validation->run($this) is called, even though I changed the do_login callback function to return TRUE, $this->form_validation->run($this) still returns FALSE!!
This is driving me crazy and I have no idea why this is happening. It is as if the form validation is ignoring the callback function and just returning false.
Can anyone help me? Could it be a setting on the server causing it or something else that could have changed when I uploaded the site files to the server?
If it is relevant, on my local machine, within the do_login callback function I had originally set the callback error message like this:
$this->form_validation->set_message('do_login', 'User / Pass Incorrect');
...which worked fine, but on the production server it threw an error stating: "Unable to access an error message corresponding to your field name Password.(do_login)". I had to set the error message in the language library file to overcome this. But the fact that this happened on the production server and not on my WAMP setup makes me think there must be some setting or something on the server that is causing this.
Anyway, any help is gratefully received.
Thanks
I finally found the solution. The HMVC application requires a small library file named as MY_Form_validation.php. Seemingly everywhere on the net this file is shown to be thus:
class MY_Form_validation extends CI_Form_validation {
function run($module = '', $group = '')
{
(is_object($module)) AND $this->CI = &$module;
return parent::run($group);
}
}
However, although this worked in my WAMP setup, it did not work on my server. I found that by declaring the CI variable at the start the server problem is resolved. So the MY_Form_validation.php file finally becomes:
class MY_Form_validation extends CI_Form_validation {
public $CI;
function run($module = '', $group = '')
{
(is_object($module)) AND $this->CI = &$module;
return parent::run($group);
}
}

Exchanging Facebook Auth Code for Access Token using the PHP SDK

I am trying to build a server-to-server auth flow using the Facebook PHP SDK and no Javascript, as outlined here. So far, I have successfully created a LoginUrl that lets the User sign in with Facebook, then redirect back to my App and check the state parameter for CSFR protection.
My Problem is, that I can't seem to get the API-call working that should swap my Auth Code for an access token. I pillaged every similar problem anyone else that Google was able to find had encountered for possible solutions.
Yet the end result was always the same: no access token, no error message that I could evaluate.
Researching the topic yielded the following advice, which I tested:
The URL specified in the App Settings must be a parent folder of $appUrl.
use curl to make the request instead of the SDK function api()
I've been at this for 2 days straight now and really could use some help.
<?php
require '../inc/php-sdk/src/facebook.php';
// Setting some config vars
$appId = 'MY_APP_ID';
$secret = 'MY_APP_SECRET';
$appUrl = 'https://MY_DOMAIN/appFolder';
$fbconfig = array('appId'=>$appId, 'secret'=>$secret);
$facebook = new Facebook($fbconfig);
// Log User in with Facebook and come back with Auth Code if not yet done
if(!(isset($_SESSION['login']))){
$_SESSION['login']=1;
header('Location: '.$facebook->getLoginUrl());
}
// process Callback from Facebook User Login
if($_SESSION['login']===1) {
/* CSFR Protection: getLoginUrl() generates a state string and stores it
in "$_SESSION['fb_'.$fbconfig['appId'].'_state']". This checks if it matches the state
obtained via $_GET['state']*/
if (isset($_SESSION['fb_'.$fbconfig['appId'].'_state'])&&isset($_GET['state'])){
// Good Case
if ($_SESSION['fb_'.$fbconfig['appId'].'_state']===$_GET['state']) {
$_SESSION['login']=2;
}
else {
unset($_SESSION['login']);
echo 'You may be a victim of CSFR Attacks. Try logging in again.';
}
}
}
// State check O.K., swap Code for Token now
if($_SESSION['login']===2) {
$path = '/oauth/access_token';
$api_params = array (
'client_id'=>$appId,
'redirect_uri'=>$appUrl,
'client_secret'=>$secret,
'code'=>$_GET['code']
);
$access_token = $facebook->api($path, 'GET', $api_params);
var_dump($access_token);
}
The easiest way I found to do this is to extend the Facebook class and expose the protected getAccessTokenFromCode() method:
<?php
class MyFacebook extends Facebook {
/** If you simply want to get the token, use this method */
public function getAccessTokenFromCode($code, $redirectUri = null)
{
return parent::getAccessTokenFromCode($code, $redirectUri);
}
/** If you would like to get and set (and extend), use this method instead */
public function setAccessTokenFromCode($code)
{
$token = parent::getAccessTokenFromCode($code);
if (empty($token)) {
return false;
}
$this->setAccessToken($token);
if (!$this->setExtendedAccessToken()) {
return false;
}
return $this->getAccessToken();
}
}
I also included a variation on the convenience method I use to set the access token, since I don't actually need a public "get" method in my own code.

CakePHP 2.3.1 Facebook authentication

I'm using CakePHP 2.3.1 and this plugin: https://github.com/webtechnick/CakePHP-Facebook-Plugin to implement a facebook authentication. I followed this screen cast http://tv.cakephp.org/video/webtechnick/2011/01/12/nick_baker_--_facebook_integration_with_cakephp but it doesn't work, I can't receive the Facebook user information. I mean $this->Connect->user() always return null.
First make sure your user as granted access to your app. Then make a call to retrieve personal details through the api(/me) => $this->Connect->user()
Personally, I use this
public function beforeFilter(){
if($this->Connect->FB->getUser() != 0){
$this->set('facebookUser', $this->Connect->user());
}
Initiating ConnectComponent will populate (or not) the Auth Session. If no id is to be found, redirect user to a login dialog.
Call this method from beforefilter..and save the post data received in some variable like fb_data here.
protected function _valdiateFbRequest() {
if (!isset($this->request->data['signed_request'])) {
// not a valid request from fb
// throw exception or handle however you want
return;
}
$this->signedRequest = $this->request->data['signed_request'];
$this->fb_data=$this->Connect->registrationData(); //save fb data
unset($this->request->data['signed_request']);
if (empty($this->request->data)) {
$this->Security->csrfCheck = false;
}
// validate the request
}

Cakephp 2.1 Facebook Connect And Auth

I'm using the below plugin in my app to get facebook connect working with auth.
https://github.com/webtechnick/CakePHP-Facebook-Plugin
The thing is I want to save user data into users table manually.
So I'm trying like this
public function beforeFacebookSave(){
//$this->Auth->autoRedirect = false;
debug($this->Connect->user('email'));
$this->Connect->authUser['User']['email'] = $this->Connect->user('email');
$this->Connect->authUser['User']['username'] = $this->Connect->user('username');
//Must return true or will not save.
$this->redirect(array('controller' => 'users', 'action' => 'beforefbsave', '?' => array('param1' => $this->Connect->user('email'))));
//return true;
}
The redirect is getting into a loop and getting an error
The page isn't redirecting properly
Is this a proper way or have follow some other method to get this done?
there is a documentation on page:
https://github.com/webtechnick/CakePHP-Facebook-Plugin
beforeFacebookSave handle the user to save into the users table. If returned false, creation is haulted.
//Add an email field to be saved along with creation.
function beforeFacebookSave(){
$this->Connect->authUser['User']['email'] = $this->Connect->user('email');
return true; //Must return true or will not save.
}
so if i were you i' d look on the next section:
beforeFacebookLogin Handle the user before logging the user into Auth.
function beforeFacebookLogin($user){
//Logic to happen before a facebook login
}
and instead of redirection use direct functions from your model.