I have a Jhipster application and already changed the default language in the app to use french.
In app.js:
$translateProvider.preferredLanguage('fr');
But I can't change the language that was set for a User. I am using the default User account created with the application: "user".
When I logged in the application and change the language to French and save the User information, the default User table is not changed. So when I logged in again, the language is English.
The lang_key field is still en in the table.
Do you know how to change the language for a User?
Thanks,
It looks like this is not implemented in Jhipster. So the lang_key is only set when you create a new user.
I added it to my application by doing the following:
NOTE: This is changing the language of the current user by setting it by the current language in use in the app.
UserService.java
Add the langKey to the method:
public void updateUserInformation(String firstName, String lastName, String email, String langKey) {
...
currentUser.setLangKey(langKey);
...
}
AccountResource.java
In the Post Request (add the langKey by getting it from the userDTO):
userService.updateUserInformation(userDTO.getFirstName(), userDTO.getLastName(), userDTO.getEmail(), userDTO.getLangKey());
settings.controller.js
Finally in the setting controller set the language in use (just after the account is fetched)
$scope.settingsAccount = account;
$scope.settingsAccount.langKey = $translate.use();
You will need to add $translate to the function parameter of the controller.
If you want set language for each user, you can set it in liquibase, users.csv. And in this file find column - "lang_key". and set language. For default it is "en".
I did, that always was only one language. In any roles and for any users.
Find this block in app.js:
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: 'i18n/{lang}/{part}.json'
});
and change line
urlTemplate: 'i18n/{lang}/{part}.json'
to
urlTemplate: 'i18n/fr/{part}.json'
In this case always will be french language
Related
I have tried to save login value as true if user has logged in once by using
Application.Current.Properties["isLoggedIn"] = "true";
but its not working. If i remove my app from background it again shows the login page but if user is logged in it should show the next page.
When using 'Application Properties Dictionary' you have to keep in mind few things:
According to the official documentation: 'The Properties dictionary is saved to the device automatically'. However, if you want to ensure persistence you have to explicitly call SavePropertiesAsync().
The Properties dictionary can only serialize primitive types for storage. Attempting to store other types such as List can fail silently.
Read the official documentation carefully and pay attention to details. Here is a code example:
private async Task SaveApplicationProperty<T>(string key, T value)
{
Xamarin.Forms.Application.Current.Properties[key] = value;
await Xamarin.Forms.Application.Current.SavePropertiesAsync();
}
private T LoadApplicationProperty<T>(string key)
{
return (T) Xamarin.Forms.Application.Current.Properties[key];
}
// To save your property
await SaveApplicationProperty("isLoggedIn", true);
// To load your property
bool isLoggedIn = LoadApplicationProperty<bool>("isLoggedIn");
Base on your needs you may consider Local Database or Settings Plugin instead. However for saving just a few primitive values Application Properties approach should be good enough.
Xamarin Forms now includes Xamarin Forms Essentials and contains the Preferences component that you need. Check out the official website and try it.
https://learn.microsoft.com/en-us/xamarin/essentials/preferences?tabs=ios
This is an example of how to manage preferences with Essentials.
To save a value for a given key in preferences:
Preferences.Set("my_key", "my_value");
To retrieve a value from preferences or a default if not set:
var myValue = Preferences.Get("my_key", "default_value");
To remove the key from preferences:
Preferences.Remove("my_key");
To remove all preferences:
Preferences.Clear();
Supported Data Types:
bool
double
int
float
long
string
DateTime
First we set the key and value using below code
Xamarin.Essentials.Preferences.Set("UserId", content.userId);
We can get the above value in any page of project using below code
Xamarin.Essentials.Preferences.Get("UserId", "");
I have an MVC 5 application that I lock down by only allowing certain authenticated users to have access to specific actions within my controller. I utilize the authorize attribute at the top of the class allowing only the user(s) I want to gain access after login. I do this with the following attribute placed at top of my class...
[Authorize(Users="user1,user2")]
This works great! However, what if I don't want to recompile and deploy the application everytime I want to add a new user to this specific controller?
I thought I might add this in my web.config file under as a key like so...
<appSettings>
<add users="user1,user2"/>
</appSettings>
But when I try to access this key in my controller like so: [Authorize(Users=ConfigurationManager.AppSettings["users"])] I am getting an error: Cannot resolve symbol 'AppSettings'.
Is there a way to do this?
I'm not sure why an answer that didn't answer the question was accepted. Regardless, I thought it might be worth adding an answer for any future travelers.
While this functionality isn't provided out of the box, it's certainly possible by writing your own authorize attribute.
public class ConfigAuthorize : AuthorizeAttribute
{
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var allowedUsers = ConfigurationManager.AppSettings["CoolActionAllowedUsers"];
var allowedUsersArray = allowedUsers.Split(',');
if (httpContext.User.Identity != null && allowedUsersArray.Contains(httpContext.User.Identity.Name))
{
return true;
}
return false;
}
}
And to use the attribute:
[ConfigAuthorize]
public ActionResult CoolAction() {
//...
}
In the code above when your authorization is performed in AuthorizeCore, the configuration value from CoolActionAllowedUsers will be pulled into memory and the currently authenticated user will be verified if they are in the list of allowed users. If you make a change to your config file it won't be a problem; the application pool will automatically restart and the next time the code runs to read the config file your new value will be read.
I completely agree with #Shoe that roles should be used. Managing a list of users in your code is just a pain in the arse. In fact, at work, anytime I get a request for just one random user to have access to a page I always require a group to be setup. However the code above could apply to a list of roles as well.
Instead of using the Users parameter use the Roles parameter.
[Authorize(Roles="CanExecuteActions")]
Now you can manage what users have access to your controller by giving them this role. Any user without the role can't execute any actions of the controller.
I have a custom component generating a email newsletter. Now I want to generate the html in the language of the user.
But how can I access the user language file within the code?
using
$lang->setLanguage( $language );
$lang->load();
does not wrok
Thanks
If the email is generated in front-end while user is navigating your site, you can get the language user is using:
$lang = JFactory::getLanguage();
$langTag = $lang->getTag();
echo $langTag; // for example, "en-GB" for English.
$langTag could be different if your site is a multilingual site and user is browsing in a different language, not English.
When you get the language tag, you can generate your newsletter in that language and send.
If you send newsletter from back-end, you can get user's language like this
$user = JFactory::getUser(USER ID HERE); // $user = JFactory::getUser(123);
$langTag $user->getParam('language', 'en-GB'));
echo $langTag;
User can change his/her language in user profile, if user uses the default language, $langTag will be empty, so we use 'en-GB' as fallback.
I hope this helps you.
include
protected $autoloadLanguage = true;
inside your component class in php. And use language files.
I have an application where one username can belong to many companies. Thus to distinguish them, i need to use the both username and password as unique pair to login.
I'm using ASP.NET MVC and i struggle to understand where the Login occurs.
Actually i can see where it validates the user but i don't find where it retrieves the user.
So where the
Select user where username=xx and password=xx occurs ?
Asked differently : i did not find wher User is set ? I see User.Identity.Name it in the code, but i don't see :
User=Select....
Thanks
John
John, as you are using MVC. You wont be seeing any queries in the code aside from the LINQ syntax. Im guessing what you are trying to do is a many to many relationship between the User table and the Company table. (one user has multiple companys and 1 company has multiple users)
Pretty much database wise this would mean you need an extra table with both primairy keys of Company and Users.
To get back to your question. ASP.net MVC has its own membership provider. You can choose to either use the default one with its own tables or overwrite it and create ur own custom membership provider (with the ability to use ur own user table)
The default one pretty much should contain most of the basic attributes. (password reset, password salt, email,..)
http://www.asp.net/web-forms/tutorials/security/membership/creating-the-membership-schema-in-sql-server-cs
skip to the step: Installing the Application Services to generate the tables
However guessing you already have a database with your very own user table. you should overwrite the custom membership class.
Simply this would mean you make a new class that inherits from the abstract class "MembershipProvider"
public class MyMembershipProvider : MembershipProvider
{
}
After that you have to let asp know that you will be overwriting the default membershipprovider with yours in web.config:
<membership defaultProvider="MyMembershipProvider">
<providers>
<clear />
<add name="MyMembershipProvider"
applicationName="MyApp"
Description="My Membership Provider"
passwordFormat="Clear"
connectionStringName="MyMembershipConnection"
type="MyApp.MyMembershipProvider" />
</providers>
</membership>
Some methods in the membership provider requires you to return or use an object of MembershipUser. Everything of how to implement this is right here:
http://msdn.microsoft.com/en-us/library/system.web.security.membershipuser.aspx
This is not a necessary step but its recommended.
Good luck john :)
If theres any confusion in the explanation, dont hesitate to ask
Short Answer:
The code you're describing happens behind the scenes in the LogOn action of the Account Controller:
MembershipService.ValidateUser(model.UserName, model.Password)
Which returns true for a valid user. The user is then "signed in" with the next line in the code:
FormsService.SignIn(model.UserName, model.RememberMe)
(You can see both of those functions defined in the AccountModels file under the Models folder)
If you want to also check company id while authenticating the user then you'll need to write your own auth method to replace ValidateUser. Ths will depend on what you're using for your store (SQL?)
But, as a broader point, best practices you should not allow the same user name for different users. It's just a bad idea and will lead to trouble.
UPDATE:
If I were recommending how to do this, I would suggest you user the UserProfile aspect of ASP.NET Membership. It is designed to capture and store additional user variables (such as company) while still using the nicely built and secure Membership that they've written for you. Read up on it, but below is my CreateUser function in the app I'm currently working on. Note how I use the Profile to store first and last name as well as a flag that the user needs their password reset.
Again, this would preempt the ability to have multiple users with the same username, but I really think you ought to avoid that.
[HttpPost]
public ActionResult CreateUser(string username, string email, string first, string last, string role)
{
string password;
MembershipUser user;
//Generate a random password
password = Auth.CreateRandomPassword(6);
try
{
//Create the user
user = Membership.CreateUser(username, password, email);
//Add the user to the chosen role
Roles.AddUserToRole(username, role);
//Create the user profile
UserProfile profile = UserProfile.GetUserProfile(username);
profile.FirstName = first;
profile.LastName = last;
profile.ForcePasswordReset = true;
profile.Save();
EmailNewUser(username, email, password);
}
catch (Exception ex)
{
HttpContext.Response.StatusCode = 500;
HttpContext.Response.StatusDescription = ex.Message;
HttpContext.Response.Clear();
}
return PartialView("UserTable", Auth.Users());
}
For the project I'm working on, I can't use the [dbo] schema. From looking at the EventStore source, it doesn't look trivial to use a non-dbo schema.
So far, the best I've come up with is to use a custom dialect like this:
Sub-class CommonSqlDialect
Add a private instance of MsSqlDialect
Then override all virtual properties of CommonSqlDialect to do something like
Example:
public override string AppendSnapshotToCommit
{
get { return customizeSchema(_msSqlDialect.AppendSnapshotToCommit); }
}
private string customizeSchema(string dboStatement)
{
// replace "[dbo]" with "[notdbo]",
// replace " Commits" with " [notdbo].Commits",
// replace " Snapshots" with " [notdbo].Snapshots"
}
I also have to customize the InitializeStorage property to replace "sysobjects" with "sys.objects" so I can add an additional constraint on the schema name.
This works, but it seems like there should be wireup options for customizing the schema and table names.
UsingSqlPersistence(...)
.WithSchema(...)
.WithCommitsTable(...)
.WithSnapshotsTable(...)
Is there a clearly better way to handle this that I've missed?
While I can see a potential need to customize the table names, the existing version does not support that. All you need to do is to subclass the MsSqlDialect and then provide your custom version to the wireup like so:
UsingSqlPersistence(...)
.WithDialect(new MsSqlDialectWithCustomTableNames());
A solution that doesn't require any code changes, and is good for security:
Create a new user in database and give him read/write only access to the new schema.
Set the new schema as a default schema to the user.
Add a new 'EventStore' connection string to the config file.
Pass this new connection to UsingSqlPersistence constructor.
All the queries in the event store are not prefixed with schema name, so changing a default schema for the user effectively 'redirects' all the calls to the new schema.
What is more, having a specific user for event store with limited permissions is a good thing anyway. Make sure that other db users don't have access to your new schema.