diff --git a/server/AyaNova/Controllers/UserController.cs b/server/AyaNova/Controllers/UserController.cs
index 9c8b3732..3031eca1 100644
--- a/server/AyaNova/Controllers/UserController.cs
+++ b/server/AyaNova/Controllers/UserController.cs
@@ -86,6 +86,7 @@ namespace AyaNova.Api.Controllers
///
/// Put (update) User
+ /// (Login and / or Password are not changed if set to null / omitted)
///
///
///
diff --git a/server/AyaNova/biz/BizRoles.cs b/server/AyaNova/biz/BizRoles.cs
index 46a4ccd3..a55520cf 100644
--- a/server/AyaNova/biz/BizRoles.cs
+++ b/server/AyaNova/biz/BizRoles.cs
@@ -432,7 +432,7 @@ namespace AyaNova.Biz
//throw new System.ArgumentException("BizRoles::Constructor - roles were modified from last snapshot for client!!!");
// log =
{
- ((ILogger)AyaNova.Util.ApplicationLogging.CreateLogger("BizRoles.cs")).LogError("BizRoles::Constructor - roles were modified from last snapshot for client!!!");
+ ((ILogger)AyaNova.Util.ApplicationLogging.CreateLogger("BizRoles.cs")).LogWarning("BizRoles::Constructor - roles were modified from last snapshot for client!!!");
}
}
diff --git a/server/AyaNova/biz/UserBiz.cs b/server/AyaNova/biz/UserBiz.cs
index 352e4b36..cb821e24 100644
--- a/server/AyaNova/biz/UserBiz.cs
+++ b/server/AyaNova/biz/UserBiz.cs
@@ -49,6 +49,19 @@ namespace AyaNova.Biz
//CREATE
internal async Task CreateAsync(User inObj)
{
+ //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
+ //because a login name and password are required always
+ if (string.IsNullOrWhiteSpace(inObj.Password))
+ {
+ inObj.Password = Hasher.GenerateSalt();//set it to some big random value
+ }
+
+ if (string.IsNullOrWhiteSpace(inObj.Login))
+ {
+ inObj.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
inObj.Salt = Hasher.GenerateSalt();
inObj.Password = Hasher.hash(inObj.Salt, inObj.Password);
@@ -88,6 +101,10 @@ namespace AyaNova.Biz
//TAGS
await TagUtil.ProcessUpdateTagsInRepositoryAsync(ct, inObj.Tags, null);
+ //Accept, but never return a User's password or login
+ inObj.Password = null;
+ inObj.Login = null;
+
return inObj;
}
@@ -128,6 +145,7 @@ namespace AyaNova.Biz
dbObj.Tags = TagUtil.NormalizeTags(dbObj.Tags);
dbObj.CustomFields = JsonUtil.CompactJson(dbObj.CustomFields);
+ //NOTE: It's valid to call this without intending to change login or password (null values)
//Is the user updating the password?
if (!string.IsNullOrWhiteSpace(inObj.Password) && SnapshotOfOriginalDBObj.Password != inObj.Password)
{
@@ -140,6 +158,17 @@ namespace AyaNova.Biz
dbObj.Password = SnapshotOfOriginalDBObj.Password;
dbObj.Salt = SnapshotOfOriginalDBObj.Salt;
}
+ //Updating login?
+ if (!string.IsNullOrWhiteSpace(inObj.Login))
+ {
+ //YES Login is being updated:
+ dbObj.Login=inObj.Login;
+ }
+ else
+ {
+ //No, use the original value
+ dbObj.Login = SnapshotOfOriginalDBObj.Login;
+ }
//Set "original" value of concurrency token to input token
@@ -183,6 +212,18 @@ namespace AyaNova.Biz
dbObj.Password = Hasher.hash(dbObj.Salt, dbObj.Password);
}
+ //Updating login?
+ if (!string.IsNullOrWhiteSpace(dbObj.Login) && dbObj.Login != SnapshotOfOriginalDBObj.Login)
+ {
+ //YES Login is being updated:
+ dbObj.Login=SnapshotOfOriginalDBObj.Login;
+ }
+ else
+ {
+ //No, use the original value
+ dbObj.Login = SnapshotOfOriginalDBObj.Login;
+ }
+
ct.Entry(dbObj).OriginalValues["ConcurrencyToken"] = concurrencyToken;
await ValidateAsync(dbObj, SnapshotOfOriginalDBObj);
if (HasErrors)
diff --git a/server/AyaNova/models/AyContext.cs b/server/AyaNova/models/AyContext.cs
index 05c69569..aa9068c1 100644
--- a/server/AyaNova/models/AyContext.cs
+++ b/server/AyaNova/models/AyContext.cs
@@ -5,11 +5,13 @@ namespace AyaNova.Models
{
public partial class AyContext : DbContext
{
+ public virtual DbSet User { get; set; }
+ public virtual DbSet UserOptions { get; set; }
public virtual DbSet Widget { get; set; }
public virtual DbSet GlobalBizSettings { get; set; }
public virtual DbSet Event { get; set; }
public virtual DbSet SearchDictionary { get; set; }
- public virtual DbSet SearchKey { get; set; }
+ public virtual DbSet SearchKey { get; set; }
public virtual DbSet FileAttachment { get; set; }
public virtual DbSet OpsJob { get; set; }
public virtual DbSet OpsJobLog { get; set; }
@@ -19,8 +21,6 @@ namespace AyaNova.Models
public virtual DbSet Tag { get; set; }
public virtual DbSet FormCustom { get; set; }
public virtual DbSet PickListTemplate { get; set; }
- public virtual DbSet User { get; set; }
- public virtual DbSet UserOptions { get; set; }
public virtual DbSet License { get; set; }
public virtual DbSet Customer { get; set; }
public virtual DbSet Contract { get; set; }
diff --git a/server/AyaNova/models/User.cs b/server/AyaNova/models/User.cs
index c8ee0bb9..ea7dc015 100644
--- a/server/AyaNova/models/User.cs
+++ b/server/AyaNova/models/User.cs
@@ -15,9 +15,9 @@ namespace AyaNova.Models
public bool Active { get; set; }
[Required, MaxLength(255)]
public string Name { get; set; }
- [Required]
+ //[Required]
public string Login { get; set; }
- [Required]
+ //[Required]
public string Password { get; set; }
public string Salt { get; set; }
[Required]
diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs
index a0a6a3bd..22bc8b77 100644
--- a/server/AyaNova/util/AySchema.cs
+++ b/server/AyaNova/util/AySchema.cs
@@ -181,7 +181,7 @@ namespace AyaNova.Util
await ExecQueryAsync("CREATE TABLE auseroptions (id BIGSERIAL PRIMARY KEY, " +
"userid bigint not null, translationid bigint not null REFERENCES atranslation (id), languageoverride text, timezoneoverride text, currencyname text, hour12 bool not null, emailaddress text, uicolor varchar(12) not null default '#000000')");
-
+
//Prime the db with the default MANAGER account
await AyaNova.Biz.PrimeData.PrimeManagerAccount(ct);
@@ -454,7 +454,7 @@ namespace AyaNova.Util
await ExecQueryAsync("CREATE UNIQUE INDEX apmtemplateitem_name_id_idx ON apmtemplateitem (id, name);");
await ExecQueryAsync("CREATE INDEX apmtemplateitem_tags ON apmtemplateitem using GIN(tags)");
-
+
await SetSchemaLevelAsync(++currentSchema);
}
diff --git a/server/AyaNova/util/DbUtil.cs b/server/AyaNova/util/DbUtil.cs
index 24e4ab05..3059f66e 100644
--- a/server/AyaNova/util/DbUtil.cs
+++ b/server/AyaNova/util/DbUtil.cs
@@ -293,7 +293,7 @@ namespace AyaNova.Util
//REMOVE ALL DATA with few exceptions of manager user, license, schema tables
//and job logs because this is called by job code
-
+
await EraseTableAsync("atranslationitem", conn);
await EraseTableAsync("atranslation", conn);
//Load the default TRANSLATIONS
@@ -353,7 +353,7 @@ namespace AyaNova.Util
using (var cmd = new Npgsql.NpgsqlCommand())
{
cmd.Connection = conn;
- cmd.CommandText = "TRUNCATE \"" + sTable + "\" RESTART IDENTITY CASCADE;";
+ cmd.CommandText = "TRUNCATE \"" + sTable + "\" RESTART IDENTITY;";
await cmd.ExecuteNonQueryAsync();
}
}