This commit is contained in:
@@ -78,12 +78,10 @@ namespace AyaNova.Api.Controllers
|
|||||||
if (o == null)
|
if (o == null)
|
||||||
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND));
|
||||||
|
|
||||||
bool IsOutsideUser = (o.UserType == UserType.Customer || o.UserType == UserType.HeadOffice);
|
if (o.IsOutsideUser && !AllowedOutsideUser)
|
||||||
|
|
||||||
if (IsOutsideUser && !AllowedOutsideUser)
|
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
|
|
||||||
if (!IsOutsideUser && !AllowedInsideUser)
|
if (!o.IsOutsideUser && !AllowedInsideUser)
|
||||||
return StatusCode(403, new ApiNotAuthorizedResponse());
|
return StatusCode(403, new ApiNotAuthorizedResponse());
|
||||||
|
|
||||||
return Ok(ApiOkResponse.Response(o));
|
return Ok(ApiOkResponse.Response(o));
|
||||||
|
|||||||
@@ -115,18 +115,28 @@ namespace AyaNova.Biz
|
|||||||
//CREATE
|
//CREATE
|
||||||
internal async Task<dtUser> CreateAsync(User newObject)
|
internal async Task<dtUser> CreateAsync(User newObject)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
//Also used for Contacts (customer type user or ho type user)
|
||||||
|
//by users with no User right but with Customer rights so need to double check here
|
||||||
|
if (
|
||||||
|
(newObject.IsOutsideUser && !Authorized.HasCreateRole(CurrentUserRoles, AyaType.Customer)) ||
|
||||||
|
(!newObject.IsOutsideUser && !Authorized.HasCreateRole(CurrentUserRoles, AyaType.User))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//password and login are optional but in the sense that they can be left out in a PUT
|
//password and login are optional but in the sense that they can be left out in a PUT
|
||||||
// but if left out here we need to generate a random value instead so they can't login but the code is happy
|
// but if left out here we need to generate a random value instead so they can't login but the code is happy
|
||||||
//because a login name and password are required always
|
//because a login name and password are required always
|
||||||
if (string.IsNullOrWhiteSpace(newObject.Password))
|
if (string.IsNullOrWhiteSpace(newObject.Password))
|
||||||
{
|
|
||||||
newObject.Password = Hasher.GenerateSalt();//set it to some big random value
|
newObject.Password = Hasher.GenerateSalt();//set it to some big random value
|
||||||
}
|
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(newObject.Login))
|
if (string.IsNullOrWhiteSpace(newObject.Login))
|
||||||
{
|
|
||||||
newObject.Login = Hasher.GenerateSalt();//set it to some big random value
|
newObject.Login = Hasher.GenerateSalt();//set it to some big random value
|
||||||
}
|
|
||||||
|
|
||||||
//This is a new user so it will have been posted with a password in plaintext which needs to be salted and hashed
|
//This is a new user so it will have been posted with a password in plaintext which needs to be salted and hashed
|
||||||
newObject.Salt = Hasher.GenerateSalt();
|
newObject.Salt = Hasher.GenerateSalt();
|
||||||
@@ -173,6 +183,18 @@ namespace AyaNova.Biz
|
|||||||
AddError(ApiErrorCode.NOT_FOUND, "id");
|
AddError(ApiErrorCode.NOT_FOUND, "id");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Also used for Contacts (customer type user or ho type user)
|
||||||
|
//by users with no User right but with Customer rights so need to double check here
|
||||||
|
if (
|
||||||
|
(dbObject.IsOutsideUser && !Authorized.HasCreateRole(CurrentUserRoles, AyaType.Customer)) ||
|
||||||
|
(!dbObject.IsOutsideUser && !Authorized.HasCreateRole(CurrentUserRoles, AyaType.User))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
User newObject = new User();
|
User newObject = new User();
|
||||||
CopyObject.Copy(dbObject, newObject, "Id, Salt, Login, Password, CurrentAuthToken, DlKey, DlKeyExpire, Wiki, Serial");
|
CopyObject.Copy(dbObject, newObject, "Id, Salt, Login, Password, CurrentAuthToken, DlKey, DlKeyExpire, Wiki, Serial");
|
||||||
string newUniqueName = string.Empty;
|
string newUniqueName = string.Empty;
|
||||||
@@ -236,6 +258,18 @@ namespace AyaNova.Biz
|
|||||||
AddError(ApiErrorCode.NOT_FOUND, "id");
|
AddError(ApiErrorCode.NOT_FOUND, "id");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
//Also used for Contacts (customer type user or ho type user)
|
||||||
|
//by users with no User right but with Customer rights so need to double check here
|
||||||
|
if (
|
||||||
|
(dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.Customer)) ||
|
||||||
|
(!dbObject.IsOutsideUser && !Authorized.HasModifyRole(CurrentUserRoles, AyaType.User))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
User SnapshotOfOriginalDBObj = new User();
|
User SnapshotOfOriginalDBObj = new User();
|
||||||
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
CopyObject.Copy(dbObject, SnapshotOfOriginalDBObj);
|
||||||
CopyObject.Copy(putObject, dbObject, "Id, Salt, CurrentAuthToken, LoginKey, DlKey, DlKeyExpire");
|
CopyObject.Copy(putObject, dbObject, "Id, Salt, CurrentAuthToken, LoginKey, DlKey, DlKeyExpire");
|
||||||
@@ -398,12 +432,25 @@ namespace AyaNova.Biz
|
|||||||
internal async Task<bool> DeleteAsync(long id)
|
internal async Task<bool> DeleteAsync(long id)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
using (var transaction = await ct.Database.BeginTransactionAsync())
|
using (var transaction = await ct.Database.BeginTransactionAsync())
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id);
|
User dbObject = await ct.User.SingleOrDefaultAsync(z => z.Id == id);
|
||||||
|
if (dbObject == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Also used for Contacts (customer type user or ho type user)
|
||||||
|
//by users with no User right but with Customer rights so need to double check here
|
||||||
|
if (
|
||||||
|
(dbObject.IsOutsideUser && !Authorized.HasDeleteRole(CurrentUserRoles, AyaType.Customer)) ||
|
||||||
|
(!dbObject.IsOutsideUser && !Authorized.HasDeleteRole(CurrentUserRoles, AyaType.User))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
await ValidateCanDelete(dbObject);
|
await ValidateCanDelete(dbObject);
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
return false;
|
return false;
|
||||||
@@ -448,12 +495,25 @@ namespace AyaNova.Biz
|
|||||||
private async Task ValidateAsync(User proposedObj, User currentObj)
|
private async Task ValidateAsync(User proposedObj, User currentObj)
|
||||||
{
|
{
|
||||||
//skip validation if seeding
|
//skip validation if seeding
|
||||||
if(ServerBootConfig.SEEDING) return;
|
if (ServerBootConfig.SEEDING) return;
|
||||||
|
|
||||||
//run validation and biz rules
|
//run validation and biz rules
|
||||||
bool isNew = currentObj == null;
|
bool isNew = currentObj == null;
|
||||||
|
|
||||||
|
//UserType change has Inside / Outside role implications
|
||||||
|
//a user attempting to change a UserType between inside or outside status must have the correct rights
|
||||||
|
//to *BOTH* Customer and User since it's affecting both types
|
||||||
|
if (currentObj.IsOutsideUser != proposedObj.IsOutsideUser)
|
||||||
|
{
|
||||||
|
//only can change if have both rights
|
||||||
|
if (
|
||||||
|
!Authorized.HasModifyRole(CurrentUserRoles, AyaType.User) ||
|
||||||
|
!Authorized.HasModifyRole(CurrentUserRoles, AyaType.Customer)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AddError(ApiErrorCode.NOT_AUTHORIZED, "UserType");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//do we need to check the license situation?
|
//do we need to check the license situation?
|
||||||
if (proposedObj.IsTech && proposedObj.Active)
|
if (proposedObj.IsTech && proposedObj.Active)
|
||||||
|
|||||||
@@ -35,6 +35,14 @@ namespace AyaNova.Models
|
|||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public AyaType AyaType { get => AyaType.User; }
|
public AyaType AyaType { get => AyaType.User; }
|
||||||
|
|
||||||
|
public bool IsOutsideUser
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.UserType == UserType.Customer || this.UserType == UserType.HeadOffice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// [JsonIgnore]//hide from being returned (as null anyway) with User object in routes
|
// [JsonIgnore]//hide from being returned (as null anyway) with User object in routes
|
||||||
// public UserOptions UserOptions { get; set; }
|
// public UserOptions UserOptions { get; set; }
|
||||||
}//eoc
|
}//eoc
|
||||||
@@ -114,6 +122,15 @@ namespace AyaNova.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsOutsideUser
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.UserType == UserType.Customer || this.UserType == UserType.HeadOffice;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
[NotMapped, JsonIgnore]
|
[NotMapped, JsonIgnore]
|
||||||
public AyaType AyaType { get => AyaType.User; }
|
public AyaType AyaType { get => AyaType.User; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user