Laravel Cashier - How to execute a function once when subscription is over? - php

I'm using Cashier on my laravel application. It has a simple way of verifying if the user is subscribed:
$user->subscribed();
Cashier stores on the users table a field "stripe_active" to check if the user has an active subscription. Now, I'm trying to do something kinda simple, but didn't find in the documentation.
When the user subscription expires, I want to run a function that will disable some stuff on the user account and save it to the database. I don't want to check and run it at every login , I want it to fire only once, when the account expires.
So I looked into Cashier's StripeGateway file, which has this function :
public function cancel($atPeriodEnd = true)
{
$customer = $this->getStripeCustomer();
if ($customer->subscription) {
if ($atPeriodEnd) {
$this->billable->setSubscriptionEndDate(
Carbon::createFromTimestamp($this->getSubscriptionEndTimestamp($customer))
);
}
$customer->cancelSubscription(['at_period_end' => $atPeriodEnd]);
}
if ($atPeriodEnd) {
$this->billable->setStripeIsActive(false)->saveBillableInstance();
} else {
$this->billable->setSubscriptionEndDate(Carbon::now());
$this->billable->deactivateStripe()->saveBillableInstance();
}
}
Now it appears that when the account is canceled, two functions run - cancelSubscription and deactivateStripe. I didn't find a documented way to run something on account expire, so I figured I might have to extend these methods and run it myself, but I'm a bit lost on how to do it. Can someone help out?

Related

How can I properly authenticate a user as an admin in Laravel?

I am attempting to introduce "ghosting" into my application - wherein I can access our app from the POV of a user.
Currently using the loginUsingID function to achieve this, with a protected route only accessible by admins. However, I would also like to display to the admin that they are ghosting a user by displaying a bar across the top of our app.
I was thinking of adding a property to the user is_being_ghosted - setting it as false on logout, false on login, and true on ghostLogin.
But I realize there is a small chance an admin attempts to ghost a user, and it sets that property, and while they are investigating things within the account, the user themselves refreshes their page (they were already authenticated so do not need to login again). In that case they would see this "admin bar" across the top, which clearly I wouldn't want to happen.
Is there an efficient way to achieve what I'm trying to do here? Am I going about this the wrong way?
As jszobody has mentioned. You could rather manage the state inside the session. You secure the /ghost route and then if the original-user-id session is set you display your bar and an unghost link.
public function ghost(Request $request, $id)
{
$request->session()->put('original-user-id', Auth::user()->id);
Auth::loginUsingId($id);
return redirect('/');
}
public function unghost(Request $request)
{
if ($request->session()->has('original-user-id')) {
Auth::loginUsingId($request->session()->pull('original-user-id'));
}
return redirect('/');
}
Update:
The ghost endpoint basically accepts the id that you want to impersonate, typically found through an ajax search input or something similar. Whatever suites your use case.

Laravel 5.1 auth logs out after refresh

I'm working with Laravel for the first time.
My auth user logs out automatically after i go to another route or if i refresh the page, and i dont understand why, please help me.
This is my log in code:
public function ini_ses(Request $datos)
{
//Inicia sesion
Session::put('ses_correo', Input::get('email'));
$correo = $datos->input('email');
$password= $datos->input('password');
if(Auth::attempt(['correo_elec'=>$correo, 'password'=>$password]))
{
$_session['correo']=$correo;
$_session['contra']=$password;
if(Auth::user()->tipo==0)
{
return view('cliente');
}
elseif(Auth::user()->tipo==1)
{
return view('veterinario');
}
elseif(Auth::user()->tipo==2)
{
echo("Admin");
}
}
else
{
var_dump($correo, $password);
}
}
If you know how to fix it, i aprecciate your help.
UPDATE: Another possibility
Laravel 4 Auth works but does not stay logged in
Remove all, but the redirects. Apparently this may mess up the authentication process.
The Auth::attempt() should trigger the necessary things to keep the user logged in, a small yet simple possibility could be the remember me function. Although it shouldn't be that, it would be worth a try.
Add true as a second parameter to the function.
if(Auth::attempt(['correo_elec'=>$correo, 'password'=>$password], true))
Assuming your Users table has the default laravel structure (with a remember token column)

Symfony 2 stop saving form process

I am trying to link my local users stored in the database with some external services, so they can login anywhere with the same credentials.
I have an EventListener waiting for some FOSUserEvents like FOSUserEvents::REGISTRATION_SUCCESS or FOSUserEvents::CHANGE_PASSWORD_SUCCESS, fired when the data are valid but not actually saved, to perform some call to the various external services and replicate the new user credentials.
If the services return a message saying that the data are replicated, everything work fine.
But if a service say that there is a problem, no mater what it is, I would like to interrupt the saving process of the form and adding an error message.
The objective is to prevent Symfony to save the data, even if they are valid, if an external service say no, and I don't know how to perform this kind of emergency stop.
Actually, it's only based on FOSUserBundle but if I find a working solution, I will have to execute something similar for other entities, that why I try to be as generic as possible.
Here a some of my code
class MyListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'createUser',
FOSUserEvents::CHANGE_PASSWORD_SUCCESS => 'editUser'
);
}
public function createUser(FormEvent $event)
{
$user = $event->getForm()->getData();
// Check if the user exists before trying to edit
$result = $this->_userExists($user);
if($result['value'] == false)
{
// Create the user
$result = $this->_createUser($user);
// Check if the user is successfully replicated
if($result['result'] != 'success')
{
/*
* Emergency stop (user not replicated)
*/
}
}else{
/*
* Emergency stop (user doesn't exists)
*/
}
}
. . .
}
Actually I didn't find any way to stop the saving workflow and returning to the form page to display an error message. So if somebody has an idea of how to perform this, feel free so write your idea, and thanks you all guys. Stackoverflow is really the best ;-)

automatically login user if they are guest with Yii

I've been handed off some code that for legacy reasons must keep using the Yii framework. Though when a user comes to a certain page as a guest I need the page to automatically log them in as a certain user. After browsing both the Yii documentation and here I have not found any solutions to this problem. Is what I am trying to do possible with Yii?
I would use Behaviors to do this, probably onBegnRequest. This will fire before every request is handled, and automatically log a user in if they're currently a guest
<?php
class BeginRequest extends CBehavior
{
public function attach($owner)
{
$owner->attachEventHandler('onBeginRequest', array($this, 'handleBeginRequest'));
}
public function handleBeginRequest($event)
{
if(Yii::app()->user->isGuest())
{
$identity = new UserIdentity('known-user', 'known-password');
// authenticate identity or not, up to you if you know which user should be logged in
Yii::app()->user->login($identity);
}
}

CakePHP redirect on login depending on username

I have a CakePHP 1.3 application that has a login system, which works well. It uses a DB with a users table, which existed before creating this app.
I'm using Auth in my AppController. The login function looks like
function login() {}
and it's located in the users_controller.
Everything works fine, as I said, but I have problems trying to add a new functionality. I would like to, during the login process, detect if a user has introduced a specific combination of login/password (let's say admin/adminpwd). If so, the login should be succesful AND he would be taken to an admin area (/admin/index). Otherwise, the login process should work as usual.
Once in this admin area (controlled by an admin_controller), this user should be able to perform some actions exclusive to him, no to the rest of users (even if they type on the browser /admin/action).
I've read about ACL, and probably it would help with this, but it seems too complicated for what I really need. Is there any simple way to do this? I guess I should modify the login function, but I don't really know how exactly, and if there's anything else I should change... any ideas?
Yeah, ACL is pretty complicated (and powerful). But in your case, I'd suggest create a 'group' field in users table to distinguish the role of the user. So you can have more admins later if you want. It's more flexible than hard-code a certain login credential in your users_controller.
There are several things you need to do to:
Tell the Auth component to transfer control to you after the user logins, so you can determine their group and redirect them accordingly.
Check if a user in a group is accessing some other group's action: If you don't, a regular user just need to be logged in, and they can type in admin url (if they know about it) and they can do everything an admin can. This check will probably be done in before_something_() in app_controller or tap into Auth somewhere.
I don't remember all the details, but you can get everything you need in the Cake Cookbook. Good luck!
Let's just see some code...
class UsersController extends AppController {
// we're moving the variable to AppController!
public function login() {
$usrInfo = $this->Auth->user();
if (isset($usrInfo) {
// this index name might not be right. I'm going off memory please check this!
if (in_array($usrInfo['username'], $this->adminUsers)) {
// do your code here for admin users.
// could be a redirect or just changing the layout used
} else {
// is a user that is logged in but not in our admin list
}
}
}
To test if the user is logged in you would need to do something like the following:
class AppController extends Controller {
protected $adminUsers = array('joe_blow_uname', 'jane_blow_uname');
public function beforeFilter() {
$routing = Configure::read('Routing.admin');
$usrInfo = $this->Auth->user();
if (isset($this->params[$routing]) && isset($usrInfo)) {
if (!in_array($usrInfo['username'], $this->adminUsers)) {
// do code here for non-admin users using /admin prefix
}
}
}
}
Let me know if this doesn't help.
Or worse breaks something...
Edit:
This is really not the best way to do this obviously. ACL or setting up some kind of group in your database would probably be better. BUT, it is a relatively quick-n-dirty way that, for a small site, should work fine.

Categories