Multiple User Roles in Authorize - c#

I have a controller which can be accessed by user having admin privileges or nurse. Then on separate action I can do more strict if I want to. Right now what I have is something like this
[AuthorizeUser(UserRole = "Admin", OrganizationType = "Institution")]
It works fine. But I would something like
[AuthorizeUser(UserRole = "Admin,Nurse", OrganizationType = "Institution")]
AuthorizeUser is custom made authorization
public class AuthorizeUser : AuthorizeAttribute
{
public string UserRole { get; set; }
public string OrganizationType { get; set; }
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
var isAuthorized = base.AuthorizeCore(httpContext);
if (!isAuthorized)
{
return false;
}
return CheckOrganizationType
.checkRole(this.UserRole, this.OrganizationType, Auth.CurrentUser);
}
}
public static bool checkRole(String role, String organizationType, User user)
{
RolesType rt = null;
OrganizationType ot = null;
foreach (UserRoles ur in user.GetUserRoles())
{
rt = RolesType.Get(ur.organizationTypeId,ur.roleTypeId);
ot = OrganizationType.Get(ur.organizationTypeId, "1");
}
if (rt != null && rt.Name == role && ot != null && ot.Name == organizationType)
{
return true;
}
else
{
return false;
}
}
and then check if the current user has any of the defined roles. How can this be done? Any idea?

You have just to change this statement:
if (rt != null && rt.Name == role && ot != null && ot.Name == organizationType)
with this:
if (rt != null && role.Contains(rt.Name) && ot != null && ot.Name == organizationType)

Related

How to check for presence of a login in the database

I use an ASP.NET Web API. How do I check my login with a Post request? I want to check if the login already exists in the database, and if so, throw an error.
UsersController:
[HttpPost]
public async Task<ActionResult<User>> PostUser(User user)
{
if (_context.Users == null)
{
return Problem("Entity set 'ShopContext.Users' is null.");
}
var role = await _context.Roles.FindAsync(user.IdRole);
if (role == null)
{
return NotFound();
}
for (int i = 0; i < user.Id; i++)
{
if (i == user.UserName.Length)
{
return Problem("User already registered");
}
}
user.Role = role;
_context.Users.Add(user);
await _context.SaveChangesAsync();
return CreatedAtAction("GetUser", new { id = user.Id }, user);
}
User model:
namespace ShopAPI.Models
{
public class User
{
public int Id { get; set; }
public string? Password { get; set; }
public string? UserName { get; set; }
}
}
[HttpPost]
public async Task<ActionResult<User>> PostUser(User user)
{
var userWithIdAlreadyExists = _context.Users.Find(user.Id) != null;
if(userAlreadyExists)
{
return Problem ("user with id already exists");
}
var userNameAlreadyExists = _context.users
.FirstOrDefault(u => u.UserName == user.UserName) == null;
if(userNameAlreadyExists)
{
return Problem("User already exists with that name");
}
//Write the code you want to execute when the user has a valid id and username
}

How to check whether all two objects' properties are equal, including derived ones?

Let's say I have these three classes:
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int IdNumber { get; set; }
public string Address { get; set; }
// Constructor and methods.
}
class Employee : Person
{
public byte SalaryPerHour { get; set; }
public byte HoursPerMonth { get; set; }
// Constructor and methods.
}
class Seller : Employee
{
public short SalesGoal { get; set; }
public bool MetSaleGoleLastYear { get; set; }
// Constructor and methods.
}
I would implement IEquatable<T> like this:
public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address;
}
public bool Equals(Employee other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address
&& SalaryPerHour == other.SalaryPerHour
&& HoursPerMonth == other.HoursPerMonth;
}
public bool Equals(Seller other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address
&& SalaryPerHour == other.SalaryPerHour
&& HoursPerMonth == other.HoursPerMonth
&& SalesGoal == other.SalesGoal
&& MetSaleGoleLastYear == other.MetSaleGoleLastYear;
}
Now, as you can see, the more a class is down the inheritance chain, the more properties I need to check. If for example, I inherit from a class someone else written, I also need to see the class code to find all of its properties, so I could use them to check value equality. It sounds strange to me. Isn't there a better way of doing this?
Use base. Much shorter.
public bool Equals(Seller other)
{
if (other == null) return false;
return base.Equals(other)
&& SalesGoal == other.SalaryPerHour;
&& MetSaleGoleLastYear == other.HoursPerMonth;
}
In addition to John Wu's answer, here is the corrected complete solution :
public bool Equals(Person other)
{
if (other == null) return false;
return FirstName == other.FirstName
&& LastName == other.LastName
&& IdNumber == other.IdNumber
&& Address == other.Address;
}
public bool Equals(Employee other)
{
if (other == null) return false;
return base.Equals(other)
&& SalaryPerHour == other.SalaryPerHour // ; removed
&& HoursPerMonth == other.HoursPerMonth;
}
public bool Equals(Seller other)
{
if (other == null) return false;
return base.Equals(other)
&& SalesGoal == other.SalesGoal // SalaryPerHour;
&& MetSaleGoleLastYear == other.MetSaleGoleLastYear; //HoursPerMonth;
}

ConcurrentBag FirstOrDefault NullCheck throws

I've got a Problem at my null check .
if (element == null)
throws
Object reference not set to an instance of an object.
Why can a simple null check fail at this Point? When i make a breakpoint at this Position, element has the value "null", but throws the exception anyway.
PS: At this Point, are no additional Threads active.
internal static ConcurrentBag<Node_Library> AddFileDetail(
this ConcurrentBag<Node_Library> list,
FileDetails file , Node<Node_Application> app)
{
var element = list.FirstOrDefault(x => file.Equals(x));
if (element == null)
{
list.Add(new Node_Library(file, app));
}
else
{
if (!element.ApplicationNodes.Contains(app))
{
element.AddNode(app);
}
}
return list;
}
EDIT: file is not null, the list is empty but not null
EDIT2: Operator and FileDetail details
public class FileDetails
{
internal string FileName { get; private set; }
internal string Name { get; private set;}
internal string Endung { get; private set; }
internal string Version { get; private set; }
internal string Produkt { get; private set; }
internal string ProduktVersion { get; private set; }
internal FileTyp Filetyp { get; private set; }
internal string Pfad { get; private set; }
public static bool operator==(FileDetails file1, Node_Library library)
{
return
file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName;
}
public static bool operator !=(FileDetails file1, Node_Library library)
{
return
!(file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName);
}
public static bool operator ==(FileDetails file1, FileDetails file2)
{
if (
file1.FileName == file2.FileName &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return true;
return false;
}
public static bool operator !=(FileDetails file1, FileDetails file2)
{
if (
file1.Name == file2.Name &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return false;
return true;
}
internal bool Equals(Node_Library file2)
{
if (file2 == null)
{
return false;
}
return (
Name == file2.Name &&
Produkt == file2.Produkt &&
ProduktVersion == file2.ProduktVersion &&
Version == file2.Version);
}
//More Stuff
}
EDIT3:
I used a breakpoint in my equal overload, but it never triggered... So the problem is maybe the FirstOrDefault?
finally:
Operatoroverload was faulty. Fixed it. Ty a lot.
The problem lies in your operators:
public static bool operator==(FileDetails file1, Node_Library library)
{
return
file1.Version == library.Version &&
file1.Produkt == library.Produkt &&
file1.ProduktVersion == library.ProduktVersion &&
file1.FileName == library.FileName;
}
When you compare an instance to null it's trying to access the properties Version, Produkt, ProduktVersion and FileName from a null instance, hence the NullReferenceException.
So, answering to your initial question "Why can a simple null check fail at this Point?", it's because there's nothing simple about that null check once you override the operators. =D
To solve it, you can add a null check on file2:
public static bool operator ==(FileDetails file1, FileDetails file2)
{
if (file2 != null &&
file1.FileName == file2.FileName &&
file1.Produkt == file2.Produkt &&
file1.ProduktVersion == file2.ProduktVersion &&
file1.Version == file2.Version)
return true;
return false;
}
The problem may be the previous line:
var element = list.FirstOrDefault(x => file.Equals(x));
The file parameter is probably null.
EDIT: If file is not null, then the FileDetails.Equals method can be the culprit.

Session object is working on localhost but fails on server

I have created a SessionManager class in my MVC 5 Web application to maintain session for the application. This class works fine on localhost but failes on server. Here is my SessionManager class code:
public class SessionManager : BaseController
{
private HttpContext _context;
public SessionManager()
{
//TODO:
}
public SessionManager(HttpContext context)
{
_context = context;
}
private RAWOnlineDBEntities db = new RAWOnlineDBEntities();
private string _FromMailID = string.Empty;
private string _FromPassword = string.Empty;
private string _CompanyName = string.Empty;
private string _AdminEmailID = string.Empty;
public string FromMailID
{
get
{
if (_context != null && _context.Session != null)
{
if (_context.Session["FromMailID"] == null)
{
_context.Session["FromMailID"] = db.Users.Where(u => u.CompanyID == CompanyID && u.UserID == UserID && u.IsActive == true).Select(table => table.InternalMailID).FirstOrDefault();
}
}
//return _FromMailID = _context.Session["FromMailID"].ToString(); // localhost
// Server
return _FromMailID = db.Users.Where(u => u.CompanyID == CompanyID && u.UserID == UserID && u.IsActive == true).Select(table => table.InternalMailID).FirstOrDefault();
}
}
public string FromPassword
{
get
{
try
{
if (_context != null && _context.Session != null)
{
if (_context.Session["FromPassword"] == null)
{
_context.Session["FromPassword"] = db.Users.Where(u => u.CompanyID == CompanyID && u.UserID == UserID && u.IsActive == true).Select(table => table.InternalMailIDPassword).FirstOrDefault();
}
}
_FromPassword = _context.Session["FromPassword"].ToString();
}
catch (Exception ex)
{
//ErrorSignal.FromCurrentContext().Raise(ex); //ELMAH Signaling
IsSuccess = false;
ViewBag.ErrorMessage = "Transaction failed. Please try again. If problem persists, contact system administrator.";
ViewBag.InfoMessage = "";
// Handle exception here and Log Error to text file...
string sLogFilePath = Server.MapPath(#"~/ApplicationFiles/ErrorLog/ErrorLogFile.txt");
GeneralRepository.LogErrorToFile(ex, sLogFilePath, "FromPassword from session manager");
}
return _FromPassword;
}
}
public string CompanyName
{
get
{
if (_context != null && _context.Session != null)
{
if (_context.Session["CompanyName"] == null)
{
_context.Session["CompanyName"] = db.CompanyMasters.Where(u => u.CompanyID == CompanyID && u.IsActive == true).Select(table => table.CompanyName).FirstOrDefault();
}
}
return _CompanyName = _context.Session["CompanyName"].ToString();
}
}
public string AdminEmailID
{
get
{
if (_context != null && _context.Session != null)
{
if (_context.Session["AdminEmailID"] == null)
{
_context.Session["AdminEmailID"] = (from table in db.Users
where table.RoleID == ADMIN_ROLE
&& table.IsActive == true
&& table.UserName.ToUpper() == "ADMIN"
select table.EmailID).FirstOrDefault();
}
}
return _AdminEmailID = _context.Session["AdminEmailID"].ToString();
}
}
}
And I am calling this class like this in my controller action method...
System.Web.HttpContext currentContext = System.Web.HttpContext.Current;
SessionManager objSessionManager = new SessionManager(currentContext);
StringBuilder MsgBody = MakeMailBodyForReportCreated(objReportTransactionData);
EmailRepository.SendEmail(objSessionManager.FromMailID, objSessionManager.FromPassword, ToMailAddress, CCMailAddress, MsgSubject, MsgBody.ToString());
and here is my web.config file
<sessionState mode="InProc" timeout="20"></sessionState>
<pages validateRequest="false" enableSessionState="true" />
<modules>
<remove name="Session" />
<add name="Session" type="System.Web.SessionState.SessionStateModule" />
</modules>
Please help...

Comparing (specific) object properties in c#

Building upon this answer for comparing objects in C#
Comparing object properties in c#
Knowing this is a complex topic, I wanted to handle a few more specific structures.
While this code will match properties if they are simple value types such as this object:
public class BasicStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
}
But as soon as it gets any more complex, this code fails.
So what I would like to do is make it a bit more usable for nested objects of the above, such as:
public class NestedStuff
{
public BasicStuff theBasic { get; set; }
}
Any array of the above, such as:
public class ArrayStuff
{
public BasicStuff[] theBasicArray { get; set; }
}
And finally any combination of the above:
public class AllTheStuff
{
public int anInt { get; set; }
public bool aBool { get; set; }
public BasicStuff theBasic { get; set; }
public BasicStuff[] theBasicArray { get; set; }
}
So what I came up with was the following:
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
string t = AValue.GetType().ToString();
if (!AllPublicPropertiesEqual<object>(AValue, BValue))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual<object>(BValue, AValue))
return false;
}
else
{
object selfValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object toValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (selfValue != toValue && (selfValue == null || !selfValue.Equals(toValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
Only this fails because when recursively calling AllPublicPropertiesEqual, I need to pass the specific values type rather than just a generic object type.
But I dont know how to do this.... Any ideas are greatly appreciated...
Your method does not have to be generic. You can change the beginning of the method to:
public static bool AllPublicPropertiesEqual(object AObj, object BObj, params string[] ignore)
{
if (AObj != null && BObj != null)
{
Type type = AObj.GetType();
if (BObj.GetType() != type)
throw new Exception("Objects should be of the same type");
....
}
....
}
Well first thing what is that you should create Interface for those classes because from what I see you can combine those classes but all of them will have the same properties. Second option is create some Base abstract class with those properties and inherit from it. It is up to you what you choose.
Than create in this Base class or Interface Equals functions where you will equal directly the shared properties it is much easier and I think more efficient :-)
public abstract class BaseStaff {
public int anInt { get; set; }
public bool aBool { get; set; }
public abstract bool Equals(BaseStaff anotherStaff);
}
Then you can use this class and create your BasicStaff class and AllTheStaff class too in BasicStaff implement Equals method like this.
public override bool Equals(BaseStaff staff) {
this.anInt == staff.anInt &&
this.aBool == staff.aBool;
}
In AllTheStaff u can than override this method like this
public override bool Equals(BaseStaff staff) {
bool baseEquals = base.Equals(staff);
bool basicStaffEquals = this.BasicStaff.Equals(staff);
return baseEquals || basicStaffEquals;
}
This is just core idea and maybe I dont understand you well what you really want to achieve but hope it helps you :)
tested Solution
public static bool AllPublicPropertiesEqual<T>(T AObj, T BObj, params string[] ignore) where T : class
{
if (AObj != null && BObj != null)
{
Type type = typeof(T);
List<string> ignoreList = new List<string>(ignore);
foreach (PropertyInfo pInfo in type.GetCType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
if (!ignoreList.Contains(pInfo.Name))
{
if (pInfo.PropertyType.IsArray)
{
object aElementValues = (type.GetProperty(pInfo.Name).GetValue(AObj, null));
object bElementValues = (type.GetProperty(pInfo.Name).GetValue(BObj, null));
if (aElementValues != null && bElementValues != null)
{
List<object> AListValues = new List<object>();
List<object> BListValues = new List<object>();
foreach (var v in (IEnumerable)aElementValues)
AListValues.Add(v);
foreach (var v in (IEnumerable)bElementValues)
BListValues.Add(v);
if (AListValues.Count == BListValues.Count)
{
object[] aArray = AListValues.ToArray();
object[] bArray = BListValues.ToArray();
for (int i = 0; i < aArray.Length; i++)
{
if (!AllPublicPropertiesEqual(aArray[i], bArray[i]))
return false;
}
}
else
return false;
}
else if ((aElementValues == null) != (bElementValues == null))
return false;
}
else if (!pInfo.PropertyType.IsValueType && !pInfo.PropertyType.IsPrimitive && !pInfo.PropertyType.IsEnum && pInfo.PropertyType != typeof(string))
//else if (Convert.GetTypeCode(pInfo.PropertyType) == TypeCode.Object)
{
object AObjectValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object BObjectValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (!AllPublicPropertiesEqual(BObjectValue, AObjectValue))
return false;
}
else
{
object aValue = type.GetProperty(pInfo.Name).GetValue(AObj, null);
object bValue = type.GetProperty(pInfo.Name).GetValue(BObj, null);
if (aValue != bValue && (aValue == null || !aValue.Equals(bValue)))
return false;
}
}
}
return true;
}
return AObj == BObj;
}
}

Categories

Resources