How to use Sentry 2 in Laravel 4 - php

I have a Personcontroller and a Festivalcontroller in my laravel4 application. The actions in those controllers can only be accessible by an administrator.
If my database only has a user with test#hotmail.com, that user can access the routes of those 2 controllers. If my database has no user with test#hotmail.com, but it has other users, those other users can't access the routes of those 2 controllers. And when my database has a user with test#hotmail.com, and has other users, everyone can access the routes of those 2 controllers.
I only want the user with email test#hotmail.com to access the routes of those controllers.
I installed Sentry2 by doing this:
In composer.json file require:
"cartalyst/sentry": "2.0.*"
Run
php composer.phar update
In app > config > app.php:
'Cartalyst\Sentry\SentryServiceProvider', => to the providers array
'Sentry' => 'Cartalyst\Sentry\Facades\Laravel\Sentry', => to the aliases array
After the installation I made the SentrySeeder file:
<?php
class SentrySeeder extends Seeder {
public function run()
{
DB::table('users')->delete();
DB::table('groups')->delete();
DB::table('users_groups')->delete();
Sentry::getUserProvider()->create(array(
'email' => 'test#hotmail.com',
'password' => "test",
'activated' => 1,
));
$user = Sentry::getUserProvider()->findByLogin('test#hotmail.com');
$adminGroup = Sentry::getGroupProvider()->findByName('Test');
$user->addGroup($adminGroup);
}
}
In my PersonController
class PersonController extends BaseController {
public function index()
{
try
{
$user = Sentry::findUserByLogin('test#hotmail.com');
if ($user)
{
$person = Person::with('user')->orderBy('person_id')->paginate(10);
return View::make('persons.index')
->with('person', $person);
}
}
catch (Cartalyst\Sentry\Users\UserNotFoundException $e)
{
echo 'User was not found.';
}
}
}
Login action in LoginController
public function login()
{
$input = Input::all();
$rules = array(
'user_email' => 'required',
'user_password' => 'required'
);
$validator = Validator::make($input, $rules);
if ($validator->fails()) {
return Redirect::to('login')
->withErrors($validator) // send back all errors to the login form
->withInput(Input::except('user_password'));
}
else {
$attempt = Auth::attempt([
'user_email' => $input['user_email'],
'password' => $input['user_password']
]);
if ($attempt) {
return Redirect::to('/home');
}
else {
return Redirect::to('login');
}
}
Store a user in database
public function store()
{
$input = Input::all();
$rules = array(
'user_email' => 'required|unique:users|email',
'user_username' => 'required|unique:users',
);
$validator = Validator::make($input, $rules);
if($validator->passes())
{
$password = $input['user_password'];
$password = Hash::make($password);
$location = new Location();
$person = new Person();
$user = new User();
$person->person_firstname = $input['person_firstname'];
$person->person_surname = $input['person_surname'];
$user->user_username = $input['user_username'];
$user->user_email = $input['user_email'];
$user->user_password = $password;
$location->save();
$person->save();
$user->location()->associate($location);
$user->person()->associate($person);
$user->save();
Session::flash('message', 'Successfully created user!');
return Redirect::to('login');
}
else {
return Redirect::to('persons/create')->withInput()->withErrors($validator);
}
}

Looks like you need to use your own users table and also use Sentry's. So you'll need to add related Sentry's columns to yours. It's easy:
1) Go to vendor\cartalyst\sentry\src\migrations.
2) Create one new migration for every file you see there, example:
php artisan migrate:make add_sentry_groups_table
3) Copy the up() and down() code (ONLY!) to your new migrations.
4) And, for the users migration, you'll have to do some changes:
Instead of Schema::create('users' ... you do Schema::table('users' ..., to add more columns to your table.
Delete all commands for columns that you alread have in your current users table, examples of lines you must delete:
$table->increments('id');
$table->timestamps();
5) Run a normal ´php artisan migrate´.
After that you should have the Sentry's tables ready to work.
EDIT
As you're not using the usual 'email' and 'password' columns, publish Sentry's configuration:
php artisan config:publish cartalyst/sentry
And alter
'login_attribute' => 'user_email',

Related

Save user data on click button

I'm working on laravel 5.4 and I have this code:
public function apply($id){
$user = User::where('id', $id)->get()->first();
$data = [
'name' => $user->first_name,
'family' => $user->last_name,
'email' => $user->email,
'username' => $user->username,
'gender' => $user->gender,
'birthday' => $user->birthday,
'cv' => $user->cv,
'about' => $user->about,
'education' => $user->education,
'experiences' => $user->experiences,
];
$company = Company::get()->first();
Mail::send('emails.apply', $data, function ($message) use ($company)
{
$message->from('noreply#gmail.com', 'Robert Nicjoo');
$message->subject('New Apply');
$message->to($company->email);
});
Mail::send('emails.uapply', $data, function ($message) use ($user)
{
$message->from('noreply#gmail.com', 'Robert Nicjoo');
$message->subject('You Applied successfully');
$message->to($user->email);
});
Session::flash('success', 'Your application was sent to company.');
return redirect()->back()->with('session', $data);
}
This will send email to company when user click on apply button and send user info to them, now I also want to save data of the user include user_id, ad_id and company_id in another table so both user and company owners can have access to their history of applied ads.
I also have this table to save data on:
public function up()
{
Schema::create('applies', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('ad_id')->unsigned();
$table->integer('company_id')->unsigned();
$table->timestamps();
});
Schema::table('ads', function($table) {
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('ad_id')->references('id')->on('ads');
$table->foreign('company_id')->references('company_id')->on('ads');
});
}
but in my controller (first codes) I need to know how to save those information in new table (second codes)?
Update:
Ad Model >>
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Ad extends Model
{
protected $fillable = [
'company_id', 'title', 'slug', 'image', 'description', 'address', 'job_title', 'salary',
];
public function company(){
return $this->belongsTo(Company::class);
}
public function category(){
return $this->belongsTo(Category::class);
}
public function location(){
return $this->belongsTo(Location::class);
}
public function employment(){
return $this->belongsTo(Employment::class);
}
}
since your blade is like this:
<a class="btn btn-info btn-round" href="{{ route('apply.btn', Auth::user()->id) }}">
your route should look like
Route::get('apply/{id}', 'ApplyController#apply')->name('apply.btn');
why id only ? because in the discussion we had, i found out that ad_id and company_id was taken from the controller .. then in your controller this should work
public function apply($id)
{
$ad = Ad::first();
$company = Company::first();
$apply = new Apply();
$apply->user_id = $id
$apply->ad_id = $ad->id;
$apply->company_id = $company->id;
$apply->save();
// some more codes //
}
to avoid duplicates using user_id .. add a validation function like
function validateApply(array $data)
{
return Validator::make($data, [
'user_id' => 'required|numeric|unique:apply,user_id,NULL,id,ad_id,'.$data->ad_id,
]);
}
unique:apply - it means it will check the apply table the user_id already applied ..
then in the code above just do
$validateApply= $this->validateApply(['user_id'=>$id,'ad_id'=>$ad->id]);
if(!$validateApply->fails())
{
// do the above code here
}
else
{
// duplicate !!! so do your code here
}
then to retrieve the data assuming apply is already belongsTo the user as well the user hasOne apply
Auth::user()->apply->first()->somefield;
// im not sure how the hasOne works but try
Auth::user()->apply->somefield;
Your Route should be:
Route::post('apply/{$user_id}/{company_id}/{ad_id}','ApplyController#apply');
I think you have created model for ads.
So, simply save data like this:
Your function be like
public function apply(Request $request){
// other code
$apply = new Apply();
$apply->user_id = $request->user_id;
$apply->ad_id = $request->ad_id;
$apply->company_id = $request->company_id;
$apply->save();
// other code
}
And one more thing, You should have ad_id in your post request.

User Roles in Laravel

I want to implement user roles for my controller. When the user is admin or master it works, but when the user is a client it doesn't, and I receive a 205 http response.
This code works nicely in my localhost but it doesn't so in my host.
public function store(Request $request)
{
$validation = Validator::make($request->all(), [
'name' => 'required|string',
'imageone'=> 'required|string'
]);
if ($validation->fails())
{
return response()->json('Fails',404);
}
$user = JWTAuth::parseToken()->authenticate();
if ($user->roles=='admin'||$user->roles=='master') {
$name= $request->input('name');
$imageone = $request->input('imageone');
$cate=new categoryi();
$cate->name=$name;
$cate->imageone=$imageone;
if ($cate->save())
{
return response()->json($cate,202);
}
}
return response()->json('Fails',500);
}

update profile password laravel 5

I am working in laravel 5.1 and my update profile was working but will not encrypted and not working now.
When I try to update the user table will also password_confirmation field and causes a conflict in the database. I do not understand.
In the form says successfully but the database does not update any
Code
public function updatePassword() {
$passwordData = Input::except('_token');
$validation = Validator::make($passwordData, User::$passwordData);
if ($validation->passes()) {
array_forget($passwordData,'password_confirmation');
User::where(array(
'password' => Hash::make(Input::get('password'))
));
Session::flash('password', 'Perfil editado com sucesso');
return Redirect::to('backend/perfil/password');
} else {
return Redirect::to('backend/perfil/password')->withInput()->withErrors($validation);
}
}
user
public static $passwordData = array(
'password' => 'required|confirmed',
'password_confirmation' => 'required'
);
Follow this simple steps to get rid of anything
Step 1 : Get the password from the form
$PasswordData = Input::all();
Step 2 : Validate your password
Validator::extend('pwdvalidation', function($field, $value, $parameters) {
return Hash::check($value, Auth::user()->password);
});
Step 3 : Define the validation rule in your User Model
public static $rulespwd = array('OldPassword' => 'required|pwdvalidation',
'NewPassword' => 'required|confirmed|alphaNum|min:5|max:10',
'NewPassword_confirmation' => 'required',
);
Note : You shall define your own rule according to your need
Step 4 : If the rule is passed, then update else throw error messages to your view
$validator = Validator::make($PasswordData, User::$rulespwd, $messages);
if ($validator->passes()) {
$user = User::find(Auth::user()->id);
$user->password = Input::get('NewPassword');
$user->save();
return Redirect::to(Session::get('urlpath') . '/changepassword')->withInput()->with('Messages', 'The Password Information was Updated');
} else {
return Redirect::to(Session::get('urlpath') . '/changepassword')->withInput()->withErrors($validator);
}

How to assign default user role in entrust?

I just want to assign a role to newly registered user. How I can achieve this in Laravel 5 with Entrust? I am using Entrust for roles and permissions.
Last time I tried to fire event after user registration in a file in vendor folder. Is there any way to fire an event for role assignment without modifying anything inside vendor folder?
If yes then where should I fire event? I don't want to modify anything inside my vendor folder like firing event in postRegister() in AuthenticatesAndRegistersUsers.php because new updates will overwrite my code.
Code on this link looks good but I don't know entrust has registration event or not.
http://laravel.io/forum/07-02-2014-entrust-assign-role-on-user-signup
Here is my code in routes.php:
// this event is firing on user login and i am getting user object
Event::listen('auth.login', function($user) {
var_dump($user);
die(__LINE__);
});
// this event is not firing on user registration
Event::listen('auth.register', function($user) {
var_dump($user);
die(__LINE__);
// $donor_role = DB::table('app_roles')->where('name', '=', 'donor')->pluck('id');
// $user->roles()->attach($donor_role);
// return false;
});
Please help me out.
App\Service\Registrar.php
This is my way:
public function create(array $data)
{
$create = User::create([
'username' => $data['username'],
'email' => $data['email'],
'password' => $data['password'],
]);
$user = User::find($create->id);
$role = Role::where('name', '=', 'user')->firstOrFail();
$user->roles()->attach($role->id);
return $create;
}
I figured it out all by myself. Here is how I achieved:
I copied postRegister() function from /vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesAndRegistersUsers.php and overridden in /app/Http/Controllers/Auth/AuthController.php with some modification.
Here is the modified function in AuthController.php:
public function postRegister(Request $request) {
$validator = $this->registrar->validator($request->all());
if ($validator->fails()) {
$this->throwValidationException(
$request, $validator
);
}
$this->auth->login($this->registrar->create($request->all()));
// little modification :-)
\Event::fire('auth.assign_default_role', $this->auth->user());
return redirect($this->redirectPath());
}
And here is the event listener in routes.php:
Event::listen('auth.assign_default_role', function($user) {
$donor_role = DB::table('app_roles')->where('name', '=', 'donor')- >pluck('id');
$user->roles()->attach($donor_role);
return false;
});
You can fire the register event from your controller where the actual signup is being handled.
Event::fire('auth.register', array($user));
In Laravel 5.7+ you can go to the RegisterController and modify the create function:
protected function create(array $data) {
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$default_role = Role::where('name', 'DEFAULT_ROLE_NAME')->first();
$user->attachRole($default_role);
return $user;
}
Don't forget to use App\Models\Role; in the beginning.

Laravel SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry

i am very new in Laravel and this is my first project in Laravel.As usual, first of all i am developing a full user authentication system.I can registered an single user,can send an user verification email and after clicking that link i can activate a new user account, can login and can logout.But after that whenever i am trying to registered another new user and after clicking the verification link , i am facing an exception which is,
Illuminate \ Database \ QueryException
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'users_code_unique' (SQL: update `users` set `code` = , `active` = 1, `updated_at` = 2014-07- 25 04:26:06 where `id` = 41)
now this is my route.php,
<?php
Route::get('/',array(
'as' =>'home',
'uses' =>'HomeController#index'
));
Route::get('/signin',array(
'as' =>'signin',
'uses' =>'AccountController#signinGet'
));
Route::get('/signup',array(
'as' => 'signup',
'uses' => 'AccountController#signupGet'
));
/*
/*
/Authenticated Group
*/
Route::group(array('before' => 'auth'),function(){
/*
/Sign Out(GET)
*/
Route::get('/signout',array
(
'as' => 'signout',
'uses' => 'AccountController#signoutGet'
));
});
/*
/UnAuthenticated Group
*/
Route::group(array('before' => 'guest'),function(){
/* CSRF Protect*/
Route::group(array('before' => 'csrf'),function(){
/*
/ Create Account(POST)
*/
Route::post('/signup',array(
'as'=> 'signup',
'uses'=>'AccountController#signupPost'
));
/*
/ Sign In(POST)
*/
Route::post('/signin',array(
'as' => 'signin-post',
'uses' => 'AccountController#signinPost'
));
});
/*
/ Sign In (GET)
*/
Route::get('/signin',array(
'as' => 'signin',
'uses' => 'AccountController#signinGet'
));
/*
/Create Account(GET)
*/
Route::get('/signup',array(
'as' => 'signup',
'uses'=> 'AccountController#signupGet'
));
Route::get('signup/account/activate/{code}',array(
'as' =>'activate-account',
'uses' =>'AccountController#activatePost'
));
});
?>
and this is my AccountController
<?php
class AccountController extends \BaseController {
public function signinGet()
{
return View::make('account.signin');
}
public function signinPost(){
$validator = Validator::make(Input::all(),array(
'email' => 'required|email',
'password' => 'required'
));
if($validator->fails()){
//redirect to the signin page
return Redirect::route('signin')
->withErrors($validator)
->withInput();
}else{
//Attempt user singin
$auth = Auth::attempt(array
(
'email' => Input::get('email'),
'password' => Input::get('password'),
'active' => 1
));
if($auth){
//Redirect To intented URL
return Redirect::intended('/');
}
else
{
return Redirect::route('signin')
->with('global','The username or password you provided is wrong or account not activated!');
}
}
return Redirect::route('signin')
->with('global','There is a problem Signing You in.');
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function signupGet()
{
return View::make('account.signup');
}
public function signupPost()
{
$validator = Validator::make(Input::all(), array(
'email' => 'required|max:255|email|unique:users',
'username' => 'required|min:3|unique:users',
'password' => 'required|min:6',
'password_again' => 'required|same:password'
)
);
if($validator->fails())
{
return Redirect::route('signup')
->withErrors($validator)
->withInput();
}else
{
$email = Input::get('email');
$username = Input::get('username');
$password = Input::get('password');
//Activation Code
$code = str_random(60);
$user = User::create(array(
'email' => $email,
'username' => $username,
'password' => Hash::make($password),
'code' => $code,
'active' => 0
)
);
if($user){
//User Activation Code Creation
Mail::send('emails.auth.activate', array('link' => URL::route('activate-account',$code), 'username' => $username),function($message) use ($user)
{
$message->to($user->email,$user->username)->subject('Activate Your Account');
});
return Redirect::route('signup')
->with('global','Your Account has been created! We have sent you an email to activate your account.Please Check the both the Inbox and Spam Folder.');
}
}
//return 'This is a Post Result';
}
public function activatePost($code){
$user = User::where('code','=',$code)->where('active','=',0);
if($user->count()){
$user = $user->first();
$user->active = 1;
$user->code = '';
if($user->save()){
return Redirect::route('home')
->with('global','Activated!.You can sign in now!');
}
}
else{
return Redirect::route('signup')
->with('global','Sorry!We could not activate your acount,please try again later.');
}
}
public function signoutGet(){
Auth::logout();
return Redirect::route('home');
}
}
?>
and this is my create user migration file
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration {
public function up()
{
Schema::create('users', function(Blueprint $table)
{
$table->increments('id');
$table->string('username',255)->unique();
$table->string('email',255)->unique();
$table->string('password',60);
$table->string('password_temp',60);
$table->string('code',60)->unique();
$table->integer('active');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('users');
}
}
?>
and this is my user.php
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
public function getRememberToken()
{
return $this->remember_token;
}
public function setRememberToken($value)
{
$this->remember_token = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
protected $fillable = array('email','username','password','password_temp','code','active');
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
}
?>
now whats the problem?
Make sure your code field is nullable, then instead of setting it's value to empty string, make it null:
$code = null;
Then you will be able to save it as NULL (MySQL) while it remains unique.
Also change this one:
$user = User::where('code','=',$code)->where('active','=',0);
if($user->count()){
$user = $user->first();
To:
$user = User::where('code','=',$code)->where('active','=',0)->first();
if(count($user)){
You don't need to call db twice, just check if returned result is not null (count will do), meaning it returned a User object.
your problem can use validator to check. simply use as this:
use Validator;
use Request;
//...
//unique will pre check the key code weather if unique in tbl_name
public function yourfunc(Request $request) {
// set the rules to check
$rules = ['code'=>'required|unique:tbl_name'];
$validator = Validator::make($request->all(), $rules);
if ($validator->fails()) {
// handler errors
$erros = $validator->errors();
}
//... everything is ok here
}
you can explore more at laravel validation
I found it. You've set code column as unique, though you're setting it to empty string after user click an activation link. And there already is a row in table with code=''; so it throws an error. The problem is here (activatePost):
$user->code = '';
So either don't empty it, set it to something else or set db colums as not unique.
I would leave the code without emptying it and additionally I would check if user was activated - a simple if in activatePost. Maybe it's a good idea to verify user not only according to code, but also with a hashed id in link.
There a few things you need to do to improve your code. But duplicate entry usually happens when you set a column to unique and tries to re inset the same data into another row. The most time it get confusing is when you check your table and and find the column empty. Whoop! When a column is set to unique and empty, it means no other column can contain empty data.
In simple terms the form of the column can not be duplicated, either null or with data.
Integrity constraint violation Duplicate entry problems are due to database schema inconsistence being detected by laravel.
Integrity constraint violation Duplicate entry problems are likely to occur when the database schema was preserved by laravel migration, and then the db scheme is updated somehow outside of laravel migration's control (eg. developers manually (without via performing a laravel migration) alter the db schema in a db client OR the db scheme is updated by importing a piece of SQL dump that is inconsistent with the db scheme -- as a result of that, the importing unexpectedly updates the laravel-migration-preserved db schema.
To avoid the second kind of harm, be careful when importing SQL dump data into db: ensure the SQL dump data is consistent with the current db schema before your SQL dump is imported.
Overall, when doing laravel development, the db schema should always be preserved by laravel migration to avoid db schema inconsistence.

Categories