So, I'm trying to implement Sentry 2 with Laravel 4.1. I'm using this resource for it
https://github.com/rydurham/L4withSentry
Everything works fine, but now I want to assign user to a group automatically when he registers.
From Sentry 2 Docs,
// Find the group using the group id
$adminGroup = Sentry::findGroupById(5);
// Assign the group to the user
$user->addGroup($adminGroup);
Should work. So I added this lines of code to
Authority\Repo\User\SentryUser.php
Now the code looks like
try {
//Attempt to register the user.
$user = $this->sentry->register(array(
'username' => e($data['username']),
'email' => e($data['email']),
'password' => e($data['password'])
));
// Find the group using the group id
$adminGroup = Sentry::findGroupById(5);
// Assign the group to the user
$user->addGroup($adminGroup);
//success!
$result['success'] = true;
$result['message'] = trans('users.created');
$result['mailData']['activationCode'] = $user->GetActivationCode();
$result['mailData']['userId'] = $user->getId();
$result['mailData']['email'] = e($data['email']);
}
But this throws in an error
Non-static method Cartalyst\Sentry\Sentry::findGroupById() should not be called statically, assuming $this from incompatible context
Can anyone shed a light and tell me what I'm doing wrong?
Thanks in Advance
Somehow, where you are using Sentry, you're not using its Facade, but the class itself. When you call a class through a Facade you're not really using statics, it's just looks like you are.
Do you have this:
use Cartalyst\Sentry\Sentry;
In your code?
Ok, but if this line is working for you:
$user = $this->sentry->register(array(
'username' => e($data['username']),
'email' => e($data['email']),
'password' => e($data['password'])
));
So you already have it instantiated and you can surely do:
$adminGroup = $this->sentry->findGroupById(5);
Related
I write test for Laravel app with codeception and modules Laravel5, REST.
One of api test:
public function testEmailRegistration(ApiTester $I) {
...
// Not correct data
$I->sendPOST($route, [
'first_name' => (string)$this->faker->randomNumber(),
'password' => $this->faker->password(1, 7),
'email' => 'not_valid_email',
]);
$I->seeResponseCodeIs(HttpCode::UNPROCESSABLE_ENTITY);
// Correct data
\Illuminate\Support\Facades\Queue::fake();
$I->sendPOST($route, [
'first_name' => $firstName,
'password' => $password,
'email' => $email,
]);
\Illuminate\Support\Facades\Queue::assertPushed(\App\Jobs\SendEmail::class);
...
}
I send requests on incorrect and correct data and make some assertions. In addition I check, that job is present in queue.
After execute test I give error:
[Error] Call to undefined method Illuminate\Queue\SyncQueue::assertPushed()
After Queue:fake facade \Illuminate\Support\Facades\Queue must resolves to QueueFake, but in fact is still QueueManager, thus assertPushed function is undefined.
Execution of $I->sendPOST() reset call Queue::fake. It happened in laravel 5 module \Codeception\Lib\Connector\Laravel5, method doRequest.
protected function doRequest($request)
{
if (!$this->firstRequest) {
$this->initialize($request);
}
$this->firstRequest = false;
$this->applyBindings();
$this->applyContextualBindings();
$this->applyInstances();
$this->applyApplicationHandlers();
$request = Request::createFromBase($request);
$response = $this->kernel->handle($request);
$this->app->make('Illuminate\Contracts\Http\Kernel')->terminate($request, $response);
return $response;
}
Each call of doRequest except the first init app again and some configurations as Queue::fake are cleared.
One of decision is one request per test. Is there another variant to work Queue::fake when in test make more then one request?
I am not sure why the Laravel module does this but I found a work-around that allows you to use fakes:
public function someTest(ApiTester $I): void
{
// what the SomeFacade::fake method call does is basically create
// a fake object and swaps it for the original implementation in
// the app container, so the we're recreating that behavior here
// only this will be persisted even after the request is issued:
$notification_fake = new NotificationFake();
// `haveInstance` is a method from Laravel Codeception Module
// which sets an object in the app container for you:
$I->haveInstance(ChannelManager::class, $notification_fake);
// making the request
$I->sendPUT('some url', $some_payload);
// assertions
$I->canSeeResponseCodeIs(Response::HTTP_OK);
$notification_fake->assertSentToTimes($expected_user, MyNotification::class, 1);
}
note that this test method is only for illustrative purposes and it misses so of the details, hence the undefined variables and such.
Also note that I user the notification fake which get registered at Illuminate\Notifications\ChannelManager, unlike most fakes that you can register under their aliased name e.g. queue. So you have to check what is being instantiated and how to swap it on your own. You can either find this in respective service providers for each service. Most of the time it's lowercase name of the facade.
I'm trying to manually login a frontend user (and do some other basic operations while I'm at it) in an ajaxAction and it doesn't seem to work as I intend. What I do when the loginform is submitted:
$loginData = array(
'username' => $username,
'uident_text' => $password,
'status' => 'login',
);
$GLOBALS['TSFE']->fe_user->checkPid = 0;
$info = $GLOBALS['TSFE']->fe_user->getAuthInfoArray();
$user = $GLOBALS['TSFE']->fe_user->fetchUserRecord($info['db_user'], $loginData['username']);
$GLOBALS['TSFE']->loginUser = 1;
$GLOBALS['TSFE']->fe_user->createUserSession($user);
$GLOBALS['TSFE']->fe_user->setAndSaveSessionData('user', TRUE);
return json_encode(['login' => 'true']);
when trying to print out $GLOBALS['TSFE']->fe_user before the return, the data are set and $GLOBALS['TSFE']->loginUser = 1 , so everything looks file. When I reload the login form afterwards though, the fe_user data are still there, but the fluid security.ifAuthenticated does not work.
The Form view looks like this:
<f:security.ifAuthenticated>
<f:then>
user is authenticated!
</f:then>
<f:else>
<f:render partial="LoginForm.html"/>
</f:else>
</f:security.ifAuthenticated>
Username: {user.firstName}
And it corretly outputs the Firstname of the logged in user, but also still shows the loginform. security.ifAuthenticated always enters the ELSE. And when I looked at the viewHelper it is because $GLOBALS['TSFE']->loginUser is not set.
Any hints/ideas as to why this is happening?
From what I experimented, you need to set a cookie for it to work.
$reflection = new \ReflectionClass($GLOBALS['TSFE']->fe_user);
$setSessionCookieMethod = $reflection->getMethod('setSessionCookie');
$setSessionCookieMethod->setAccessible(TRUE);
$setSessionCookieMethod->invoke($GLOBALS['TSFE']->fe_user);
If I played only with $GLOBALS['TSFE']->fe_users, it didn't work even if the fe_session was created in the database.
Turns out my inexperience with typo3 and the fe_login was at fault. What I did not know is that $GLOBALS['TSFE']->loginUser is an indicator of fe_groups. The problem was, that my frontend user was not assigned to a group, the column "usergroup" was empty in the database. Therefore Typo3 sets loginUser back to false and that's why ifAuthenticated does not work.
I wrote about the solution here, but basically the only thing I did was assign the user to a group and afterwards the login as I tried it worked fine.
I started a new project with Silex, it looks like a cool and fast Framework but I'm getting crazy with the SecurityServiceProvider trying to get the uid. I though it should be something like the getId() like Symfony but I got an error that the function doesn't exists.
PHP Fatal error: Call to undefined method Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage::getUser()
If I got the current logged user I have his information but not the Id.
$user = $app['user'];
print_r($user);
Symfony\Component\Security\Core\User\User Object (
[username:Symfony\Component\Security\Core\User\User:private] =>
myuser#mymail.com
[password:Symfony\Component\Security\Core\User\User:private] =>
5FZ2Z8QIkA7UTZ4BYkoC+GsReLf569mSKDsfods6LYQ8t+a8EW9oaircfMpmaLbPBh4FOBiiFyLfuZmTSUwzZg==
[enabled:Symfony\Component\Security\Core\User\User:private] => 1
[accountNonExpired:Symfony\Component\Security\Core\User\User:private]
=> 1 [credentialsNonExpired:Symfony\Component\Security\Core\User\User:private]
=> 1 [accountNonLocked:Symfony\Component\Security\Core\User\User:private]
=> 1 [roles:Symfony\Component\Security\Core\User\User:private] => Array ( [0] => ROLE_USER ) )
Any idea? Thanks in advance!
// Symfony 2.6+
$token = $app['security.token_storage']->getToken();
// Symfony 2.3/2.5
$token = $app['security']->getToken();
Get user info:
$user = $token->getUser();
Check $user
var_dump($user);
Ok got the solution, if anybody implements a new UserProvider, should to add the customs fields on the provider, and define them on User class in Symfony. Thanks anyway!
I'm developing a custom Moodle authentification plugin for Moodle 2.7.
When a user is authenticated I want them to be added to a specific cohort. If that cohort does not exist I need it to be created automatically. I use the user_authenticated_hook() function in my authentification plugin to achieve this.
My code for creating the cohort is this
$data = new stdClass();
$data->name = 'Name string';
$data->idnumber = 'ID string';
$data->description = 'Description string';
$cohortId = cohort_add_cohort($data);
I have included cohort/lib.php in the auth.php file and I have declared the global variables $DB, $CFG and $SESSION at the first line of the user_authenticated_hook() function.
The authentification works without the part about cohorts. But with the cohort part in place authentication fails and I am redirected to the login page.
The page title is changed to "Error" but that is the only error message I get.
What Am I doing wrong? I hope somebody will be able to help me create cohorts and add members.
It might be because the global $USER object doesn't exist yet or hasn't been populated.
Do you have debug switched on in your config.php?
$CFG->debug = 32767;
$CFG->debugdisplay = 1;
It might be better to respond to the user_created event. So if a user is created by another method, they will still be added to the cohort. eg:
Create a local plugin eg:
/local/add_cohorts
Create an events.php
/local/add_cohorts/db/events.php
Which has something like this
$handlers = array (
'user_created' => array (
'handlerfile' => '/local/add_cohorts/lib.php',
'handlerfunction' => 'local_add_cohorts_user_created',
'schedule' => 'instant',
'internal' => 1,
),
);
Then in /local/add_cohorts/lib.php have
function local_add_cohorts_user_created($user) {
// Do your cohort processing here and add the user
// Use $user->id to add to the cohort members
}
Then create a version.php and install the plugin, then the event handler will be registered.
Events api - https://docs.moodle.org/dev/Events_API
I am using Ion Auth for my codeigniter application and all seems good except for one thing.
I need to display a list of users along with the groups they are in. How can I retrieve the group id of a particular user without making my own models and querying for it.
$this->ion_auth->user($id)->row(); does not retrieve the group id.
Ion Auth has updated and removed the get_user function in the latest version. As a result of this, the below should return the current group id of the logged in user:
$this->ion_auth->get_users_groups()->row()->id
If you're wanting to get the group id of a particular user, you can pass the user id into the get_users_groups method.
get the Object:
$user_groups = $this->ion_auth->get_users_groups($user->id)->result();
Get the name of the group:
$this->ion_auth->get_users_groups($data['id'])->row()->name;
In my case:
$data['groups'] = $this->ion_auth->get_users_groups($data['id'])->row()
You can check the offcial doc about get users groups:
http://benedmunds.com/ion_auth/#get_users_groups
I came across this because I wanted to add a user's group_id(s) to the session upon successful login. In case anyone is interested, here's how I did it (once i managed to figure out where everything was being done).
In ion_auth_model.php, I took the set_session function:
public function set_session($user)
{
$this->trigger_events('pre_set_session');
$session_data = array(
'identity' => $user->{$this->identity_column},
'username' => $user->username,
'email' => $user->email,
'user_id' => $user->id, //everyone likes to overwrite id so we'll use user_id
'old_last_login' => $user->last_login
);
$this->session->set_userdata($session_data);
$this->trigger_events('post_set_session');
return TRUE;
}
and modified it to this:
public function set_session($user)
{
$this->trigger_events('pre_set_session');
$session_data = array(
'identity' => $user->{$this->identity_column},
'username' => $user->username,
'email' => $user->email,
'user_id' => $user->id, //everyone likes to overwrite id so we'll use user_id
'old_last_login' => $user->last_login
);
//get user group ids for user and pass to session
$groups = $this->ion_auth->get_users_groups($user->id)->result();
foreach ($groups as $row){
$session_data['groups'][] = $row->id;
}
$this->session->set_userdata($session_data);
$this->trigger_events('post_set_session');
return TRUE;
}
now it writes an array to the session called groups that is a list of all the groups the user belongs to.
The only other thing I had to do was to modify the logout function in Ion_auth.php (in application/libraries) to make sure the group session variable is unset by adding
$this->session->unset_userdata('groups');
to the list of other unset_userdata() statements.
I know I probably should have just extended the libraries/models to keep the core untouched, but you could take what I did and easily do that.
hope this helps someone.
Rob
Try adding this to ion_auth_model.php
(Or place the query somewhere else)
/**
* get_all_users_with_group
*
* #return array
**/
public function get_all_users_with_group()
{
$this->trigger_events('get_all_users_with_groups');
return $this->db->select(
$this->tables['users'].'.*, '.
$this->tables['users_groups'].'.'.$this->join['groups'].' as group_id, '.
$this->tables['groups'].'.name as group_name, '.
$this->tables['groups'].'.description as group_desc'
)
->join($this->tables['users_groups'], $this->tables['users_groups'].'.'.$this->join['users'].'='.$this->tables['users'].'.id')
->join($this->tables['groups'], $this->tables['users_groups'].'.'.$this->join['groups'].'='.$this->tables['groups'].'.id')
->get($this->tables['users']);
}
use in the controller:
$groups = array(1,2,3,4);
$this->data['list_staff'] = $this->ion_auth->users($groups)->result(); // выбираем всех teachers из зарегистрированных пользователей
foreach ($this->data['list_staff'] as $k => $one_staff)
{
$this->data['list_staff'][$k]->groups = $this->ion_auth->get_users_groups($one_staff->id)->result();
}
and in view use:
<?php foreach($list_staff as $one):?>
<?php foreach ($one->groups as $group):?>
<?php echo $group->description;?>,
<?php endforeach?>
<?endforeach;?>
but what about query to get groups for current logged in user (for example in my profile) I find next decision.
Controller:
$this->data['this_user_groups'] = $this->ion_auth->get_users_groups()->result();
and view just:
<?php foreach ($this_user_groups as $group):?>
<?php echo $group->description;?>,
<?php endforeach?>