getCurrentUser not going null even i logged out using Parse sdk - parse-platform

How to manage session with Parse SDK?
I have used SharedPrefences to locally store the session user info, and checked on the start whether move the user to Home Screen or Login screen. Is this the right process or there is an option to maintain session automatically without using SharedPrefecences.

Just use SharedPrefences according to your Login and SignUp Activity besides you can also use Parse Session Management..

I don't know the solution to the first problem as even I failed to get it working. One of the workaround is to store the user information in shared preferences temporarily when he/she logs in and clear them when user logs out of the app.
private void setUserPreferences(String username){
SharedPreferences sharedPreferences=getSharedPreferences("DEFAULT_SP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.putString("username", username);
editor.commit();
}
private String getUserPreferences(){
SharedPreferences sharedPreferences=getSharedPreferences("DEFAULT_SP", Context.MODE_PRIVATE);
return sharedPreferences.getString("username", null);
}
private void clearUserPreferences(){
SharedPreferences sharedPreferences=getSharedPreferences("DEFAULT_SP", Context.MODE_PRIVATE);
SharedPreferences.Editor editor=sharedPreferences.edit();
editor.clear();
editor.commit();
}
Now you can call these functions when you log into the app and log out of the app. Not a viable solution but its all what I've got for the time being.
Also, you cannot login using email-id in parse, you will need username for that. So what you can do is to find the username associated with that email and then log into parse using that username.
private String mUsername=null;
private void getParseUsername(String email){
ParseQuery<ParseObject> query = ParseQuery.getQuery("User");
query.whereEqualTo("email", email);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> parseList, ParseException e) {
if (e == null) {
//assuming you don't have same email id's in the parse database
//, I don't think that's even allowed.
mUsername = parseList.get(0).getString("");
} else {
Log.d("parseList", "Error: " + e.getMessage());
}
}
});
}
For retrieving user info, you can simply type this code:
ParseUser.getCurrentUser().getUsername()
For your fourth question, if I understand it correctly, you don't want user to register with a mobile number which is already registered.
private boolean mDuplicatePhoneNo=false;
private void isPhoneNumberDuplicate(String phoneNo)
ParseQuery<ParseObject> query = ParseQuery.getQuery("User");
//Here phone_no is the field name in which you have stored your phone numbers
//Make sure they are in string format.
query.whereEqualTo("phone_no", phone);
query.findInBackground(new FindCallback<ParseObject>() {
public void done(List<ParseObject> parseList, ParseException e) {
if (e == null) {
if(phoneNo.equals(parseList.get(0).getString("phone_no"))){
mDuplicatePhoneNo=true;
}
} else {
Log.d("parseList", "Error: " + e.getMessage());
}
}
});
Also make sure to visit https://parse.com/docs/android/guide#getting-started
for a better guide.

Related

Correct Implementation of Forgot Password AspNetBoilerPlate

Im using aspnetboilerplate (MVC) and wanted to implement a forgot password feature to allow the user to reset their own passwords using a link on the login screen.
I imagine this to work by generating a password reset code which is then emailed to the user.The user follows the link and is taken to a screen allowing them to reset the password.
Im stuck at the initial stage. i started with a copy of the login action after noticing that when attempting to log in the user object was returned. From here i attempt to set a password reset code.
[HttpPost]
[UnitOfWork]
public virtual async Task<JsonResult> ForgotPassword(ForgotPasswordViewModel forgotPasswordModel, string returnUrl = "", string returnUrlHash = "")
{
returnUrl = NormalizeReturnUrl(returnUrl);
if (!string.IsNullOrWhiteSpace(returnUrlHash))
{
returnUrl = returnUrl + returnUrlHash;
}
var loginResult = await _logInManager.LoginAsync(forgotPasswordModel.UsernameOrEmailAddress, "ForgotPassword", GetTenancyNameOrNull());
loginResult.User.SetNewPasswordResetCode();
switch (loginResult.Result)
{
case AbpLoginResultType.Success:
return Json(loginResult);
default:
throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, forgotPasswordModel.UsernameOrEmailAddress, GetTenancyNameOrNull());
}
}
Checking the AbpUser table after the
loginResult.User.SetNewPasswordResetCode();
i cannot see any password reset code for the user, they are all null.
Could someone point me in the right direction.
Thanks in advance
Thanks to answer below for being correct, just for completion below is exactly what worked. Obviously ignore the json return at the end
public virtual async Task<JsonResult> ForgotPassword(ForgotPasswordViewModel forgotPasswordModel, string returnUrl = "", string returnUrlHash = "")
{
//var user = await GetUserByChecking(emailAddress);
var user = await _userManager.FindByEmailAsync(forgotPasswordModel.UsernameOrEmailAddress);
if (user == null)
{
throw new UserFriendlyException("User not found!");
}
user.SetNewPasswordResetCode();
//Send an email to user with the below password reset code
/* Uri.EscapeDataString(user.PasswordResetCode) */
return Json("");
}
public class AccountAppService: IAccountAppService
{
public UserManager UserManager {get; set; }
public async Task SendPasswordResetCode(string emailAddress)
{
var user = await UserManager.FindByEmailAsync(emailAddress);
if (user == null)
{
throw new UserFriendlyException("User not found!");
}
user.SetNewPasswordResetCode();
//Send an email to user with the below password reset code
/* Uri.EscapeDataString(user.PasswordResetCode) */
}
}

Passing a variables in C#

I am trying to pass a variable that identifies a staff member from their login details to the next screen to populate the Tester ID box.
Would I be better using a global variable that is then read when the next screen is set up or would I be better to put it into a variable and send it to the next screen?
The login code sits as follows:
public Login()
{
InitializeComponent();
}
private void LoginButton_Click(object sender, EventArgs e)
{
String Username1 = StaffUsername.Text;
String Password1 = StaffPassword.Text;
String HardUser = "Test";
String HardPass = "Merlin123";
if (Username1 == "" && Password1 == "")
{
MessageBox.Show("Please Enter Login Id and Password");
}
else
{
if (Username1.Equals(HardUser) && Password1.Equals(HardPass))
{
this.Hide();
AddingClients M1 = new AddingClients();
M1.Show();
}
else{
this.Hide();
Login Lg = new Login();
Lg.Show();
MessageBox.Show("Incorrect Username or Password Entered");
}
}
}
}
}
I am using a hardcoded username and password for now, but in the actual program, I would have this call on a database and compare the username and the password and then go through to the next screen.
Would lit be better to have a global variable that the login action throws over to the next screen or would it be easier having a variable that the next screen reads and then populates the text box required? How would I go about this?
Thanks
The way you do this is to use the Thread.CurrentPrincipal.
Once the user is confirmed to be who they say they are, you can do:
private static void SignUserIn(string userName)
{
GenericIdentity identity = new GenericIdentity(userName, null);
Thread.CurrentPrincipal = new GenericPrincipal(identity);
}
Then whenever you need the userName, you use Thread.CurrentPrincipal.Identity.Name.
To extend this a little further, its probably best to abstract this a little bit, so you can swap in and out providers e.g. you might want to use Windows Authentication.
So you could do it like this:
public interface IAuthenticator
{
bool IsValidUser ( string username, string password );
IPrincipal SignInUser ( string username );
void SignOutCurrentUser();
}
public class DbAuthenticator : IAuthenticator
{
public bool IsValidUser ( string username, string password )
{
// Check user here and return bool if valid
}
public void SignInUser(string userName, string[] roles = null)
{
GenericIdentity identity = new GenericIdentity(userName, roles);
Thread.CurrentPrincipal = new GenericPrincipal(identity);
return Thread.CurrentPrincipal;
}
public void SignOutUser()
{
Thread.CurrentPrincipal = WindowsPrincipal.GetCurrent();
}
}
Then in your code, inject the authenticator using some sort of DI pattern. So MEF would be like this:
[Export(typeof(IAuthenticator))]
public interface IAuthenticator { }
And in your form:
[Import]
internal IAuthenticator authenticator;
private static void SignUserIn(string userName)
{
authenticator.SignUserIn(username);
}
You should have a User object and pass it to other pages and functions. That way they become more testable.
But you also need to store the object somewhere globally so you can retrieve the currently logged in user when needed. The problem with that is that piece of code then depends on that user storage existing/working, but if it's only one place it's okay.
PS: your title should be: pass the user on or store globally?

MVC 3 where to encrypt the user's password?

I have my own password encryption dll that I am using to check the user's password when they login, this is referenced in my User entity.
Now I have created the ability for a user to register which is working fine, apart from the passwords are yet to be encrypted.
My question is quite simple, where should I put the encryption of the new user's password? I'm not sure as I am aware that the user's password shouldn't be transmitted in plain text, therefore I don't know where the best place to call the encryption function:
User Entity (where the encryption dll is already used for validation).
The User repository where the save user method is.
The User controller where the user creation views are controlled.
Somewhere else that I haven't considered!
Thanks very much
First of all, for client - server communication, I would suggest you to use SSL for the sensitive information (like passwords) not to be transferred in plain text format.
Afterwards, it's the common practice not to save passwords anywhere (even with encryption, but the hashed values of them.
You can put the hash function to the set method of password property. Here is an example:
public class Member
{
private string _username;
public string Username
{
get { return _username; }
set { _username = value.ToLowerInvariant(); }
}
public string Passhash {get;set;}
public void SetPassword(string password)
{
Passhash = Crypto.Hash(password);
}
public bool CheckPassword(string password)
{
return string.Equals(Passhash, Crypto.Hash(password));
}
}
public static class Crypto
{
public static string Hash(string value)
{
return Convert.ToBase64String(
System.Security.Cryptography.SHA256.Create()
.ComputeHash(Encoding.UTF8.GetBytes(value)));
}
}
Edit:
As Craig Stuntz pointed out, the Hash code in this example is very simple. See the following post for a more secure way to hash your password: Hashing passwords with MD5 or sha-256 C#
In a service layer method that will be responsible for doing 2 things:
call your encryption layer to hash the password (not to encrypt it)
call your user repository to persist the user entity to the database with the hashed password
The controller action will of course talk to the service layer.
Don't do your own password hashing and don't even think about encrypting passwords.
The effort of making this secure are tremendous. Use an existing method based on publicly available specs and algorithms.
//ENCODE
public string base64Encode(string sData)
{
try
{
byte[] encData_byte = new byte[sData.Length];
encData_byte = System.Text.Encoding.UTF8.GetBytes(sData);
string encodedData = Convert.ToBase64String(encData_byte);
return encodedData;
}
catch(Exception ex)
{
throw new Exception("Error in base64Encode" + ex.Message);
}
}
//DECODE
public string base64Decode(string sData)
{
try
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Text.Decoder utf8Decode = encoder.GetDecoder();
byte[] todecode_byte = Convert.FromBase64String(sData);
int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);
char[] decoded_char = new char[charCount];
utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);
string result = new String(decoded_char);
return result;
}
catch (Exception ex)
{
throw new Exception("Error in base64Decode" + ex.Message);
}
}
How to call
string encode= base64Encode(val);
string decode= base64Decode(val);
This is very helpful to decode and encode your string(password)

Play Framework: Image Display question

ref:
http://www.lunatech-research.com/playframework-file-upload-blob
I'm uneasy about one point in this example
#{list items:models.User.findAll(), as:'user'}
<img src="#{userPhoto(user.id)}">
#{/list}
At this point I'm already holding the user object (including the image blob). Yet the userPhoto() method makes another dip into the backend to get the Image user.photo
public static void userPhoto(long id) {
final User user = User.findById(id);
notFoundIfNull(user);
response.setContentTypeIfNotSet(user.photo.type());
renderBinary(user.photo.get());
}
Any way to avoid this unnecessary findById call?
You're not actually holding the user object any more though, because the userPhoto action is invoked in a separate request that's sent when the browser tries to load the image from the URL generated by #{userPhoto(user.id)}.
Of course, you could use the cache to store data from each user's photo Blob, which would reduce the likelihood that you had to go to the database on the image request. It's more trouble than it's worth in this case though since you're just doing a simple primary key lookup for the user object, and that should be relatively inexpensive. Plus Blobs aren't serializable, so you have to pull out each piece of information separately.
Still, if you were to try that it might look something like this:
// The action that renders your list of images
public static void index() {
List<User> users = User.findAll();
for (User user : users) {
cachePhoto(user.photo);
}
render(users);
}
// The action that returns the image data to display
public static void userPhoto(long id) {
InputStream photoStream;
String path = Cache.get("image_path_user_" + id);
String type = Cache.get("image_type_user_" + id);
// Was the data we needed in the cache?
if (path == null || type == null) {
// No, we'll have to go to the database anyway
User user = User.findById(id);
notFoundIfNull(user);
cachePhoto(user.photo);
photoStream = user.photo.get();
type = user.photo.type();
} else {
// Yes, just generate the stream directly
try {
photoStream = new FileInputStream(new File(path));
} catch (Exception ex) {
throw new UnexpectedException(ex);
}
}
response.setContentTypeIfNotSet(type);
renderBinary(photoStream);
}
// Convenience method for caching the photo information
private static void cachePhoto(Blob photo) {
if (photo == null) {
return;
}
Cache.set("image_path_user_" + user.id,
photo.getFile.getAbsolutePath());
Cache.set("image_type_user_" + user.id,
photo.getType());
}
Then you'd still have to worry about appropriately populating/invalidating the cache in your add, update, and delete actions too. Otherwise your cache would be polluted with stale data.

Login Procedure that does not require a Email Address

I have been asked to create a site where the user isn't required to provide a email to login because of privacy issues. In the past I have simple said this isn't advisable but in this case the client has stringently requested it. My initial thoughts are to potentially create administrators with a email whom could create generic logins (username and a password) and pass them to members of there group on site. Then at least I have a point of contact for login resets and such.
Has anyone had any experience with such situations where they have needed to create logins without the use of a email address? Could you direct me towards any relevant materials or tutorials that may be of use. I'm using MVC3 to develop this project.
I hope I understand your question right and you want to implement a login using username and password instead of email adress and password.
In that case you would have to implement your own custom membership provider and a custom roleprovider if needed.
You want to check the following page for more information:
Custom Membership Provider # Codeproject
EDIT
Fyi you dont need to implement every function - just implement the ones you need.
Custom membership provider from some of my older mvc3 projects. Removed most of the not-implemented functions for shorter code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
namespace Domain.Models
{
public class PlatformMembershipProvider : MembershipProvider
{
public SalesModelContainer ******** = new SalesModelContainer();
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
var user = ********.UserSet.Single(s => s.Email == username);
if (user.Password == oldPassword)
{
user.Password = newPassword;
return true;
}
else
{
return false;
}
}
public override string GetUserNameByEmail(string email)
{
var user = ********.UserSet.Single(s => s.Email == email);
return user.CompanyName;
}
public override void UpdateUser(System.Web.Security.MembershipUser user)
{
throw new NotImplementedException();
}
//TODO: use MD5 for password encryption
public override bool ValidateUser(string username, string password)
{
bool returnValue;
var user = ********.UserSet.SingleOrDefault(s => (s.Email == username) && (s.Password == password));
if (user != null)
returnValue = true;
else
returnValue = false;
return returnValue;
}
}
}

Resources