I'm trying to utilize the external class on my idp install of simple saml. The idp works fine for logging in user/pass but I need the external to help verify some types of users.
Here is the class I'm attempting to modify and use
https://github.com/simplesamlphp/simplesamlphp/blob/56a8949141a3aa2d783763aaaaccaa0ccf6164c2/modules/exampleauth/lib/Auth/Source/External.php
I keep getting this php fatal error
PHP Fatal error: Declaration of SimpleSAML\Module\mymodule\Auth\Source\MyAuth::authenticate() must be compatible with SimpleSAML\Auth\Source::authenticate(&$state) in /var/simplesamlphp/modules/mymodule/lib/Auth/Source/MyAuth.php on line 355, referer: https://xxxxxxxyyyyyzzzzz.com/
I've googled and cannot seem to find anything relating to this. Any ideas where I might have gone wrong or what I may try to fix?
<?php
declare(strict_types=1);
namespace SimpleSAML\Module\mymodule\Auth\Source;
use SimpleSAML\Assert\Assert;
use SimpleSAML\Auth;
use SimpleSAML\Error;
use SimpleSAML\Module;
use SimpleSAML\Utils;
//use Symfony\Component\HttpFoundation\Request;
//use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
/**
* Example external authentication source.
*
* This class is an example authentication source which is designed to
* hook into an external authentication system.
*
* To adapt this to your own web site, you should:
* 1. Create your own module directory.
* 2. Enable to module in the config by adding '<module-dir>' => true to the $config['module.enable'] array.
* 3. Copy this file to its corresponding location in the new module.
* 4. Replace all occurrences of "mymodule" in this file with the name of your module.
* 5. Adapt the getUser()-function, the authenticate()-function and the logout()-function to your site.
* 6. Add an entry in config/authsources.php referencing your module. E.g.:
* 'myauth' => [
* '<mymodule>:External',
* ],
*
* #package SimpleSAMLphp
*/
class MyAuth extends Auth\Source
{
/**
* The key of the AuthId field in the state.
*/
//public const AUTHID = 'SimpleSAML\Module\mymodule\Auth\Source\MyAuth.AuthId';
const AUTHID = 'SimpleSAML\Module\mymodule\Auth\Source\MyAuth.AuthId';
/**
* Constructor for this authentication source.
*
* #param array $info Information about this authentication source.
* #param array $config Configuration.
*/
public function __construct(array $info, array $config)
{
// Call the parent constructor first, as required by the interface
parent::__construct($info, $config);
// Do any other configuration we need here
}
/**
* Log in using an external authentication helper.
*
* #param array &$state Information about the current authentication.
*/
public function authenticate(array &$state)
//public function authenticate(array &$state)
{
require_once('/yyy/xxx/some_server/public_html/web/setup.php');
$_users = new \Users;
$user = $_users->verifyUser($username,$password);
$attributes = [
'user_id' => [$user['user_id']],
'mfg_dealer_number' => [$user['mfg_dealer_number']],
'location_name' => [$location['name']],
'first_name' => [$name[0]],
'last_name' => [$name[1]],
'email' => [$user['email']],
'address1' => [$location['address']],
'address2' => [$location['address2']],
'city' => [$location['city']],
'country' => [$location['country_abbrev']],
'state' => [$location['state_abbrev']],
'zip' => [$location['zip']],
'phone' => [$location['phone']],
'user_type' => [$user_type],
];
if ($attributes !== null) {
/*
* The user is already authenticated.
*
* Add the users attributes to the $state-array, and return control
* to the authentication process.
*/
$state['Attributes'] = $attributes;
return;
}
/*
* The user isn't authenticated. We therefore need to
* send the user to the login page.
*/
/*
* First we add the identifier of this authentication source
* to the state array, so that we know where to resume.
*/
$state['mymodule:AuthID'] = $this->authId;
/*
* We need to save the $state-array, so that we can resume the
* login process after authentication.
*
* Note the second parameter to the saveState-function. This is a
* unique identifier for where the state was saved, and must be used
* again when we retrieve the state.
*
* The reason for it is to prevent
* attacks where the user takes a $state-array saved in one location
* and restores it in another location, and thus bypasses steps in
* the authentication process.
*/
$stateId = Auth\State::saveState($state, 'mymodule:MyAuth');
/*
* Now we generate a URL the user should return to after authentication.
* We assume that whatever authentication page we send the user to has an
* option to return the user to a specific page afterwards.
*/
$returnTo = Module::getModuleURL('mymodule/resume', [
'State' => $stateId,
]);
/*
* Get the URL of the authentication page.
*
* Here we use the getModuleURL function again, since the authentication page
* is also part of this module, but in a real example, this would likely be
* the absolute URL of the login page for the site.
*/
$authPage = Module::getModuleURL('mymodule/authpage');
/*
* The redirect to the authentication page.
*
* Note the 'ReturnTo' parameter. This must most likely be replaced with
* the real name of the parameter for the login page.
*/
$httpUtils = new Utils\HTTP();
$httpUtils->redirectTrustedURL($authPage, [
'ReturnTo' => $returnTo,
]);
/*
* The redirect function never returns, so we never get this far.
*/
Assert::true(false);
}
/**
* Resume authentication process.
*
* This function resumes the authentication process after the user has
* entered his or her credentials.
*
* #param \Symfony\Component\HttpFoundation\Request $request
*
* #throws \SimpleSAML\Error\BadRequest
* #throws \SimpleSAML\Error\Exception
*/
public static function resume(Request $request)
{
/*
* First we need to restore the $state-array. We should have the identifier for
* it in the 'State' request parameter.
*/
if (!$request->query->has('State')) {
throw new Error\BadRequest('Missing "State" parameter.');
}
/*
* Once again, note the second parameter to the loadState function. This must
* match the string we used in the saveState-call above.
*/
$state = Auth\State::loadState($request->query->get('State'), 'mymodule:MyAuth');
/*
* Now we have the $state-array, and can use it to locate the authentication
* source.
*/
$source = Auth\Source::getById($state['mymodule:AuthID']);
if ($source === null) {
/*
* The only way this should fail is if we remove or rename the authentication source
* while the user is at the login page.
*/
throw new Error\Exception('Could not find authentication source with id ' . $state[self::AUTHID]);
}
/*
* Make sure that we haven't switched the source type while the
* user was at the authentication page. This can only happen if we
* change config/authsources.php while an user is logging in.
*/
if (!($source instanceof self)) {
throw new Error\Exception('Authentication source type changed.');
}
/*
* OK, now we know that our current state is sane. Time to actually log the user in.
*
* First we check that the user is acutally logged in, and didn't simply skip the login page.
*/
require_once('/yyy/xxx/some_server/public_html/web/setup.php');
$_users = new \Users;
$user = $_users->verifyUser($username,$password);
$attributes = [
'user_id' => [$user['user_id']],
'mfg_dealer_number' => [$user['mfg_dealer_number']],
'location_name' => [$location['name']],
'first_name' => [$name[0]],
'last_name' => [$name[1]],
'email' => [$user['email']],
'address1' => [$location['address']],
'address2' => [$location['address2']],
'city' => [$location['city']],
'country' => [$location['country_abbrev']],
'state' => [$location['state_abbrev']],
'zip' => [$location['zip']],
'phone' => [$location['phone']],
'user_type' => [$user_type],
];
if ($attributes === null) {
/*
* The user isn't authenticated.
*
* Here we simply throw an exception, but we could also redirect the user back to the
* login page.
*/
throw new Error\Exception('User not authenticated after login page.');
}
/*
* So, we have a valid user. Time to resume the authentication process where we
* paused it in the authenticate()-function above.
*/
$state['Attributes'] = $attributes;
Auth\Source::completeAuth($state);
/*
* The completeAuth-function never returns, so we never get this far.
*/
Assert::true(false);
}
/**
* This function is called when the user start a logout operation, for example
* by logging out of a SP that supports single logout.
*
* #param array &$state The logout state array.
*/
public function logout(array &$state)
{
//$session = new SymfonySession();
//if (!$session->getId()) {
// $session->start();
//}
$session->clear();
/*
* If we need to do a redirect to a different page, we could do this
* here, but in this example we don't need to do this.
*/
}
}
You seem to be mixing up two SimpleSAML versions.
This code:
public function authenticate(array &$state)
has "array" typehint in it while the class you're extending in SimpleSAMLphp does not, as evidenced from the error message:
must be compatible with SimpleSAML\Auth\Source::authenticate(&$state)
So remove the array keyword. If you use code/documentation that matches the SimpleSAMLphp version you are running this should match.
Related
I generated flag link
$flag_link = [
'#lazy_builder' => ['flag.link_builder:build', [
$product->getEntityTypeId(),
$product->id(),
'product_like',
]],
'#create_placeholder' => TRUE,
];
Flag link is generated successfully. But while I click flag link , I got error message as response
{message: "'csrf_token' URL query argument is invalid."}
message: "'csrf_token' URL query argument is invalid."
I found a temporary solution. Not sure if this is a bug in Flag that needs to be addressed by the module maintainers, or if this is working as intended, since this is a REST response, and not a typical Drupal call for a view or display mode.
In the ModuleRestResource.php file (In my case, the ModuleRestResource.php file is located at:
{{DRUPAL_ROOT}}/web/modules/custom/{{Module_Name}}/src/Plugin/rest/resource/{{Module_Name}}RestResource.php):
use Drupal\rest\ModifiedResourceResponse;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Entity\EntityInterface;
use Drupal\flag\FlagService;
use Drupal\Core\Render\RenderContext;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class ModuleRestResource extends ResourceBase {
/**
* A current user instance.
*
* #var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* #var $entityTypeManager \Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;
/**
* #var \Drupal\flag\FlagService
*/
protected $flagService;
/**
* #var Drupal\Core\Access\CsrfTokenGenerator
*/
protected $csrfService;
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->logger = $container->get('logger.factory')->get('module');
$instance->currentUser = $container->get('current_user');
$instance->entityTypeManager = $container->get('entity_type.manager');
$instance->flagService = $container->get('flag');
$instance->csrfService = $container->get('csrf_token');
return $instance;
}
/**
* Responds to GET requests.
*
* #param string $payload
*
* #return \Drupal\rest\ResourceResponse
* The HTTP response object.
*
* #throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function get($payload) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
if (!is_numeric($payload)) {
throw new BadRequestHttpException();
}
/*
* This is the object that will be returned with the node details.
*/
$obj = new \stdClass();
// First load our node.
/**
* #var \Drupal\Core\Entity\EntityInterface
*/
$node = $this->entityTypeManager->getStorage('node')->load($payload);
/**
* FIX STARTS HERE !!!!!
*/
/**
* Because we are rending code early in the process, we need to wrap in executeInRenderContext
*/
$render_context = new RenderContext();
$fl = \Drupal::service('renderer')->executeInRenderContext($render_context, function() use ($node, $payload) {
/**
* Get the flag we need and check if the selected node has been flagged by the current user
*
* Set the path to create a token. This is the value that is missing by default that creates an
* invalid CSRF Token. Important to note that the leading slash should be left off for token generation
* and then added to to the links href attribute
*
*/
$flag = $this->flagService->getFlagById('bookmark');
$is_flagged = (bool) $this->flagService->getEntityFlaggings($flag, $node, \Drupal::currentUser() );
$path = 'flag/'. ($is_flagged ? 'un' : '') .'flag/bookmark/' . $node->id();
$token = $this->csrfService->get($path);
$flag_link = $flag->getLinkTypePlugin()->getAsFlagLink($flag, $node);
$flag_link['#attributes']['href'] = '/' . $path . '?destination&token=' . $token;
/**
* Render the link into HTML
*/
return \Drupal::service('renderer')->render($flag_link);
});
/**
* This is required to bubble metadata
*/
if (!$render_context->isEmpty()) {
$bubbleable_metadata = $render_context->pop();
\Drupal\Core\Render\BubbleableMetadata::createFromObject($fl)
->merge($bubbleable_metadata);
}
/*
* !!!!! FIX ENDS HERE !!!!!
*/
$obj->flag_link = $fl;
return new ResourceResponse((array)$obj, 200);
}
}
Anyone who can get module maintainers to address this would be nice.
In my laravel project, i have a forget password system, when i click on forget password and and enter email id , i will recieve password reset link with token on email. But when i clicked on that link its going to 404 page. I have attached sample link which i recieved on email ( https://directory.lifeloveandotherthings.com/public/user/password/reset/1e15c30fcb769f14182cb407861b685bc31a8eb42121b6394049d979beda0753 ).
Following is my codes in routes (web.php)
Route::get('user/password/reset', 'User\UserAuth\ForgotPasswordController#showLinkRequestForm')->name('password.reset');
Route::post('user/password/email', 'User\UserAuth\ForgotPasswordController#sendResetLinkEmail')->name('password.reequest');
Route::post('user/password/reset', 'User\UserAuth\ResetPassswordController#reset')->name('password.email');
Route::get('/password/reset/{token}', 'User\UserAuth\ResetPasswordController#showResetForm');
Following is my code in ResetpasswordController.php
<?php
namespace App\Http\Controllers\User\UserAuth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Password;
use Illuminate\Http\Request;
use JsValidator;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after login / registration.
*
* #var string
*/
public $redirectTo = '/user/home';
protected $validationRules = [
'name' => 'required|max:255',
'email' => 'required|email|max:255',
'password' => 'required|min:6|confirmed',
];
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
// $this->middleware('user.guest');
}
/**
* Display the password reset view for the given token.
*
* If no token is present, display the link request form.
*
* #param \Illuminate\Http\Request $request
* #param string|null $token
* #return \Illuminate\Http\Response
*/
public function showResetForm(Request $request, $token = null)
{
$validator = JsValidator::make($this->validationRules,[],[],'#resetform');
return view('user.auth.passwords.reset')->with(
['token' => $token, 'email' => $request->email, 'validator' => $validator]
);
}
/**
* Get the broker to be used during password reset.
*
* #return \Illuminate\Contracts\Auth\PasswordBroker
*/
public function broker()
{
return Password::broker('users');
}
/**
* Get the guard to be used during password reset.
*
* #return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard('user');
}
}
In this resetpassword link controller i have just checked wether the calling is coming to showResetForm
Function by echo "hello" in that function, but still its returing 404 not found.
What is the problem here
Something I have run into with password resets is if you are still logged into your system it tries to hit the /home route. You might not have this route anymore and gives you
You must have slashes or dots in the generated token and Laravel is interpreting your token parameter as a route. Append this regex [\w\s\-_\/\.\$]+ to your Password Reset Controller route and it will work again.
This is what I do to fix the problem
Route::get( '/user/reset/password/{token?}', 'CustomResetPasswordController#reset' )->where('token', '[\w\s\-_\/\.\$]+');
I have try to create a Custom REST POST plugin in my Drupal 8.3.2 for get an external JSON and then create an article from that.
I have follow that guide: How to create Custom Rest Resources for POST methods in Drupal 8
And this is my code:
<?php
namespace Drupal\import_json_test\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\node\Entity\Node;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
/**
* Provides a resource to get view modes by entity and bundle.
*
* #RestResource(
* id = "tio_rest_json_source",
* label = #Translation("Tio rest json source"),
* serialization_class = "Drupal\node\Entity\Node",
* uri_paths = {
* "canonical" = "/api/custom/",
* "https://www.drupal.org/link-relations/create" = "/api/custom"
* }
* )
*/
class TioRestJsonSource extends ResourceBase {
/**
* A current user instance.
*
* #var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* Constructs a new TioRestJsonSource object.
*
* #param array $configuration
* A configuration array containing information about the plugin
instance.
* #param string $plugin_id
* The plugin_id for the plugin instance.
* #param mixed $plugin_definition
* The plugin implementation definition.
* #param array $serializer_formats
* The available serialization formats.
* #param \Psr\Log\LoggerInterface $logger
* A logger instance.
* #param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user) {
parent::__construct($configuration, $plugin_id,
$plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
}
/**
* {#inheritdoc}
*/
public static function create(ContainerInterface $container, array
$configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('import_json_test'),
$container->get('current_user')
);
}
/**
* Responds to POST requests.
*
* Returns a list of bundles for specified entity.
*
* #param $data
*
* #param $node_type
*
* #return \Drupal\rest\ResourceResponse
*
* #throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function post($node_type, $data) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
$node = Node::create(
array(
'type' => $node_type,
'title' => $data->title->value,
'body' => [
'summary' => '',
'value' => $data->body->value,
'format' => 'full_html',
],
)
);
$node->save();
return new ResourceResponse($node);
}
}
Now if i try to test this without passing a payload and modifing the return value in this way:
return new ResourceResponse(array('test'=>'OK'));
It's working!
But if i send a custom payload like this using my custom code above:
{
"title": [{
"value": "Test Article custom rest"
}],
"type": [{
"target_id": "article"
}],
"body": [{"value": "article test custom"}]
}
I recieve a 400 Error with: Symfony\Component\HttpKernel\Exception\BadRequestHttpException: The type link relation must be specified. in Drupal\rest\RequestHandler->handle() (line 103 of core/modules/rest/src/RequestHandler.php).
What's going Wrong?
Thx.
I have find a solution:
I have removed the annotation:
* serialization_class = "Drupal\node\Entity\Node",
Then i take care just for data in my post function:
/**
* Responds to POST requests.
*
* Returns a list of bundles for specified entity.
*
* #param $data
*
*
* #return \Drupal\rest\ResourceResponse
*
* #throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function post($data) {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
return new ResourceResponse(var_dump($data));
The important thing is, when you use postman for example, is to add an header with Content-Type -> application/json:
Instead of Content-Type -> application/hal+json
With this configuration i can post any type of JSON and then manage it as i prefer.
Bye!
I'm trying to setup single sign on for MediaWiki with ExtAuthDB extension. The purpose is to authenticate user from external user system automatically when user logins in the main website: www.mysite.com. Mediawiki is located on subdomain: www.wiki.mysite.com.
I have installed the extension as it said in the guide. All priviliges are correct. But it doesn't work.
ExtAuthDB.php is:
<?php
/**
* Authentication plugin interface. Instantiate a subclass of AuthPlugin
* and set $wgAuth to it to authenticate against some external tool.
*
* The default behavior is not to do anything, and use the local user
* database for all authentication. A subclass can require that all
* accounts authenticate externally, or use it only as a fallback; also
* you can transparently create internal wiki accounts the first time
* someone logs in who can be authenticated externally.
*
* This interface is a derivation of AuthJoomla and might change a bit before 1.4.0 final is done...
*
*/
$wgExtensionCredits['parserhook'][] = array (
'name' => 'ExtAuthDB',
'author' => 'Alessandra Bilardi',
'description' => 'Authenticate users about external MySQL database',
'url' => 'https://www.mediawiki.org/wiki/Extension:ExtAuthDB',
'version' => '0.1',
);
require_once ( "$IP/includes/AuthPlugin.php" );
class ExtAuthDB extends AuthPlugin
{
/**
* Add into LocalSettings.php the following code:
*
* MySQL Host Name.
* $wgExtAuthDB_MySQL_Host = '';
* MySQL Username.
* $wgExtAuthDB_MySQL_Username = '';
* MySQL Password.
* $wgExtAuthDB_MySQL_Password = '';
* MySQL Database Name.
* $wgExtAuthDB_MySQL_Database = '';
* MySQL Database Table of users data.
* $wgExtAuthDB_MySQL_Table = '';
* MySQL Database username column label.
* $wgExtAuthDB_MySQL_Login = '';
* MySQL Database login password column label
* $wgExtAuthDB_MySQL_Pswrd = '';
* MySQL Database email column label
* $wgExtAuthDB_MySQL_Email = '';
* MySQL Database user real name column label
* $wgExtAuthDB_MySQL_RealN = '';
* require_once("$IP/extensions/ExtAuthDB/ExtAuthDB.php");
* $wgAuth = new ExtAuthDB();
*
* #return Object Database
*/
private function connectToDB()
{
$db = & Database :: newFromParams(
$GLOBALS['wgExtAuthDB_MySQL_Host'],
$GLOBALS['wgExtAuthDB_MySQL_Username'],
$GLOBALS['wgExtAuthDB_MySQL_Password'],
$GLOBALS['wgExtAuthDB_MySQL_Database']);
$this->userTable = $GLOBALS['wgExtAuthDB_MySQL_Table'];
$this->userLogin = $GLOBALS['wgExtAuthDB_MySQL_Login'];
$this->userPswrd = $GLOBALS['wgExtAuthDB_MySQL_Pswrd'];//.$GLOBALS['$wgExtAuthDB_MySQL_Salt'];
$this->userEmail = $GLOBALS['wgExtAuthDB_MySQL_Email'];
$this->userRealN = $GLOBALS['wgExtAuthDB_MySQL_RealN'];
wfDebug("ExtAuthDB::connectToDB() : DB failed to open\n");
return $db;
}
/**
* Check whether there exists a user account with the given name.
* The name will be normalized to MediaWiki's requirements, so
* you might need to munge it (for instance, for lowercase initial
* letters).
*
* #param $username String: username.
* #return bool
* #public
*/
function userExists( $username ) {
# Override this!
return true;
}
/**
* Check if a username+password pair is a valid login.
* The name will be normalized to MediaWiki's requirements, so
* you might need to munge it (for instance, for lowercase initial
* letters).
*
* #param $username String: username.
* #param $password String: user password.
* #return bool
* #public
*/
function authenticate( $username, $password )
{
$db = $this->connectToDB();
$hash_password = $db->selectRow($this->userTable,array ($this->userPswrd), array ($this->userLogin => $username ), __METHOD__ );
if ($password == $hash_password->{$this->userPswrd}) {
return true;
}
return false;
}
/**
* Set the domain this plugin is supposed to use when authenticating.
*
* #param $domain String: authentication domain.
* #public
*/
function setDomain( $domain ) {
$this->domain = $domain;
}
/**
* Check to see if the specific domain is a valid domain.
*
* #param $domain String: authentication domain.
* #return bool
* #public
*/
function validDomain( $domain ) {
# Override this!
return true;
}
/**
* When a user logs in, optionally fill in preferences and such.
* For instance, you might pull the email address or real name from the
* external user database.
*
* The User object is passed by reference so it can be modified; don't
* forget the & on your function declaration.
*
* #param User $user
* #public
*/
function updateUser( &$user )
{
$db = $this->connectToDB();
$euser = $db->selectRow($this->userTable,array ( '*' ), array ($this->userLogin => $user->mName ), __METHOD__ );
$user->setRealName($euser->{$this->userRealN});
$user->setEmail($euser->{$this->userEmail});
$user->mEmailAuthenticated = wfTimestampNow();
$user->saveSettings();
//exit;
# Override this and do something
return true;
}
function disallowPrefsEditByUser() {
return array (
'wpRealName' => true,
'wpUserEmail' => true,
'wpNick' => true
);
}
/**
* Return true if the wiki should create a new local account automatically
* when asked to login a user who doesn't exist locally but does in the
* external auth database.
*
* If you don't automatically create accounts, you must still create
* accounts in some way. It's not possible to authenticate without
* a local account.
*
* This is just a question, and shouldn't perform any actions.
*
* #return bool
* #public
*/
function autoCreate() {
return true;
}
/**
* Can users change their passwords?
*
* #return bool
*/
function allowPasswordChange() {
return false;
}
/**
* Set the given password in the authentication database.
* As a special case, the password may be set to null to request
* locking the password to an unusable value, with the expectation
* that it will be set later through a mail reset or other method.
*
* Return true if successful.
*
* #param $user User object.
* #param $password String: password.
* #return bool
* #public
*/
function setPassword( $user, $password ) {
return true;
}
/**
* Update user information in the external authentication database.
* Return true if successful.
*
* #param $user User object.
* #return bool
* #public
*/
function updateExternalDB( $user ) {
$db = $this->connectToDB();
$euser = $db->selectRow($this->userTable,array ( '*' ), array ($this->userLogin => $user->mName ), __METHOD__ );
$user->setRealName($euser->{$this->userRealN});
$user->setEmail($euser->{$this->userEmail});
$user->mEmailAuthenticated = wfTimestampNow();
$user->saveSettings();
return true;
}
/**
* Check to see if external accounts can be created.
* Return true if external accounts can be created.
* #return bool
* #public
*/
function canCreateAccounts() {
return false;
}
/**
* Add a user to the external authentication database.
* Return true if successful.
*
* #param User $user - only the name should be assumed valid at this point
* #param string $password
* #param string $email
* #param string $realname
* #return bool
* #public
*/
function addUser( $user, $password, $email='', $realname='' ) {
return false;
}
/**
* Return true to prevent logins that don't authenticate here from being
* checked against the local database's password fields.
*
* This is just a question, and shouldn't perform any actions.
*
* #return bool
* #public
*/
function strict() {
return true;
}
/**
* When creating a user account, optionally fill in preferences and such.
* For instance, you might pull the email address or real name from the
* external user database.
*
* The User object is passed by reference so it can be modified; don't
* forget the & on your function declaration.
*
* #param $user User object.
* #param $autocreate bool True if user is being autocreated on login
* #public
*/
function initUser( $user, $autocreate=false ) {
# Override this to do something.
}
/**
* If you want to munge the case of an account name before the final
* check, now is your chance.
*/
function getCanonicalName( $username ) {
return $username;
}
}
And in LocalSettings.php, I should add this code:
// add ExtAuthDB
// MySQL Host Name.
$wgExtAuthDB_MySQL_Host = 'localhost';
// MySQL Username.
$wgExtAuthDB_MySQL_Username = 'dbuser';
// MySQL Password.
$wgExtAuthDB_MySQL_Password = 'dbpassword';
// MySQL Database Name.
$wgExtAuthDB_MySQL_Database = 'base';
// MySQL Database Table of users data.
$wgExtAuthDB_MySQL_Table = 'members';
// MySQL Database username column label.
$wgExtAuthDB_MySQL_Login = 'username';
// MySQL Database login password column label
$wgExtAuthDB_MySQL_Pswrd = 'password';
$wgExtAuthDB_MySQL_Salt='salt';
// MySQL Database email column label
$wgExtAuthDB_MySQL_Email = 'email';
// MySQL Database user real name column label
$wgExtAuthDB_MySQL_RealN = 'real_name';
require_once("$IP/extensions/ExtAuthDB/ExtAuthDB.php");
$wgAuth = new ExtAuthDB();
Sorry, I had to copy full script, because I don't know where is the exact fault. And my question is: Why doesn't it work? Where is the mistake?
EDIT:
My external user table consists of id, username, password, salt, email, real_name. I thought it could be because of seperate password and salt fields, so I tried to implement salt in ExtAuthDB.php file manually. Unfortunately, it didn't work either. Then I commented this line.
I was able to setup SSO (Single sign-on) from WordPress to media wiki using OAuth 2.0 server, I have posted my solution on this post
Or you can follow these steps:
First you need an OAuth 2.0 server, you could implement it your self see details here Run your own OAuth 2.0 Server or the easiest way is to use the WordPress plugin WP Oauth 2.0 server you don't have to buy the pro, you can also implement SSO by using the Grant type Authorization codes which comes free.
You need OAuth 2.0 client extension installed on your media wiki, the extension can be found here, follow the installation instructions there.
Go to WordPress plugin page and activate OAuth server, then navigate to OAuth Server and add a new client, give your client a name and in Redirect URI add the link mention on the media wiki extension page i.e http://your.wiki.domain/path/to/wiki/Special:OAuth2Client/callback, then go to OAuth>clients page where you can see your newly created client, click edit and here you can see clientID and Client secret add this ID and secret in the localSettings.php of your media wiki.
Create a page on WordPress and put the following button with your client id in it
< a href="https://your-Domain-Where-OAuth-server-is-running.de/oauth/authorize?response_type=code&client_id=YOURCLIENTID&state=RANDOM-STRING&scope=basic">
go to wiki</a>
don't forget to put scope otherwise you will get a media wiki internal error.
If everything worked fine then you should automatically go to the media wiki main page after clicking this button from your WordPress. media wiki will show you as logged in. It took me some time to figure it out I hope this helps anyone who comes here.
You need to run the MediaWiki update script for this extension.
Many extensions need an update with update.php script!
From the browser
If you do not have access to the command line of your server, then use the web updater to run the update script.
From the command line
From the command line, or an SSH shell or similar:
Change to the maintenance directory!
Run the update script with php update.php command!
in node.js i will create mongodb session like this.
app.configure(function()
{
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({
secret: 'MY SECRET',
store: new MongoStore({
db: 'MY SESSION DB',
host: 'localhost',
port:88888
})
}));
app.use(everyauth.middleware());
app.use(express.methodOverride());
app.use(app.router);
});
how to create session with mongodb in php.i am new one for php..i want to create session with mongodb in php(webserver: apache),so let me know how to create
You must use a session handler to accomplish this. Normally we don't answer these sort of questions which lack research of any kind but, this one time, here is a small, extremely simple, self contained edition I have:
class Session{
public $db;
/**
* This decides the lifetime (in seconds) of the session
*
* #access private
* #var int
*/
public $life_time='+2 weeks';
/**
* This stores the found session collection so that we don't
* waste resources by constantly going back for it
*
* #access private
* #var sessions
*/
private $_session = array();
/**
* Constructor
*/
function open() {
// Ensure index on Session ID
$this->db->sessions->ensureIndex(array('session_id' => 1), array("unique" => true));
// Register this object as the session handler
session_set_save_handler(
array( $this, "openSession" ),
array( $this, "closeSession" ),
array( $this, "readSession" ),
array( $this, "writeSession"),
array( $this, "destroySession"),
array( $this, "gcSession" )
);
session_start(); // Start the damn session
}
/**
* Open session
*
* This function opens a session from a save path.
* The save path can be changed the method of opening also can
* but we do not change that we just do the basics and return
*
* #param string $save_path
* #param string $session_name
*/
function openSession( $save_path, $session_name ) {
global $sess_save_path;
$sess_save_path = $save_path;
// Don't need to do anything. Just return TRUE.
return true;
}
/**
* This function closes the session (end of session)
*/
function closeSession() {
// Return true to indicate session closed
return true;
}
/**
* This is the read function that is called when we open a session.
* This function attempts to find a session from the Db. If it cannot then
* the session class variable will remain null.
*
* #param string $id
*/
function readSession( $id ) {
// Set empty result
$data = '';
// Fetch session data from the selected database
$time = time();
$this->_sessions = $this->db->sessions->findOne(array("session_id"=>$id));
if (!empty($this->_sessions)) {
$data = $this->_sessions['session_data'];
}
return $data;
}
/**
* This is the write function. It is called when the session closes and
* writes all new data to the Db. It will do two actions depending on whether or not
* a session already exists. If the session does exist it will just update the session
* otherwise it will insert a new session.
*
* #param string $id
* #param mixed $data
*
* #todo Need to make this function aware of other users since php sessions are not always unique maybe delete all old sessions.
*/
function writeSession( $id, $data ) {
//Write details to session table
$time = strtotime('+2 weeks');
// If the user is logged in record their uid
$uid = $_SESSION['logged'] ? $_SESSION['uid'] : 0;
$fields = array(
"session_id"=>$id,
"user_id"=>$uid,
"session_data"=>$data,
"expires"=>$time,
"active"=>1
);
$fg = $this->db->sessions->update(array("session_id"=>$id), array('$set'=>$fields), array("upsert"=>true));
// DONE
return true;
}
/**
* This function is called when a user calls session_destroy(). It
* kills the session and removes it.
*
* #param string $id
*/
function destroySession( $id ) {
// Remove from Db
$this->db->sessions->remove(array("session_id" => $id), true);
return true;
}
/**
* This function GCs (Garbage Collection) all old and out of date sessions
* which still exist in the Db. It will remove by comparing the current to the time of
* expiring on the session record.
*
* #todo Make a cronjob to delete all sessions after about a day old and are still inactive
*/
function gcSession() {
$this->db->sessions->remove(array('expires' => array('$lt' => strtotime($this->life_time))));
return true;
}
}
Which can be called like so:
$session = new Session;
$session->db=$mongo->my_db;
$session->open();
It is a very basic example of how to do this.
Afterwards you can just use it like a normal session like so:
$_SESSION['user_id'] = $id;