2015-08-05 04:07:31 +08:00
|
|
|
|
using MongoDB.Bson;
|
|
|
|
|
using MongoDB.Bson.Serialization.Attributes;
|
|
|
|
|
using MongoDB.Driver;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Web.Security;
|
|
|
|
|
using System.Collections.Specialized;
|
2015-08-05 07:23:20 +08:00
|
|
|
|
using System.Configuration.Provider;
|
2015-08-05 04:07:31 +08:00
|
|
|
|
|
|
|
|
|
namespace MongoAuth
|
|
|
|
|
{
|
|
|
|
|
public class MongoRoleProvider : RoleProvider
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
private const string _roleCollectionName = "roles";
|
|
|
|
|
private const string _memberCollectionName = "members";
|
2015-08-05 04:07:31 +08:00
|
|
|
|
private MongoClient _dbClient;
|
2015-08-05 07:23:20 +08:00
|
|
|
|
private IMongoCollection<MongoRole> _roleCollection;
|
|
|
|
|
private IMongoCollection<MongoMember> _memberCollection;
|
2015-08-05 04:07:31 +08:00
|
|
|
|
|
|
|
|
|
public override string ApplicationName
|
|
|
|
|
{
|
|
|
|
|
get { return ""; }
|
|
|
|
|
set { }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Initialize(string name, NameValueCollection config)
|
|
|
|
|
{
|
|
|
|
|
base.Initialize(name, config);
|
|
|
|
|
|
|
|
|
|
_dbClient = new MongoClient(new MongoClientSettings()
|
|
|
|
|
{
|
|
|
|
|
Server = new MongoServerAddress(DatabaseConfig.Host, DatabaseConfig.Port)
|
|
|
|
|
});
|
2015-08-05 07:23:20 +08:00
|
|
|
|
|
|
|
|
|
_roleCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoRole>(_roleCollectionName);
|
|
|
|
|
_memberCollection = _dbClient.GetDatabase(DatabaseConfig.Database).GetCollection<MongoMember>(_memberCollectionName);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var roleTask = _roleCollection
|
|
|
|
|
.Find(r => roleNames.Contains(r.RoleName))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
roleTask.Wait();
|
|
|
|
|
List<MongoRole> roles = roleTask.Result;
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var userTask = _memberCollection
|
|
|
|
|
.Find(u => usernames.Contains(u.UserName))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
userTask.Wait();
|
|
|
|
|
List<MongoMember> users = userTask.Result;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < roles.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
List<Guid> newUsers = new List<Guid>();
|
|
|
|
|
|
|
|
|
|
if (roles[i].Users != null)
|
|
|
|
|
{
|
|
|
|
|
newUsers.AddRange(roles[i].Users);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var usersToAdd = from u in users
|
|
|
|
|
where !newUsers.Any(v => v == u.Id)
|
|
|
|
|
select u.Id;
|
|
|
|
|
|
|
|
|
|
newUsers.AddRange(usersToAdd);
|
|
|
|
|
|
|
|
|
|
roles[i].Users = newUsers.ToArray();
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var update = _roleCollection
|
|
|
|
|
.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
update.Wait();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void CreateRole(string roleName)
|
|
|
|
|
{
|
|
|
|
|
MongoRole r = new MongoRole()
|
|
|
|
|
{
|
|
|
|
|
Id = Guid.NewGuid(),
|
|
|
|
|
RoleName = roleName
|
|
|
|
|
};
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var task = _roleCollection
|
|
|
|
|
.InsertOneAsync(r);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
task.Wait();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.RoleName == roleName)
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
role.Wait();
|
|
|
|
|
|
|
|
|
|
if (role.Result != null && role.Result.Users.Length > 0 && throwOnPopulatedRole)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
throw new ProviderException(Properties.Resources.RoleNotEmpty);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var task = _roleCollection
|
|
|
|
|
.DeleteOneAsync(r => r.RoleName == roleName);
|
|
|
|
|
task.Wait();
|
|
|
|
|
|
2015-08-05 04:07:31 +08:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.RoleName == roleName)
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
role.Wait();
|
|
|
|
|
|
|
|
|
|
if (role == null)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
return Array.Empty<string>();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var users = _memberCollection
|
|
|
|
|
.Find(u => role.Result.Users.Contains(u.Id) && u.UserName.ToLower().Contains(usernameToMatch.ToLower()))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
users.Wait();
|
|
|
|
|
|
|
|
|
|
return users.Result
|
|
|
|
|
.Select(r => r.UserName)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string[] GetAllRoles()
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var roles = _roleCollection
|
|
|
|
|
.Find(new BsonDocument())
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
roles.Wait();
|
2015-08-05 07:23:20 +08:00
|
|
|
|
|
2015-08-05 04:07:31 +08:00
|
|
|
|
return roles.Result
|
|
|
|
|
.Select(r => r.RoleName)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string[] GetRolesForUser(string username)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var user = _memberCollection
|
|
|
|
|
.Find(u => u.UserName.ToLower() == username.ToLower())
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
user.Wait();
|
|
|
|
|
|
|
|
|
|
if (user == null)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
return Array.Empty<string>();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.Users != null && r.Users.Contains(user.Result.Id))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
role.Wait();
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
return role.Result
|
|
|
|
|
.Select(r => r.RoleName)
|
|
|
|
|
.ToArray();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override string[] GetUsersInRole(string roleName)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.RoleName == roleName)
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
role.Wait();
|
|
|
|
|
|
|
|
|
|
if (role == null)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
return Array.Empty<string>();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var users = _memberCollection
|
|
|
|
|
.Find(u => role.Result.Users.Contains(u.Id))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
users.Wait();
|
|
|
|
|
|
|
|
|
|
return users.Result
|
|
|
|
|
.Select(u => u.UserName)
|
|
|
|
|
.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool IsUserInRole(string username, string roleName)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var user = _memberCollection
|
|
|
|
|
.Find(u => u.UserName.ToLower() == username.ToLower())
|
|
|
|
|
.SingleOrDefaultAsync();
|
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.RoleName == roleName)
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
user.Wait();
|
2015-08-05 07:23:20 +08:00
|
|
|
|
role.Wait();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
if (user.Result == null || role.Result == null || role.Result.Users == null)
|
2015-08-05 04:07:31 +08:00
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
return role.Result.Users.Contains(user.Result.Id);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var roleTask = _roleCollection
|
|
|
|
|
.Find(r => roleNames.Contains(r.RoleName))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
roleTask.Wait();
|
|
|
|
|
List<MongoRole> roles = roleTask.Result;
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var userTask = _memberCollection
|
|
|
|
|
.Find(u => usernames.Contains(u.UserName))
|
|
|
|
|
.ToListAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
userTask.Wait();
|
|
|
|
|
List<MongoMember> users = userTask.Result;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < roles.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
roles[i].Users = (from u in roles[i].Users
|
|
|
|
|
where !users.Any(v => v.Id == u)
|
|
|
|
|
select u).ToArray();
|
|
|
|
|
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var update = _roleCollection
|
|
|
|
|
.ReplaceOneAsync(Builders<MongoRole>.Filter.Eq(r => r.Id, roles[i].Id), roles[i]);
|
2015-08-05 04:07:31 +08:00
|
|
|
|
update.Wait();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool RoleExists(string roleName)
|
|
|
|
|
{
|
2015-08-05 07:23:20 +08:00
|
|
|
|
var role = _roleCollection
|
|
|
|
|
.Find(r => r.RoleName == roleName)
|
|
|
|
|
.SingleOrDefaultAsync();
|
2015-08-05 04:07:31 +08:00
|
|
|
|
role.Wait();
|
|
|
|
|
|
|
|
|
|
return role.Result != null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[DataObject]
|
|
|
|
|
public class MongoRole
|
|
|
|
|
{
|
|
|
|
|
[BsonId]
|
|
|
|
|
public Guid Id { get; set; }
|
|
|
|
|
|
|
|
|
|
public string RoleName { get; set; }
|
|
|
|
|
|
|
|
|
|
public Guid[] Users { get; set; }
|
|
|
|
|
}
|
|
|
|
|
}
|