GithubHelp home page GithubHelp logo

tugberkugurlu / aspnet.identity.ravendb Goto Github PK

View Code? Open in Web Editor NEW
42.0 42.0 28.0 10.62 MB

Fully asynchronous, new and sweet ASP.NET Identity implementation for RavenDB

License: MIT License

Shell 0.30% PowerShell 1.73% C# 97.96%

aspnet.identity.ravendb's People

Contributors

thoemmi avatar tugberkugurlu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aspnet.identity.ravendb's Issues

Extending the UserStore?

Would it not make sense to use virtual methods on the UserStore, this would let me modify some of the existing methods to my liking. For my existing database when logging in I don't want to lookup a user by key, i want to use an index and lookup by email.

Cannot ConfirmEmail with new 2.0

I am attempting to ConfirmEmail. I have implemented Registration but when i confirm the email, I receive 'Cannot set the confirmation status of the e-mail because user doesn't have an e-mail as RavenUserEmail document.'

I then attempted to extend RavenUser by creating a new class that inherits from RavenUser. Within this class i have a property RavenUserEmail and create it when I create the RavenUser within the Registration. When i attempt to Confirm the email, I receive an error 'Cannot set the confirmation status of the e-mail because user doesn't have an e-mail.'

This is the code within my AccountController:

// GET: /Account/ConfirmEmail
[AllowAnonymous]
public async Task ConfirmEmail(string userId, string code)
{
var result = await UserManager.ConfirmEmailAsync(userId, code);
return View();
}

Users stored as RavenUsers rather than ApplicationUsers

In version 1.0, users were stored as ApplicationUsers/# (i.e. ApplicationUsers/225). I understand the need to move to /UserName to ensure uniqueness, but instead of ApplicationUsers/UserName, my user accounts under 2.0 are being saved as RavenUsers/UserName (even though I do derive ApplicationUsers from RavenUsers to add my own custom properties).

I create users like this:

var user = new ApplicationUser(model.UserName) {
    DateRegistered = DateTime.UtcNow,
    DateLastConnected = DateTime.UtcNow
};
user.SetEmail(model.Email);

var result = await UserManager.CreateAsync(user, model.Password);

I just want to make sure this is how it will always remain even when 2.0 becomes stable... If so, I'll move all my user accounts to the new naming convention.

UpdateAsync doesn't update the user in the database

If I update claims of a user and then call the UpdateAsync method, the user is not updated in the database. The UpdateAsync does not throw an exception and returns success. Any idea why the user is not updated?

Cannot query users

In the 2.0 branch at least , using the RavenUserStore.User() method results in "System.NotSupportedException: You can't get a sync query from async session" because the session is async.

Upgrade to RavenDB3 and PRE6 Issue

After updating to PRE6 I am getting this error now. I was using RavenDB build 3.3528 with PRE1 I think it was OK but I had issues with getting roles for a user.

Something that the ApplicationUser could not be cast to Models.Person (my own model) Not even sure why it was saying that. But I read that RavenDB 2 to 3 had some breaking changes and it was likley to that. (Even though I was already on RavenDB 3)

I upgraded Identity to PRE6 and raven to 3.3690 (When I run the sample from tag PRE6 I get the same issues (I thought I did but it worked fine in the end) + optimistic concurrency is not set on AutoFac too, on the sample!)

I get this error now.

Method not found: 'System.Threading.Tasks.Task1<!!0> Raven.Client.IAsyncDocumentSession.LoadAsync(System.String).

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.MissingMethodException: Method not found: 'System.Threading.Tasks.Task`1<!!0> Raven.Client.IAsyncDocumentSession.LoadAsync(System.String)'.

Source Error: 


Line 49:             if (ModelState.IsValid)
Line 50:             {
Line 51:                 var user = await UserManager.FindAsync(model.UserName, model.Password);
Line 52:                 if (user != null)
Line 53:                 {

FindAsync assumes incorrect document structure

It seems that the method RavenUserStore.FindAsync assumes an incorrect document structure, where RavenUserLogins are stored seperately from RavenUsers when in fact they are just an array property in the RavenUser document. The method does not find the user when the correct login provider and provider key are present. While it might not be the most effective approach, I got the method working by changing it to the following:

    public async Task<TUser> FindAsync(UserLoginInfo login)
    {
        if (login == null) throw new ArgumentNullException("login");

        string keyToLookFor = RavenUserLogin.GenerateKey(login.LoginProvider, login.ProviderKey);
        return await _documentSession.Query<TUser>().Where(u => u.Logins.Any(l => l.Id == keyToLookFor)).SingleOrDefaultAsync();
    }

This is what the user looks like in the database, after creating it with the standard code in the VS2013 web template:

{
    "UserName": "MortenChristiansen",
    "Email": null,
    "PhoneNumber": null,
    "PasswordHash": null,
    "SecurityStamp": "...",
    "IsLockoutEnabled": false,
    "IsTwoFactorEnabled": false,
    "AccessFailedCount": 0,
    "LockoutEndDate": null,
    "Claims": [],
    "Logins": [
      {
          "Id": "RavenUserLogins/Google/https://www.google.com/accounts/o8/id?id=...",
          "UserId": "Morten Christiansen",
          "LoginProvider": "Google",
          "ProviderKey": "https://www.google.com/accounts/o8/id?id=..."
      }
    ]
}

Add JsonConstructor attribute to RavenUserClaim constructor

Attribute should be added for

[JsonConstructor]
public RavenUserClaim(string claimType, string claimValue)

Here is the Exception when searching for user:

Unable to find a constructor to use for type AspNet.Identity.RavenDB.Entities.RavenUserClaim. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'Claims[0].ClaimType'.

Also I need in my project importing of test data on application startup. I am reading JSON text file, deserializing to proper object and store it into RavenDB and can't deserialize it with same exception.
Here is how I am deserializing:

private static void Insert<T>(IDocumentSession session, string path)
{
    var folder = new DirectoryInfo(path);
    var files = folder.EnumerateFiles("*.json");
    foreach (var fileInfo in files)
    {
        var c = File.ReadAllText(fileInfo.FullName);
        var obj = JsonConvert.DeserializeObject<T>(c);

        session.Store(obj);
    }
}

Username disallows using "-"

Why is it not allowed to use a dash "-" in the username?

   var user = new Models.ApplicationUser(userEmail);
   var result = await UserManager.CreateAsync(user, password);

Exception

Creating user Failed. User name [email protected] is invalid, can only contain letters or digits.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 

Exception Details: System.Web.HttpException: Creating user Failed. User [email protected] is invalid, can only contain letters or digits.

When I go into RavenDB management panel, I can change the Key manually to include the "-" and the username is just a string.

Question, use OWIN?

Has anybody got this working in the OWIN pipeline?

I'm trying to mimic the EF implementation, per owin request.
Unless theres a better way...

app.CreatePerOwinContext<AppUserIdentityDbContext>(AppUserIdentityDbContext.Create);
app.CreatePerOwinContext<AppUserManager>(AppUserManager.Create);

Where AppUserManager : UserManager
and

 public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
        {
            return = new AppUserManager(new UserStore<AppUserIdentity>(context.Get<AppUserIdentityDbContext>()));
}  

User data not being refreshed from database

You probably haven't used or seen this code in a while, but I have the following issue:

I login with a user that has an "admin" role Claim

"Claims": [
    {
         "ClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role",
         "ClaimValue": "admin"
     }
 ],

And everything works fine. But to try and test of the roles are properly set up, I change the ClaimValue to "admin2" in de database. When logging in I would expect to get a 401 unauthorised response, but instead I see that the user being fetched from the Document Store still has the old ClaimValue of "admin".

Any ideas on why the user is not being refreshed?

Update

I grabbed the source code and changed RavenUserStore so that i opens a new IAsyncSession every time FindByNameAsync is called, and that does fetch the user data anew.
Just mentioning in case it helps you to point me in the right direction

CreateAsync duplicate username

any ideas why an exception is thrown when i go to create a user with the same username as an existing user? i was expecting the result object having the errors detailed out.

thanks!

IncrementAccessFailedCountAsync

In RavenUserStore, the method IncrementAccessFailedCountAsync is supposed to return the failed count but rather it always returns zero.

It should return this
return Task.FromResult(user.AccessFailedCount);

Concurrency Issues

I'm running into concurrency issues using the 2.0.0x implementation. Depending on the the timing of each call to the UserManager, I receive the following error when trying to use more than 1 API call that incorporates the RavenDB session in a controller context:

Only a single concurrent async request is allowed per async client instance.

My understanding is that the RavenDb AsyncDocumentSession only allows one async request at a time per instance of itself. This results in the above error being thrown, again depending on the timing, if more than one request is used per controller context.

Is there a way to avoid this? Do I need to wire up a new ApplicationUserManager with a new AsyncDocumentSession each time I make a API call to ApplicationUserManager?

Optimistic Concurrency AutoFAC

I upgraded to RavenDB 3 and updated to Identity PRE6

You suggest this

IDocumentStore documentStore = new DocumentStore
{
Url = "http://localhost:8080",
DefaultDatabase = "AspNetIdentity"
}.Initialize();

using (IAsyncDocumentSession session = documentStore.OpenAsyncSession())
{
session.Advanced.UseOptimisticConcurrency = true;
RavenUserStore ravenUserStore = new RavenUserStore(session);
UserManager userManager = new UserManager(ravenUserStore);

// UserManager<RavenUser> is ready to use!

}

But I am using AutoFAC and I get the error: Optimistic concurrency disabled 'IAsyncDocumentSession' instance is not supported be......

On this line. How Do I set what is needed?

builder.Register(c => new RavenUserStore<Models.ApplicationUser>(c.Resolve(), false)).As<IUserStore<Models.ApplicationUser>>().InstancePerHttpRequest();

So the setting is on this line in autofac

builder.Register(c => c.Resolve().OpenAsyncSession()).As().InstancePerHttpRequest();

But how can I set .Advanced.UseOptimisticConcurrency = true ?

You can't get a sync query from async session

When executing any query on UserManager.Users against RavenDB that is hosted as separate service System.NotSupportedException is thrown.

[NotSupportedException: You can't get a sync query from async session]
   Raven.Client.Document.Async.AsyncDocumentSession.Raven.Client.Linq.IDocumentQueryGenerator.Query(String indexName, Boolean isMapReduce) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Document\Async\AsyncDocumentSession.cs:618
   Raven.Client.Linq.RavenQueryProviderProcessor`1.GetLuceneQueryFor(Expression expression) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProviderProcessor.cs:1439
   Raven.Client.Linq.RavenQueryProviderProcessor`1.Execute(Expression expression) in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryProviderProcessor.cs:1477
   Raven.Client.Linq.RavenQueryInspector`1.GetEnumerator() in c:\Builds\RavenDB-Stable\Raven.Client.Lightweight\Linq\RavenQueryInspector.cs:105

UserManger.FindID throws an cast exception

I have been trying to get a user by their ID, using UserManager, which is an email address.
For the sake of example [email protected]

I also have a Model.Person , which I store in the same database as the RavenUsers, and the Key is also the same email.

When I create the user I use this code

var user = new Models.ApplicationUser(userName); (UserName is the Email)

I have now eventually got got this working by using

var user2 = UserManager.FindByName("[email protected]");

The problem is when I use this

var user3 = UserManager.FindById("[email protected]");

I get an exception

Unable to cast object of type 'Models.Person' to type 'Models.ApplicationUser'.

I have been trying to work out what the problem is about 2 days now, on and off, but it seems when I use the FinByID, RavenDB, or Identidy.Raven DB for some reason actually matches up with the Person Key in the database. I couldn't understand why I was getting this exception the whole time since I am just calling a method and not trying to cast any thing.

When I use

var user3 = UserManager.FindByEmail("[email protected]");

It reutrns NULL, even though in the database under ApplciationUsers, the Email is the same as UserName and the same as the Key.

Is this a Identity.RavenDB problem?

Identity store should support IUserRoleStore

This project is pitching itself as a provider for supporting AspNet Identity 2.0 for Raven DB. Therefore it should be more comprehensive and support IUserRoleStore. I dont think it should tell people to write their apps to only use claims over roles.

Support both and let the users decide based on their needs / experience / preference.

RavenDb & uniquness

Hi,
I think the functions FindAsync/CreateAsync in RavenUserStore are not stable. In my previous projects, I had a lot of troubles with stale data, even with static indexes. IMHO, a Raven "style" will be better. Let's treat RavenUserLogin as independent document

public class RavenUserLogin
    {
        const string KEY_TEMPLATE = "RavenUserLogin/{0}/{1}";
        public RavenUserLogin()
        {
        }

        public RavenUserLogin(UserLoginInfo loginInfo, string userId)
        {
            Id = GenerateKey(loginInfo);
            UserId = userId;
        }

        public string Id { get; set; }

        public string UserId { get; set; }        

        public static string GenerateKey(UserLoginInfo loginInfo)
        {
            return string.Format(KEY_TEMPLATE, loginInfo.LoginProvider, loginInfo.ProviderKey);
        }
    }

Then,

public async Task<TUser> FindAsync(UserLoginInfo login)
        {
            var lg = await DocumentSession
                .Include<RavenUserLogin>(x=>x.UserId)
                .LoadAsync<RavenUserLogin>(RavenUserLogin.GenerateKey(login));
            return (lg != null) ? await DocumentSession.LoadAsync<TUser>(lg.UserId) : null;            
        }

Best, T.C

UserSecretStore and UserLoginStore relies on the user existence poorly

This's from IdentityStoreManager's CreateLocalUser method:

if (await this.Context.Users.Create(user) && await this.Context.Secrets.Create(new UserSecret(user.UserName, password)) && await this.Context.Logins.Add(new UserLogin(user.Id, this.LocalLoginProvider, user.UserName)))
{
    await this.Context.SaveChanges();
    result = true;
}

As seen here, there are no user changes persisted before setting the UserSecret and UserLogin here. With the current store implementations, such a behavior won't work as RavenUserSecretStore and RavenUserLoginStore relies on the existence of RavenUser.

However, UserLogin instance needs the user id which is not there yet. How does this even work?

Support of IQueryableUserStore<TUser>

In order to use UserManager.Users property store must implement interface IQueryableUserStore. Currently its not possible to build any admin panel for users using such provider.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.