I have an existing admin_user that I'm basically migrating to an additional admin_user record, and I want to set the password hash for the new record with the value from the old record.
Because _beforeSave hooks setPassword() and encrypts it, it doesn't seem possible.
Was in the process of writing this question, when I figured out how to solve it, so I'll go ahead and post my own answer here, in case it helps anyone else.
Looks like you need to overload the Mage_Admin_Model_User class to do this. Since you'll probably be loading the class directly and calling the method to set the password, you probably won't need to worry about rewrites or event observing.
Here's how I did it:
class Me_Mymodule_Model_Admin_User extends Mage_Admin_Model_user
{
protected function _beforeSave()
{
parent::_beforeSave();
if ($this->getPasswordHash()) {
$this->setData('password', $this->getPasswordHash());
}
}
}
And then, to change it, do the following. In my case, I did this within a custom migration script that I wrote.
// This just sets the "password_hash" data on the model which has no function other
// than to be converted to the "password" value in the _beforeSave() above.
$adminUser = Mage::getModel('mymodule/admin_user')->load($id);
$adminUser->setPasswordHash('insert password hash here')->save();
The setPasswordHash() and getPasswordHash() methods are regular Magento magic getters / setters, so they don't need to be defined anywhere.
UPDATE: Don't downvote for answering own question, it's encouraged.
Related
I'm using https://github.com/filipw/AspNetWebApi-OutputCache to add easy caching to my web-api project and I have an action that look something like this:
[HttpGet]
[CacheOutput(ClientTimeSpan = 86400, ServerTimeSpan = 86400)]
public List<Things> GetThings()
{
return service.GetThings();
}
Now things are a combination of a list of things that apply to everybody along with user-defined things that are created by a user and accessible only to that user. So I want the cache here to be tied to a specific user. I don't want user Bob getting a list of things that included things that are specific to Sally. So I created my own key generator, inheriting from DefaultCacheKeyGenerator that will append the user id:
public override string MakeCacheKey(System.Web.Http.Controllers.HttpActionContext context, System.Net.Http.Headers.MediaTypeHeaderValue mediaType, bool excludeQueryString = false)
{
var key = base.MakeCacheKey(context, mediaType, excludeQueryString);
return string.Format("{0}:{1}", key, userService.CurrentUser.UserID);
}
The UserID here is ultimately pulled from the user authorization cookie.
This seems to work fine.
However, I have another action that will let the user save their custom thing and obviously when I POST here I want to invalidate the cache, so it looks something like this:
[HttpPost]
[InvalidateCacheOutput("GetThings")]
public void SaveUserThing(UserThingModel thing)
{
service.Save(thing);
}
The problem (or rather the inefficiency) here is that from my understanding this will flush everything under this control and GetThings (the base key for all caches) which will include the cache for every user. This means if Bob saves a new thing, I'm going to force Sally to have to get a whole new list of things, even though her list won't have changed.
Is there an easy way around this? I suspect the problem lies in CacheOutputConfiguration.MakeBaseCacheKey, but there doesn't seem to be a mechanism to override that functionality to have it build a base key from controller, action and userId.
I could probably just grab the source from GitHub and adapt to suit my needs, but I wanted to be sure I wasn't a) missing something obvious and b) barking up the wrong tree.
I use the Hash::make to deal with the password when it write into database.
But now I have a problem,How I get the original password?
I mean not hashed password.
Because I have a page want to show the password to the user himself.
Should I have another database field to record the original password?
Or there has a simple Laravel way?
Just to expand on what Doon says, which as Mike points out is definitely correct - never save plain text passwords - always provide a reset option only for lost/forgotten passwords.
Laravel luckily can help you out here with its RemindableInterface, which you can implement in your User class/model, eg.
class User extends Eloquent implements RemindableInterface {
public function getReminderEmail()
{
return $this->email;
}
}
so no need to start from scratch on this - details about usage here - http://four.laravel.com/docs/security#password-reminders-and-reset
Glen
I'm building a site and would like to create a list of reserved usernames to keep people from creating usernames like account, index, profile and others. I already have my list, I'm just not sure where in Codeigniter to store this data/array.
I'm pretty familiar with Codeingiter and I like to keep things where they are suppose to be. Helpers, libraries and configs just don't seem like places to store an array of reserved variables... but maybe i'm wrong.
I would appreciate suggestions! Thanks in advance.
It depends on your need and preference, config is right but helper is also right because if you keep it in helper file then you may also create a helper function right there, for example
function is_reserved_username($username)
{
$reserved_words = array('account', 'index');
return in_array($username, $reserved_words);
}
So, from anywhere, you can use
if(is_reserved_username($this->input->post('username'))) {
// it's a reserved word
}
Also, if you are using your own base controller (MY_Controller) then you may keep it in that base controller, so it'll be available in every classes and you can access it using something like
In MY_Controller if it's available as
$reserved_words = array('account', 'index');
Use it from a controller/model
if(in_array($username, $this->reserved_words)) {
// it's a reserved word
}
I don't think there is any "right" way to do this. Personally I would just create a table in my database. I'd then create a function that would check this table for reserved names when a new user is registering and return TRUE if the username isn't reserved and FALSE if it is reserved
Since I'm porting an app to Laravel and it's using the Auth Class, I need to change all the passwords in my users table to bycrypt (using Hash::make()).
The thing is that I want to use the usernames as default password (so when the migration is done, my user "Mario" will have a Password of "Mario") — I wanna do this with all the entries of the database via a Migration, but I can't seem to make it, since I don't know how to get the value of the select, hash it, then use it in the update.
Is there any way to do this without using loops? (i.e without making one query per user)
EDIT: Yes, this is impossible to do without loops. I realized that. And #Adrenaxus has the right answer.
Why don't you do something like this:
foreach(User::all() as $user){
$user->password = Hash::make($user->username);
$user->save();
}
The Dynamics AX 2009 Best Practice add-in is throwing the following error on a display method override.
"TwC: Validate access to return value from the display/edit method."
Here is my display method.
display ABC_StyleName lookupModuleName(ABC_StyleSettings _ABC_StyleSettings)
{
;
return ABC_Styles::find(_ABC_StyleSettings.StyleID).StyleName;
}
I'm assuming it wants me to check a config or security key before returning a result. Any suggestions/examples on where to start?
Thanks
This is a reminder that you need to consider whether the user should have access to the data you are returning from the function. For table fields, the kernel normally does this for you based on the security groups the user is in and the security keys set on fields.
To check if a user has access to a field, use the hasFieldAccess function. To see how this is used, look at the table methods BankAccountStatement.openingBalance() or CustTable.openInvoiceBalanceMST(). There are other helper functions to check security keys such as hasMenuItemAccess, hasSecuritykeyAccess, and hasTableAccess.
In your case, add this code:
if(!hasFieldAccess(tablenum(ABC_Styles),fieldnum(ABC_Styles,StyleName)))
{
throw error("#SYS57330");
}
Even after you add that code, you will still get the Best Practice error. To tell the compiler you have addressed the issue, you need to add the following comment immediatly before the function declaration:
//BP Deviation Documented