I am building a paid subscription site using Drupal. After searching through the Drupal modules I have not been able to find anything that will allow me to create a new Drupal account once the user has visited my landing page, decided they want to subscribe, and provided their valid credit card information. I would like to redirect them to the subscription site with a newly created account once their credit card info has been validated.
Is anyone familiar with a module or a methodology for remotely creating a user account with Drupal? OpenID is a possibility but I would like to give the user a little more freedom in selecting their username.
Why not extend Drupal's registration form with some extra fields and validation functions?
You could have a hook, function, or build an xml-rpc interface to a function that created a new user account after the user has entered their details.
For example, on the form that they fill out, you could have in the _submit of the form:
formname_sumbit($form, &$form_state) {
// Do form stuff here
// Now do user_save stuff
$password = user_password();
$mail = $form_state['values']['email_address'];
// Use blank account object as we are creating a new account
$account = array();
$properties = array('name' => 'someusername', 'pass' => $password, 'mail' => $mail, $roles => array('authenticated user', 'some other role'));
$this_user = user_save($account, $properties);
}
That should take care of creating the user. I'm not sure about how to login them automatically, but a global $user; $user = $this_user; might work. The user should be notified of their new account via email by the user_save function, but you might want to let them know with a drupal_set_message as well.
http://api.drupal.org/api/function/user_save/6
Related
I have a Laravel 8 project. Users are applying to be a creator from another web project, and we approve these applications from the project I am currently having problems with. In other words, the project we are talking about is an admin panel. Let me tell you what I want to do now. We approve the applications coming here with the create button in the admin panel and create the creator. However, this creator does not currently occur on Firebase. I also want this creator to be rendered in Firebase as well. I did some research and found something like Firebase Admin SDK for PHP. As far as I understand, I can perform this operation with the help of this SDK.
Then I went and wrote my codes to the create function inside the CreatorController, where the content of this Create Button is written. Here is my code that I wrote.
CreatorController.php-create function
public function create(Request $request){
$application = null;
$subscriber = null;
if($request->application_id!=null){
$application = CreatorApplicationForm::findorfail($request->application_id);
$subscriber = User::where([['email','=',$application->email],['role_id','=',4]])->get()->first();
}
return view('admin.creators.create',['application' => $application,'subscriber' => $subscriber]);
if(isset($_POST['create-btn'])){
$displayName = $_POST['name'];
$email = $_POST['email'];
$userProperties = [
'displayName' => $displayName,
'email' => $email,
];
$createdUser = $auth->createUser($userProperties);
}
}
I wrote the last if block in the function, the previous ones were already written.
Later, when I showed this to a friend, he said it wouldn't work for me. He said you wrote it in classical PHP form and told me to adapt it to Laravel. Also, I guess I need to sync the newly created user to the subscribers in the first if block.
Frankly, I'm a little confused. How can I solve this problem?
Let's say I have an invoice entity. Invoice belongs to some user (invoices.user_id).
If the user enters myapp.com/invoices/1 he needs to sign in to gain access to his invoice. That's pretty normal.
Sometimes invoices.user_id is null (invoice owner doesn't have an account in our system), but we have an invoices.phone_number column.
The goal is to create an authentication system based on SMS code verification for users that don't have the account in our system. If the user confirms that he indeed owns phone number related to the invoice (code verification) I want to grant him temporary access (15 min) to this invoice details page (and only this page).
My first idea was to use a JWT token stored in the session.
My second idea was to use a custom firewall.
Is there any better approach?
Create a kernel.request listener. This way you can act, before anything is executed, and whole application is oblivious to the fact that the user can be logged out any minute.
Call a "service" which will validate the token. If the token is not valid, clear authentication status and override the request. For instance, redirect the user to a "you need to pay again" page.
This way you don't need to modify any code, execute any voters and so on, your whole application can be protected.
As for the authentication itself, go for a custom guard, where you can fully control how the authentication process will work.
You can authenticate a dummy user for 15 minutes using the following action:
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
/**
* confirm that the user indeed owns
* phone number related to the invoice (code verification)
*/
//create a user for this task only and fetch it
$user = $em->getRepository(User::class)->find(1);
//firewall name used for authentication in security.yml
$firewall = "main_secured_area";
$token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
$this->get('security.token_storage')->setToken($token);
$this->get('session')->set("_security_$firewall", serialize($token));
//$lifetime takes number of seconds to define session timeout 15min = 900sec
$this->container->get('session')->migrate($destroy = false, $lifetime = 900);
//fire the login event manually
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);
return $this->render('default/index.html.twig');
}
I am trying to create a user through web services in Moodle by using PHP and I am using ws function: core_user_create_users. but it gives me an error.
{"exception":"webservice_access_exception","errorcode":"accessexception","message":"Access control exception"}
i am using moodle ver3.4.
Can you tell me how to add capabilities to the current token with respect to the user if its problem of web service function? if its other problem please tell me.
Thanks,
I will give a full answer on how to do this. First, we will start by creating a role for web services (it's not necessary, but I love to do it this way to keep the instance clean for administrators).
But first, there is a quick solution to your problem. Add the authorized user to the list of administrators of your website and you are free to call any function with the generated token.
I. Create a new role for web services
You can do that by going to Site administration > Users > Permissions > Define roles. You will find a button to add a new role Add a new role. After you click on that button, you will get a form where you can use defined (or default) roles or archetype to define your new role. You can also create your role using an exported file from another Moodle instance. Anyway, we will choose Continue to define our custom role. Now, we can fill the necessary information like (short name, custom full name, custom description).In the context part, choose System to assign this role from everywhere in the system.
Now scroll down all the way to the capabilities. Search in the Filter search box your capabilities (in our case creating users). You can see the needed capabilities when you create the web service and add the function to it. Each function needs a user with specific capabilities to execute.
You can find function capabilities either from admin dashboard by going to Site administration > Plugins > Web services > External services and create a new external service and add your function and you will see the list of capabilities int he Required capabilities column of your service table. Just type core_user_create_users in the functions drop-down list. Click on Add functions button and now you can see the Required capabilities. In this case, it's only moodle/user:create. So we can use this in our role by checking allow checkbox next to each capability we want.
After you finish your role configuration, click on Create this role.
II. Assign a user to the new role
Now we can assign our user to the new role.
Go to Site administrator > Users > Permissions > Assign system roles.
Choose our new role.
Add the user to the list of existing users.
III. Add user to authorized users
This is only required if you checked the Only authorized users option when you created your external service.
Go to Site administrator > Plugins > Web services > External services.
Click on Authorized users link on your web service.
Add the user to the list of Authorized users.
Check the warning under the form. If your user doesn't have some capabilities, Moodle will signal that as a warning under the form. You can fix that by adding the missing capabilities to the role that we created earlier.
IV. Create a token
Now we can go to the token manager and generate a new token to our user for our external web service.
BS: Don't forget to enable web services first. Enable REST protocol or whatever protocol you are willing to use.
Update: How to call the function?
Following the details requested in the comments of this answer, I will provide an example on how to call these web services functions (in this example create_users).
In this example, we will use cURL class provided by the core team of Moodle to make things easier for us. You can find this class in the repository of their web service client example here. I will be using the curl.php file in the PHP-REST folder in this repository. All the PHP folder in this repositories have the same curl.php file. The client.php file is the only difference.
$token = 'replace it with your web service token';
$domainname = 'http://your_moodle_domain.ltd';
$functionname = 'core_user_create_users';
$restformat = 'json';
$user = array(
"username" => "username of your new user", // must be unique.
"password" => "password must respect moodle policies",
"firstname" => "first name",
"lastname" => "last name",
"email" => "your_user#email.com",
"auth" => 'authentication method can be email, manual, registred ..',
"customfields" => array ( // If you have custom fields in your system.
array(
"type" => "birthdate",
"value" => strtotime("01/01/1990")
),
array(
"type" => "something_else",
"value" => "0"
)
)
);
$users = array($user); // must be wrapped in an array because it's plural.
$param = array("users" => $users); // the paramater to send
$serverurl = $domainname . '/webservice/rest/server.php'. '?wstoken=' .
$token . '&wsfunction='.$functionname;
require_once('curl.php'); // You can put it in the top.
$curl = new curl;
$restformat = ($restformat == 'json')?'&moodlewsrestformat=' .
$restformat:'';
$resp = $curl->post($serverurl . $restformat, $param);
I have a system, that has 2 roles (admins and users). Authentication made using Security Symfony2 component. Admin doesn't know user password. But he should be able to login into the system as user. I have a grid with all users and want to add buttons like "Login as this user". How can I make it?
I have tried, but no prfit:
$userRepo = $this->getDoctrine()->getRepository('FrameFoxBackEndBundle:User');
$this->get('security.context')->getToken()->setUser($userRepo->find(1));
Why not use built-in switch user option?
I use this code :
// use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken
$entity = $userRepo->find(1);
// Authentication
// create the authentication token
$token = new UsernamePasswordToken(
$entity,
null,
'user_db',
$entity->getRoles());
// give it to the security context
$this->container->get('security.context')->setToken($token);
I would use Symfony core support for that manner.
Have a look at:
http://symfony.com/doc/current/cookbook/security/impersonating_user.html.
You define a role which is allowed to switch user, and a parameter in the url that allows you to switch the user.
I suppose I'm just looking for a bit of guidance as to how to set up my User + Authentication area on my website with cakephp 2.0.
I have a basic login and register functionality set up within my UserController.php, which also contains functions for looking up and displaying other users.
I also want to use the hybridauth plugin to allow for users to login/register using their social media / oauth account (allowing for more than one social account per user in the database, so that the same user could use either their twitter or facebook details, for example). I'm only having 3 providers at this time, so I plan to just create 6 columns in my user database, with the token and outhid in the same user row. This is in another controller - HybridauthController.php.
I have the hybridauth set up so that it creates its 'hybridauth' object from the account details, which is fine - but I want to be able to merge the whole 'authentication' together, so that my cakephp session contains the hybridauth session data (object) creating my general "current user" array that I can use, and set some generic variables within, depending on whether they are from oauth or not.
I don't currently store sessions in a database, and ideally I would like for allow persistent sessions for all, whether they use an oauth account or not. I don't really understand how persistent sessions are supposed to work with hybridauth, because how in this example would the $current_user_id be filled in when the user returns the next day? Not via a cookie, surely?
http://hybridauth.sourceforge.net/userguide/HybridAuth_Sessions.html
So in summary I'm looking for a simple solution to combine all of my 'session' / 'auth' / 'user' data into one simple array in the users session. Hopefully that all makes sense!
Thanks
Late to answer, but hopefully it'll help you or someone else searching.
I had a tough time integrating HybridAuth into a preexisting CakePHP (1.3) app that was already using Cake Sessions and the Auth component. I initially tried using the Cake example that I downloaded from the HybridAuth website, but that did not work for me.
Our preexisting User controller already had a bunch of logic in it including a beforeFilter method. That's where I inserted my session_start() as opposed to above the class declaration in the HybridAuth Cake example:
class UsersController extends AppController {
...
var $components = array('Session','Auth','Email');
...
public function beforeFilter(){
// following two lines may not be necessary for your setup
$this->Auth->allow('oauth', 'oauthLogout');
$excludeBeforeFilter = array('oauth', 'oauthLogout');
if ( ! in_array($this->action, $excludeBeforeFilter) ) {
// preexisting Auth logic -- I had to bypass it because
// calling `session_start` was messing up Cake's Auth
...
} else {
/* THIS IS NECCESSARY FOR HYBRIDAUTH (OAUTH) */
/* setting the session ID made it so users could NOT log
in from a 3rd party and our site */
session_id($_COOKIE['CAKEPHP']);
session_start();
}
}
...
public function oauth($provider){
$this->autoRender = false;
// include HybridAuth
require_once( WWW_ROOT . 'hybridauth/Hybrid/Auth.php' );
try {
// I stored my provider config in a Cake config file
// It's essentially a copy from the site/Cake example
$hybridAuth = new Hybrid_Auth(Configure::read('HAuth.config'));
$adapter = $hybridAuth->authenticate($provider);
$userProfile = $adapter->getUserProfile();
// method on the User model to find or create the 3rd party user
$user = $this->User->findOrCreate($userProfile, $provider);
if ( ! $user ) {
echo 'Unable to find/create user';
} else {
// configure your fields as necessary
$this->Auth->fields = array(...);
$this->Auth->login($user);
}
} catch (Exception $e) {
echo $e->getMessage();
}
}
}
At this point the 3rd party (HybridAuth) user is accessible in the Auth Component. This way a user was only logged in one 3rd party service or the preexisting login (but not both).
I also had an issue logging out. To do that I basically destroyed all sessions/cookies to be safe. In the oauthLogout method of the UsersController:
// probably overkill/paranoia
$this->Auth->logout();
$this->Session->destroy();
session_destroy($_COOKIE['CAKEPHP']);
/* these two seemed to make the difference
especially the 4th parameter */
setcookie( 'PHPSESSID', '', 1, '/' );
setcookie( 'CAKEPHP', '', 1, '/' );
Seems super hacky -- sorry for that. Hope it helps though!