diff --git a/.gitignore b/.gitignore index 2608a78..3ea5d77 100644 --- a/.gitignore +++ b/.gitignore @@ -260,4 +260,6 @@ paket-files/ __pycache__/ *.pyc -SeniorAssistant/SeniorAssistant/wwwroot/* \ No newline at end of file +SeniorAssistant/SeniorAssistant/wwwroot/* +/SeniorAssistant/Controllers/TestController.cs +/SeniorAssistant/Views/Test/* diff --git a/SeniorAssistant/Controllers/AccountController.cs b/SeniorAssistant/Controllers/AccountController.cs index f7ebed2..c7d8ef1 100644 --- a/SeniorAssistant/Controllers/AccountController.cs +++ b/SeniorAssistant/Controllers/AccountController.cs @@ -4,7 +4,8 @@ using SeniorAssistant.Models; using SeniorAssistant.Controllers; using LinqToDB; using System.Linq; -using System.Collections.Generic; +using System; +using SeniorAssistant.Models.Users; namespace IdentityDemo.Controllers { @@ -12,6 +13,8 @@ namespace IdentityDemo.Controllers [Route("[controller]/[action]")] public class AccountController : BaseController { + private readonly JsonResponse OkJson = new JsonResponse(); + [HttpPost] public ActionResult _login(string username, string password) { @@ -26,15 +29,20 @@ namespace IdentityDemo.Controllers if (result.Count == 1) { var loggedUser = HttpContext.Session.GetString(Username); - if (loggedUser==null || !loggedUser.Equals(username)) + if (loggedUser==null || !loggedUser.Equals(username)) // non ha senso { User user = result.First(); HttpContext.Session.SetString(Username, username); HttpContext.Session.SetString("email", user.Email); HttpContext.Session.SetString("name", user.Name); - HttpContext.Session.SetString("role", user.Role); //HttpContext.Session.SetString("lastname", user.LastName); + + var isDoc = (from d in Db.Doctors + where d.Username.Equals(username) + select d).ToArray().FirstOrDefault() != null; + HttpContext.Session.SetString("role", isDoc? "doctor":"patient"); + response.Success = true; response.Message = Request.Query["ReturnUrl"]; } @@ -56,34 +64,109 @@ namespace IdentityDemo.Controllers [HttpPost] public ActionResult _register(User user) { - JsonResponse response = new JsonResponse() { Success = true }; - - if(ModelState.IsValid) + return Action(() => { try { Db.Insert(user); - _login(user.Username, user.Password); + return _login(user.Username, user.Password); } catch { - response.Success = false; - response.Message = "Username already exists"; + return Json(new JsonResponse(false, "Username already exists")); } - } - else - { - response.Success = false; - response.Message = "Modello non valido"; - } - - return Json(response); + }); } - internal class JsonResponse + [HttpPost] + public ActionResult _notification(string username, string message) { - public bool Success { get; internal set; } - public string Message { get; internal set; } + return LoggedAction(() => + { + Db.Insert(new Notification() + { + Message = message, + Username = username, + Time = DateTime.Now, + Seen = false + }); + return Json(OkJson); + }); + } + + [HttpPut] + public ActionResult _notification(int id) + { + return LoggedAction(() => + { + JsonResponse response = OkJson; + + Notification note = Db.Notifications.Where(n => n.Id == id).ToArray().FirstOrDefault(); + if(note != null) + { + note.Seen = true; + Db.Update(note); + } + else + { + response.Success = false; + response.Message = "La notifica da modificare non esiste"; + } + return Json(response); + }); + } + + [HttpPost] + public ActionResult _addDoc(string doctor) + { + return LoggedAction(() => + { + string username = HttpContext.Session.GetString(Username); + var isAlreadyPatient = Db.Patients.Where(p => p.Username.Equals(username)).ToArray().FirstOrDefault() != null; + if (isAlreadyPatient) + return Json(new JsonResponse() + { + Success = false, + Message = "You are already a patient" + }); + + var docExist = Db.Doctors.Where(d => d.Username.Equals(doctor)).ToArray().FirstOrDefault() != null; + if(!docExist) + return Json(new JsonResponse() + { + Success = false, + Message = "Doctor doesn't exist" + }); + + Db.Insert(new Patient() + { + Doctor = doctor, + Username = username + }); + + _notification(doctor, "L'utente "+username+" ti ha inserito come il suo dottore."); + return Json(new JsonResponse()); + }); + } + + [HttpPost] + public ActionResult _sendMessage(string reciver, string body) + { + return LoggedAction(() => { + string username = HttpContext.Session.GetString(Username); + Message message = new Message() + { + Reciver = reciver, + Body = body, + Time = DateTime.Now, + Username = username, + Seen = false + }; + + Db.Insert(message); + + return Json(new JsonResponse()); + }); } } } \ No newline at end of file diff --git a/SeniorAssistant/Controllers/HomeController.cs b/SeniorAssistant/Controllers/HomeController.cs index f83ab7a..daefdd2 100644 --- a/SeniorAssistant/Controllers/HomeController.cs +++ b/SeniorAssistant/Controllers/HomeController.cs @@ -1,6 +1,4 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc; namespace SeniorAssistant.Controllers { @@ -45,9 +43,15 @@ namespace SeniorAssistant.Controllers return CheckAuthorized("Data", user); } + [Route("Message/{Id}")] + public IActionResult Message(int id) + { + return CheckAuthorized("Message", id); + } + private IActionResult CheckAuthorized(string view, object model = null) { - if (HttpContext.Session.GetString("username") == null) + if (!IsLogged()) { model = "/" + view; view = "Index"; diff --git a/SeniorAssistant/Controllers/Services/ApiControllers.cs b/SeniorAssistant/Controllers/Services/ApiControllers.cs index 71414cf..7959e9b 100644 --- a/SeniorAssistant/Controllers/Services/ApiControllers.cs +++ b/SeniorAssistant/Controllers/Services/ApiControllers.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Mvc; using SeniorAssistant.Models; +using SeniorAssistant.Models.Users; namespace SeniorAssistant.Controllers.Services { @@ -18,4 +19,12 @@ namespace SeniorAssistant.Controllers.Services [Route("api/[controller]")] public class UserController : CrudController { } + + [Route("api/[controller]")] + public class PatientController : CrudController + { } + + [Route("api/[controller]")] + public class DoctorController : CrudController + { } } diff --git a/SeniorAssistant/Controllers/Services/BaseController.cs b/SeniorAssistant/Controllers/Services/BaseController.cs index 18bb5e4..0c963ad 100644 --- a/SeniorAssistant/Controllers/Services/BaseController.cs +++ b/SeniorAssistant/Controllers/Services/BaseController.cs @@ -1,11 +1,16 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using SeniorAssistant.Data; +using System.Linq; +using System; namespace SeniorAssistant.Controllers { public abstract class BaseController : Controller { + protected static readonly string MustBeLogged = "Devi essere loggato per vedere/modificare questo dato"; + protected static readonly string InvalidModel = "Modello non valido"; + protected static readonly string NoAuthorized = "Non sei autorizzato a vedere questi dati"; protected static readonly string Username = "username"; IDataContextFactory dbFactory; @@ -28,5 +33,63 @@ namespace SeniorAssistant.Controllers { return HttpContext.Session.GetString(Username) != null; } + + protected ActionResult Action(Func success) + { + return ModelState.IsValid ? + success.Invoke() : + Json(new JsonResponse() + { + Success = false, + Message = InvalidModel + }); + } + + protected ActionResult LoggedAction(Func success) + { + return Action(() => + { + return IsLogged() ? + success.Invoke() : + Json(new JsonResponse() + { + Success = false, + Message = MustBeLogged + }); + }); + } + + protected ActionResult LoggedAccessDataOf(string username, Func success) + { + return LoggedAction(() => + { + var loggedUser = HttpContext.Session.GetString(Username); + var condition = username.Equals(loggedUser); + + condition = condition || (from patient in Db.Patients + where patient.Doctor.Equals(loggedUser) && patient.Username.Equals(username) + select patient).ToArray().FirstOrDefault() != null; + + return condition ? + success.Invoke() : + Json(new JsonResponse() + { + Success = false, + Message = NoAuthorized + }); + }); + } + } + + public class JsonResponse + { + public JsonResponse(bool success=true, string message="") + { + Success = success; + Message = message; + } + + public bool Success { get; set; } + public string Message { get; set; } } } diff --git a/SeniorAssistant/Data/SeniorDataContext.cs b/SeniorAssistant/Data/SeniorDataContext.cs index 2a23935..027a32c 100644 --- a/SeniorAssistant/Data/SeniorDataContext.cs +++ b/SeniorAssistant/Data/SeniorDataContext.cs @@ -2,6 +2,7 @@ using LinqToDB.Data; using LinqToDB.DataProvider; using SeniorAssistant.Models; +using SeniorAssistant.Models.Users; namespace SeniorAssistant.Data { @@ -11,8 +12,13 @@ namespace SeniorAssistant.Data : base(dataProvider, connectionString) { } - public ITable User => GetTable(); - + public ITable Users => GetTable(); public ITable Heartbeats => GetTable(); + public ITable Sleeps => GetTable(); + public ITable Steps => GetTable(); + public ITable Doctors => GetTable(); + public ITable Patients => GetTable(); + public ITable Notifications => GetTable(); + public ITable Messages => GetTable(); } } diff --git a/SeniorAssistant/Models/Menu.cs b/SeniorAssistant/Models/Menu.cs index cafb8a2..cdd6e86 100644 --- a/SeniorAssistant/Models/Menu.cs +++ b/SeniorAssistant/Models/Menu.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using System.Collections.Generic; namespace SeniorAssistant.Models { @@ -12,8 +9,7 @@ namespace SeniorAssistant.Models public class MenuItem : IMenuItem { - public MenuItem(string text) : this(text, "#") { } - public MenuItem(string text, string href) + public MenuItem(string text, string href = "#") { Text = text; HRef = href; diff --git a/SeniorAssistant/Models/Message.cs b/SeniorAssistant/Models/Message.cs new file mode 100644 index 0000000..e76f056 --- /dev/null +++ b/SeniorAssistant/Models/Message.cs @@ -0,0 +1,26 @@ +using LinqToDB.Mapping; +using System; + +namespace SeniorAssistant.Models +{ + public class Message : IHasTime + { + [Column(IsPrimaryKey = true, CanBeNull = false, IsIdentity = true)] + public int Id { get; set; } + + [NotNull] + public DateTime Time { get; set; } + + [NotNull] + public string Username { get; set; } + + [NotNull] + public string Reciver { get; set; } + + [NotNull] + public string Body { get; set; } + + public bool Seen { get; set; } + + } +} diff --git a/SeniorAssistant/Models/Notification.cs b/SeniorAssistant/Models/Notification.cs new file mode 100644 index 0000000..b5c16a0 --- /dev/null +++ b/SeniorAssistant/Models/Notification.cs @@ -0,0 +1,21 @@ +using LinqToDB.Mapping; +using System; + +namespace SeniorAssistant.Models +{ + public class Notification : IHasTime + { + [Column(IsPrimaryKey = true, CanBeNull = false, IsIdentity = true)] + public int Id { get; set; } + + [NotNull] + public string Username { get; set; } + + [NotNull] + public DateTime Time { get; set; } + + public bool Seen { get; set; } + + public string Message { get; set; } + } +} diff --git a/SeniorAssistant/Models/Users/Doctor.cs b/SeniorAssistant/Models/Users/Doctor.cs new file mode 100644 index 0000000..f2f0a7a --- /dev/null +++ b/SeniorAssistant/Models/Users/Doctor.cs @@ -0,0 +1,17 @@ +using LinqToDB.Mapping; + +namespace SeniorAssistant.Models.Users +{ + public class Doctor : IHasUsername + { + [Column(IsPrimaryKey = true, CanBeNull = false)] + public string Username { get; set; } + + [Association(ThisKey = "Username", OtherKey = nameof(User.Username), CanBeNull = false)] + public User UserData { get; set; } + + public string Location { get; set; } + + public string Schedule { get; set; } + } +} diff --git a/SeniorAssistant/Models/Users/Patient.cs b/SeniorAssistant/Models/Users/Patient.cs new file mode 100644 index 0000000..6a326e9 --- /dev/null +++ b/SeniorAssistant/Models/Users/Patient.cs @@ -0,0 +1,18 @@ +using LinqToDB.Mapping; + +namespace SeniorAssistant.Models.Users +{ + public class Patient : IHasUsername + { + [Column(IsPrimaryKey = true, CanBeNull = false)] + public string Username { get; set; } + + [Association(ThisKey = "Username", OtherKey = nameof(User.Username), CanBeNull = false)] + public User UserData { get; set; } + + [NotNull] + public string Doctor { get; set; } + + public string Notes { get; set; } + } +} diff --git a/SeniorAssistant/Models/User.cs b/SeniorAssistant/Models/Users/User.cs similarity index 82% rename from SeniorAssistant/Models/User.cs rename to SeniorAssistant/Models/Users/User.cs index 911c80d..98f56ba 100644 --- a/SeniorAssistant/Models/User.cs +++ b/SeniorAssistant/Models/Users/User.cs @@ -1,5 +1,4 @@ using LinqToDB.Mapping; -using Microsoft.AspNetCore.Identity; using Newtonsoft.Json; namespace SeniorAssistant.Models @@ -15,10 +14,7 @@ namespace SeniorAssistant.Models [NotNull] [JsonIgnore] public string Password { get; set; } - - [NotNull] - public string Role { get; set; } - + public string Name { get; set; } public string LastName { get; set; } diff --git a/SeniorAssistant/Startup.cs b/SeniorAssistant/Startup.cs index 892d040..cbf2c20 100644 --- a/SeniorAssistant/Startup.cs +++ b/SeniorAssistant/Startup.cs @@ -5,8 +5,6 @@ using LinqToDB.DataProvider.SQLite; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Authorization; -using Microsoft.Data.Sqlite; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using SeniorAssistant.Configuration; @@ -14,12 +12,8 @@ using SeniorAssistant.Data; using SeniorAssistant.Models; using SeniorAssistant.Extensions; using Swashbuckle.AspNetCore.Swagger; -using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Mvc.Authorization; -using Microsoft.AspNetCore.Mvc; +using SeniorAssistant.Models.Users; namespace SeniorAssistant { @@ -100,6 +94,7 @@ namespace SeniorAssistant services.AddSingleton>(dbFactory); SetupDatabase(dbFactory); + FillDatabase(dbFactory); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -144,47 +139,83 @@ namespace SeniorAssistant { using (var db = dataContext.Create()) { - const string baseUsername = "vecchio"; - string[] names = { "Mario", "Giovanni", "Aldo", "Giacomo", "Marcello", "Filippo" }; - db.CreateTableIfNotExists(); db.CreateTableIfNotExists(); db.CreateTableIfNotExists(); db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + db.CreateTableIfNotExists(); + } + } - int count = 0; - foreach (string user in names) + void FillDatabase(IDataContextFactory dataContext) + { + using (var db = dataContext.Create()) + { + Random rnd = new Random(); + + List users = new List(); + + List docs = db.Doctors.ToListAsync().Result; + if (docs.Count == 0) { - var username = baseUsername + count; - db.InsertOrReplace(new User { Role = "user", Name = user, Username = username, Password = username, Email = username + "@email.st" } ); - count++; + users.Add(new User { Name = "Alfredo", LastName = "Parise", Email = "alfred.pary@libero.it", Username = "alfredigno", Password = "alfy" }); + users.Add(new User { Name = "Edoardo", LastName = "Marzio", Email = "edo.marzio@libero.it", Username = "marzietto", Password = "edo64" }); + + docs.Add(new Doctor { Username = "alfredigno", Location = "Brasile" }); + docs.Add(new Doctor { Username = "marzietto", Location = "Uganda" }); + + foreach (var doc in docs) + db.InsertOrReplace(doc); } - Random rnd = new Random(); + List patients = db.Patients.ToListAsync().Result; + if (patients.Count == 0) + { + const string baseUsername = "vecchio"; + string[] names = { "Mario", "Giovanni", "Aldo", "Giacomo", "Marcello", "Filippo" }; + string[] lastnames = { "Rossi", "Storti", "Baglio", "Poretti", "Marcelli", "Martelli" }; + int count = 0; + for (count=0; count().MaxAsync(x => x.Time).Result; TimeSpan span = now.Subtract(maxTimeInDB); totalHours = span.TotalHours; - } catch { } - - for (int i = 0; i dbFactory @model string @{ ViewBag.Title = "Hello Razor"; var session = HttpContextAccessor.HttpContext.Session; + var username = session.GetString("username"); - // Questa variabile serve a sapere se si e' autorizzati o meno. - // Per ora e' semplice ma magari si puo' peggiorare utilizzando il ruolo di Doc... etc - // (Utilizzare inject DbContext) - bool auth = session.GetString("username").Equals(Model); + bool auth = username.Equals(Model); + if (session.GetString("role").Equals("doctor")) + { + var db = dbFactory.Create(); + var isDocPatient = (from p in db.Patients + where p.Username.Equals(Model) && p.Doctor.Equals(username) + select p).ToArray().FirstOrDefault() != null; + auth = auth || isDocPatient; + } } @if (!auth) @@ -18,90 +25,100 @@ else { // Aggiungere un qualcosa per scegliere le ore da vedere (Max 48?) -
+ + +
} \ No newline at end of file diff --git a/SeniorAssistant/Views/Home/Index.cshtml b/SeniorAssistant/Views/Home/Index.cshtml index 575a7f8..9157d25 100644 --- a/SeniorAssistant/Views/Home/Index.cshtml +++ b/SeniorAssistant/Views/Home/Index.cshtml @@ -31,6 +31,6 @@ se non loggato deve tornare qua } else { - await Html.RenderPartialAsync("Profile"); + await Html.RenderPartialAsync("Profile"); // magari sostituire qui } diff --git a/SeniorAssistant/Views/Home/Message.cshtml b/SeniorAssistant/Views/Home/Message.cshtml new file mode 100644 index 0000000..df40cae --- /dev/null +++ b/SeniorAssistant/Views/Home/Message.cshtml @@ -0,0 +1,30 @@ +@model int +@inject IHttpContextAccessor HttpContextAccessor +@inject IDataContextFactory dbFactory +@using LinqToDB; + +@{ + ViewBag.Title = "Hello Razor"; + string username = HttpContextAccessor.HttpContext.Session.GetString("username"); + var db = dbFactory.Create(); + var message = (from m in db.Messages + where m.Id.Equals(Model) && m.Reciver.Equals(username) + select m).ToArray().FirstOrDefault(); +} + +
+ @if (message == null) + { +

Non hai il permesso

+ } + else + { + message.Seen = true; + db.Update(message); +

Messaggio da @message.Username

+

Inviato il @message.Time

+
+ @message.Body +
+ } +
diff --git a/SeniorAssistant/Views/Home/Users.cshtml b/SeniorAssistant/Views/Home/Users.cshtml index 4c30ece..27fec0e 100644 --- a/SeniorAssistant/Views/Home/Users.cshtml +++ b/SeniorAssistant/Views/Home/Users.cshtml @@ -8,19 +8,11 @@ +} \ No newline at end of file diff --git a/SeniorAssistant/Views/Shared/Profile.cshtml b/SeniorAssistant/Views/Shared/Profile.cshtml index e3efdb8..57e8bb4 100644 --- a/SeniorAssistant/Views/Shared/Profile.cshtml +++ b/SeniorAssistant/Views/Shared/Profile.cshtml @@ -1,15 +1,162 @@ @inject IHttpContextAccessor HttpContextAccessor +@inject IDataContextFactory dbFactory @{ var session = HttpContextAccessor.HttpContext.Session; + var db = dbFactory.Create(); + var username = session.GetString("username"); + var patientData = db.Patients.Where(p => p.Username.Equals(username)).ToArray().FirstOrDefault(); + var hasDoc = patientData != null; }
-

- Welcome @session.GetString("username") +
+

+ Welcome @username +

+ name: @session.GetString("name")
+ lastname: @session.GetString("lastname")
+ email: @session.GetString("email")
+
-

- name: @session.GetString("name")
- lastname: @session.GetString("lastname")
- email: @session.GetString("email") +
+ @if (hasDoc) // is patient and has doc, must show doc data + { + var doctor = (from u in db.Users + join d in db.Doctors on u.Username equals d.Username + where d.Username.Equals(patientData.Doctor) + select new { u.Username, u.Name, u.LastName, d.Location }).ToArray().First(); + +

@doctor.Name @doctor.LastName

+

@doctor.Location

+ + +
+

Invia un messaggio al tuo dottore

+ + +

+ + +
+ } + else + { + dynamic[] data; + Type type = null; + string title = null; + var docData = db.Doctors.Where(d => d.Username.Equals(username)).ToArray().FirstOrDefault(); + + if (docData != null) // is DOC + { + // see all the patient of the doc + title = "Lista dei pazienti"; + var patients = (from u in db.Users + join p in db.Patients on u.Username equals p.Username + where p.Doctor.Equals(docData.Username) + select new { u.Username, u.Name, u.LastName, p.Notes, Profile = "Profile" }).ToArray(); + data = patients; + type = patients.FirstOrDefault().GetType(); + } + else // is a patient and need to choose a doctor + { + // choose which doc you want + title = "Scegli un Doc"; + var docs = (from u in db.Users + join d in db.Doctors on u.Username equals d.Username + select new { u.Username, u.Name, u.LastName, d.Location, Choose = "Scegli" }).ToArray(); + data = docs; + type = docs.FirstOrDefault().GetType(); + } + + var fields = new List(); + foreach (var field in type.GetProperties()) + { + fields.Add(field.Name); + } + +

@title

+
+ + } +
diff --git a/SeniorAssistant/Views/_ViewImports.cshtml b/SeniorAssistant/Views/_ViewImports.cshtml index e9b76c7..f4d06f3 100644 --- a/SeniorAssistant/Views/_ViewImports.cshtml +++ b/SeniorAssistant/Views/_ViewImports.cshtml @@ -1,3 +1,4 @@ -@using SeniorAssistant.Models +@using SeniorAssistant.Models; +@using SeniorAssistant.Data; @using Microsoft.AspNetCore.Mvc; @using Microsoft.AspNetCore.Http; \ No newline at end of file diff --git a/SeniorAssistant/senior.db b/SeniorAssistant/senior.db index d0030f8..084582b 100644 Binary files a/SeniorAssistant/senior.db and b/SeniorAssistant/senior.db differ