Cartalyst Sentinel user registration with custom fields (solved) - laravel-7

Good evening.
I added a boolean field "privacy_ok" to my user model and migration.
migration file
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name',100)->nullable();
$table->string('last_name',100)->nullable();
$table->string('email');
$table->string('password');
$table->boolean('privacy_ok')->default(0);
$table->text('permissions')->nullable();
$table->timestamp('last_login')->nullable();
$table->timestamps();
$table->engine = 'InnoDB';
$table->unique('email');
});
App\User.php
class User extends Authenticatable
{
use Notifiable;
protected $fillable = [
'first_name','last_name','email', 'password', 'privacy_ok'
];
....
When I try to register my user, the new field is skipped.
$user = Sentinel::register($request->all());
I noticed that, if I cause an error (a duplicate email address... for example), the INSERT query does show the "privacy_ok" field.
Is there a way to solve that?
Do I have to user User::create and than "convert" it into a Cartalyst Sentinel object to go on with all the other operations (such as activation, for example) ?
Thanks
EDIT
I found some info here
Laravel Cartalyst Sentinel - Adding a username column to users table (What is the right way)
Now I have a new file App\Models\Cartalyst\User.php, but when I add it to the cartalyst config file ( config/cartalyst.sentinel.php ), I receive an error.
'users' => [
// 'model' => 'Cartalyst\Sentinel\Users\EloquentUser',
'model' => 'App\Models\Cartalyst\User',
],
Cannot declare class User, because the name is already in use
Of course the user is there even if I change User to Lorem. It's not a naming issue.
SOLVED
I forgot to declare the namespace in the header of the new class! :(

Related

Laravel: Error while import excel into database

I am trying to export/import Excel files from/to the database. For that, I have viewed few tutorials. All show the same way for it. Here are the links.
https://www.laravelcode.com/post/laravel-8-excel-and-csv-import-export-to-database-using-maatwebsite-excel-with-example
https://www.itsolutionstuff.com/post/laravel-8-import-export-excel-and-csv-file-tutorialexample.html
And some other.
Exporting excel from the database is working fine. I am getting errors only while importing.
In both tutorials, they showed same way of importing code as shown below
public function model(array $row) {
return new product([
'vendor_id' => $row[0],
'product_name' => $row[1],
'product_price' => $row[2],
'product_model' => $row[3],
'created_at' => $row[4],
'updated_at' => $row[5],
]);
}
It is giving me this error while I am trying to import excel.
Add [vendor_id] to fillable property to allow mass assignment on [App\Models\product].
I try to search about fillable and found some solutions. I tried to apply on it but the error isn't getting resolved. Any idea where I went wrong?
UPDATE
Product Model file code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class product extends Model {
use HasFactory;
}
You will need to specify either a fillable or guarded property on your model class. These properties are required because all Eloquent models are protected against mass assignment vulnerabilities by default.
A mass assignment vulnerability occurs when a user passes an unexpected HTTP request field and that field changes a column in your database that you did not expect. For example, a malicious user might send an is_admin parameter through an HTTP request, which is then passed to your model's create method, allowing the user to escalate themselves to an administrator.
If you are not specifying $guarded property then all fields need to be mentioned in $fillable property.
protected $fillable = ['vendor_id',
'product_name',
'product_price',
'product_model',
];
or
protected $guarded=['id']
Ref:https://laravel.com/docs/8.x/eloquent#mass-assignment

Finding if someone got a new role on discord.js

I would like to give a suffix every members on my server. The nickname should be for example Name (role).
I tried the simple
client.on("guildMemberUpdate", function(oldMember, newMember){
//Here the setting
});
But it wasn't good. Can you help me?
I think, it should be like this:
client on guildMemberUpdate:
check if someone's role is xy:
give him a suffix, like name (role).
If you are assigning the role programatically it would be easier if you handle the name change of the role in the same part of the code since you already know which role is the new one, if this is not the case you are right for using the event, what you want is to find the new role that has been added and change the name of the member after
client.on("guildMemberUpdate", (oldMember, newMember) => {
// Get the role which has been added
const newRole = newMember.roles.cache
.filter(r => !oldMember.roles.cache.has(r.id))
.first()
// Change username
newMember.setNickname(`${newMember.displayName} (${newRole.name})`)
})
See Collection methods

Security model and existing database

I have created a database with code first and DbContext.
However this sit separately to the security model database on a new MVC 4 site.
My question is how do i combine my existing database with the security model or should they be kept separate for a valid reason
For example is this the best solution
http://blog.spontaneouspublicity.com/including-asp-net-simple-membership-tables-as-part-of-your-entity-framework-model
This would recreate the security model and roles when i first ran the application.
Or is there an alternative way of doing this.
I love the new MVC and Simplemembership Provider for this reason. You can very easily combine your models with the asp.net account models.
When you use the default internet template it creates a context called UsersContext. To do something simple like add additional fields to a UserProfile object to track in the database you need to do 3 simple things.
Add the properties to the model (in the account models if you use the default template)
In the register action on the account controller, add the new fields IE:
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
var db = new UsersContext();
// Attempt to register the user
try
{
WebSecurity.CreateUserAndAccount(model.UserName, model.Password, new { FirstName = model.FirstName, LastName = model.LastName, Address = model.Address, Company = model.Company, Phone = model.Phone, Country = model.Country, City = model.City, State = model.State, Zip = model.Zip });
WebSecurity.Login(model.UserName, model.Password);
return RedirectToAction("Index", "Dashboard");
}
catch (MembershipCreateUserException e)
{
ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Note the new keyword where I took values from the model passed and just matched them up to the model. (model binding may or may not work here but I haven't tested that yet)
3) Change the register View and model to pass all the info needed
I almost cried when this worked flawlessly the first time with no strange errors.
Good luck

Adding custom field to User programmatically through liferay.expando

I am trying to add fields to com.liferay.portal.model.User, an extra attribute using Expando. Can someone explain to me how this method is adding a field because docs don't have much description.
private void addUserCustomAttribute(long companyId, ExpandoTable userExpandoTable, String attributeName, int type) throws PortalException, SystemException {
ExpandoColumnLocalServiceUtil.getColumn(userExpandoTable.getTableId(), attributeName); //should be addColumn(long tableId, String name, int type) ???
} //and where can find type description couse i have very specific type, Map(String,Object) couse in ExpandoColumnConstants didn't see it
I have taken this from Liferay Expando Wiki's Adding User Custom Attributes.
When should I call this all? Where to put this in my project? What change is required or everything needs to be changed to call it.
Some good tutorial will be nice because it's hard to find something from 0 to end, always found only some part with no explanation.
The question is not very clear. But if you simply want to add a custom attribute for your User then you can refer to my answer here and reproduced for your reference:
Custom field for the user-entity can be created through:
Control Panel -> Portal -> Custom Fields -> User.
And programmatically can be created as follows:
user.getExpandoBridge().addAttribute("yourCustomFieldKey");
Then set the value as:
user.getExpandoBridge().setAttribute("yourCustomFieldKey", "valueForCustomField");
If your custom field is already present you can check like this:
if (user.getExpandoBridge().hasAttribute("yourCustomFieldKey")) { ... };
The data is stored in tables prefixed with "EXPANDO":
EXPANDOCOLUMN: stores the custom field key and other settings
(contains the tableId refrences)
EXPANDODATA: stores the custom field value for the key (contains the
columnId and tableId refrences)
EXPANDOTABLE: stores for which liferay entity (user) are you adding
the custom field
EXPANDOROW: stores linking information between a user and its values
(contains tableId and userId refrences)
Hope this helps.
If your custom field is multivalue, you can use this:
String customVal = "yourCustomFieldValue";
user.getExpandoBridge().setAttribute("yourCustomFieldKey", new String[] {customVal }, false);
The last parameter set to "false" avoids permission check.

Spring security integration with open id in grails

I am working on Integrating spring security with openId for my grails Application using springsecurity core and springsecurity openid plugins. I have integrated it, and it works well but I need to access the email for the logged in person. How can I get that, all that I am able to access is a token which is used for identifying the person.
Thanks to Ian Roberts.
He gives me this reply,Which exactly solves my problem.
His reply was:
As it happens I implemented exactly this in one of my applications
yesterday :-) Unfortunately it's not an open-source app so I can't just
point you at my code but I can explain what I did.
The spring-security-openid plugin supports the "attribute exchange"
mechanism of OpenID, although the support is not documented much (if at
all). How well it works depends on the provider at the far end but this
at least worked for me using Google and Yahoo.
In order to request the email address from the provider you need to add
the following to Config.groovy:
grails.plugins.springsecurity.openid.registration.requiredAttributes.email
= "http://axschema.org/contact/email"
Now to wire that into your user registration process you need an email
field in your S2 user domain class, and you need to edit the generated
OpenIdController.groovy in a few places.
add an email property to the OpenIdRegisterCommand
in the createAccount action there's a line
"if(!createNewAccount(...))" which passes the username, password and
openid as parameters. Change this along with the method definition to
pass the whole command object instead of just these two fields.
in createNewAccount pass the email value forward from the command
object to the User domain object constructor.
And finally add an input field for email to your
grails-app/views/openId/createAccount.gsp.
You can do the same with other attributes such as full name.
grails.plugins.springsecurity.openid.registration.requiredAttributes.fullname
= "http://axschema.org/namePerson"
The important thing to wire it together is that the thing after the last
dot following requiredAttributes (fullname in this example) must match
the name of the property on the OpenIdRegisterCommand.
Regards
Charu Jain
I've never used the springsecurity openid plugin, but when using springsecurity core you can expose additional information about the current user by implmenting a custom UserDetails. In my app, I added this implementation, so that I can show the name property of logged-in users. You'll need to change this slightly, so that the email address is exposed instead
/**
* Custom implementation of UserDetails that exposes the user's name
* http://grails-plugins.github.com/grails-spring-security-core/docs/manual/guide/11%20Custom%20UserDetailsService.html
*/
class CustomUserDetails extends GrailsUser {
// additional property
final String name
CustomUserDetails(String username,
String password,
boolean enabled,
boolean accountNonExpired,
boolean credentialsNonExpired,
boolean accountNonLocked,
Collection<GrantedAuthority> authorities,
long id,
String displayName) {
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities, id)
this.name = displayName
}
}
You then need to create a custom implementation of UserDetailsService which returns instances of the class above
class UserDetailsService implements GrailsUserDetailsService {
/**
* Some Spring Security classes (e.g. RoleHierarchyVoter) expect at least one role, so
* we give a user with no granted roles this one which gets past that restriction but
* doesn't grant anything.
*/
static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]
UserDetails loadUserByUsername(String username, boolean loadRoles) {
return loadUserByUsername(username)
}
UserDetails loadUserByUsername(String username) {
User.withTransaction { status ->
User user = User.findByUsername(username)
if (!user) {
throw new UsernameNotFoundException('User not found', username)
}
def authorities = user.authorities.collect {new GrantedAuthorityImpl(it.authority)}
return new CustomUserDetails(
user.username,
user.password,
user.enabled,
!user.accountExpired,
!user.passwordExpired,
!user.accountLocked,
authorities ?: NO_ROLES,
user.id,
user.name)
}
}
}
You need to register an instance of this class as a Spring bean named userDetailsService. I did this by adding the following to Resources.groovy
userDetailsService(UserDetailsService)

Resources