Book appointment
This commit is contained in:
parent
a107386ecd
commit
c3c09f8966
|
@ -22,6 +22,12 @@ namespace FIT5032_Assignment {
|
|||
url: "{controller}/{action}/{id}",
|
||||
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
|
||||
routes.MapRoute(
|
||||
name: "Appointments",
|
||||
url: "Appointments",
|
||||
defaults: new { controller = "Appointments", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,12 +7,93 @@ using System.Web.Mvc;
|
|||
using FIT5032_Assignment.Models;
|
||||
using System.Data.Entity;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Text;
|
||||
using Org.BouncyCastle.Crypto;
|
||||
using Org.BouncyCastle.OpenSsl;
|
||||
using Org.BouncyCastle.Security;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Globalization;
|
||||
|
||||
namespace FIT5032_Assignment.Controllers {
|
||||
public class AppointmentsController : Controller {
|
||||
private Database1Entities db = new Database1Entities();
|
||||
|
||||
// Login check
|
||||
private static RsaSecurityKey LoadRsaSecurityKeyFromPem(string pem) {
|
||||
TextReader textReader = new StringReader(pem);
|
||||
PemReader pemReader = new PemReader(textReader);
|
||||
AsymmetricKeyParameter keyParameter = (AsymmetricKeyParameter)pemReader.ReadObject();
|
||||
|
||||
RSAParameters rsaParameters = DotNetUtilities.ToRSAParameters((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keyParameter);
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
rsa.ImportParameters(rsaParameters);
|
||||
|
||||
return new RsaSecurityKey(rsa);
|
||||
}
|
||||
private String psgCredentialVerify(string token) {
|
||||
|
||||
var jwtHandler = new JwtSecurityTokenHandler();
|
||||
var jwtToken = jwtHandler.ReadJwtToken(token);
|
||||
|
||||
string base64Publickey = "LS0tLS1CRUdJTiBSU0EgUFVCTElDIEtFWS0tLS0tCk1JSUJDZ0tDQVFFQTRUWEQwVEh4NnJjNXlQcXM0Skw5M01nVEgvTS95Z2s3V1pYWWsrS01XTTA0bDdzM3owRlMKODlDRE56SFJkbVpJb3RCbDgrcUJ5TUwvck5VcUhXMnJ1Uzg0dmxFaWdza2djK2RsaitCZXFsaGsySFRpQitpegpQcGdCU1FJc2YrZjdSU3dkYktFS2hRQm1La3MxVGF4YWNDUndPVWJKT1VQbjJXZmhVSHhRd0FwZGNCQWdNdHVNCld3QzJZRThGblFRZDhxc3dMTTBGQWhoSzUrdXRXY0s0bHdCVlFxUGJRaUJZYnZmWXkwYVF6UFB2V2NMR1JvR00KUVA1b1JCTmRuRzQ4Sm9Eb2tCSEJkbCt4RzM1L1U2N1BvejFKY0VVSnpWTHdIUFNHa0xyRU1OYlFrbnJSK2tHZwpnS1dWNFpvYWVOSHZVeFE3YVg3SElFMlc1UnIwRmxGUG1RSURBUUFCCi0tLS0tRU5EIFJTQSBQVUJMSUMgS0VZLS0tLS0K";
|
||||
RsaSecurityKey rsaKey = LoadRsaSecurityKeyFromPem(Encoding.UTF8.GetString(Convert.FromBase64String(base64Publickey)));
|
||||
// Valid time 3600s
|
||||
var validationParameters = new TokenValidationParameters() {
|
||||
ValidIssuer = "https://auth.passage.id/v1/apps/ZHM5whW5xsZEczTn2loffzjN",
|
||||
ValidateAudience = false,
|
||||
IssuerSigningKey = rsaKey,
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.FromSeconds(3600)
|
||||
};
|
||||
|
||||
try {
|
||||
var claimsPrincipal = jwtHandler.ValidateToken(token, validationParameters, out var rawValidatedToken);
|
||||
} catch (SecurityTokenExpiredException) {
|
||||
Trace.WriteLine("Token has expired");
|
||||
return null;
|
||||
} catch (SecurityTokenInvalidSignatureException) {
|
||||
Trace.WriteLine("Token has invalid signature");
|
||||
return null;
|
||||
} catch (SecurityTokenInvalidIssuerException) {
|
||||
Trace.WriteLine("Token has invalid issuer");
|
||||
return null;
|
||||
} catch (SecurityTokenInvalidAudienceException) {
|
||||
Trace.WriteLine("Token has invalid audience");
|
||||
return null;
|
||||
} catch (SecurityTokenValidationException) {
|
||||
Trace.WriteLine("Token failed validation");
|
||||
return null;
|
||||
} catch (ArgumentException) {
|
||||
Trace.WriteLine("Token was empty or null");
|
||||
return null;
|
||||
}
|
||||
|
||||
string sub = jwtToken.Claims.First(claim => claim.Type == "sub").Value;
|
||||
|
||||
return sub;
|
||||
}
|
||||
private Users loginInfo(string user) {
|
||||
var db = new Database1Entities();
|
||||
var credential = db.Credentials.Where(res => (res.uniqueIdCode == user) && (res.provider == 0));
|
||||
if (credential.Count() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
var userUuid = credential.First().user;
|
||||
var dbUser = db.Users.Where(res => res.uuid == userUuid);
|
||||
if (dbUser.Count() == 0) {
|
||||
return null;
|
||||
} else {
|
||||
return dbUser.First();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GET: Appointments
|
||||
public ActionResult Index() {
|
||||
ViewBag.tip = TempData["tip"];
|
||||
return View();
|
||||
}
|
||||
|
||||
|
@ -23,6 +104,10 @@ namespace FIT5032_Assignment.Controllers {
|
|||
|
||||
// GET: Appointments/Create
|
||||
public ActionResult Create(string id) {
|
||||
if (Request.Cookies["psg_auth_token"] == null) {
|
||||
// Redirect to home page
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
if (id == null) {
|
||||
// Pass a dropdown list for all doctors
|
||||
List<Doctors> doctors = db.Doctors.ToList();
|
||||
|
@ -44,15 +129,75 @@ namespace FIT5032_Assignment.Controllers {
|
|||
}
|
||||
|
||||
|
||||
// POST: Appointments/Create
|
||||
// POST: Appointments/Create/doctorId
|
||||
[HttpPost]
|
||||
public ActionResult Create(FormCollection collection) {
|
||||
try {
|
||||
// TODO: Add insert logic here
|
||||
Trace.WriteLine(collection["doctorUuid"]);
|
||||
|
||||
// Verify login
|
||||
if (Request.Cookies["psg_auth_token"] == null) {
|
||||
// Redirect to home page
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
Trace.WriteLine("User has cookie");
|
||||
var user = psgCredentialVerify(Request.Cookies["psg_auth_token"].Value);
|
||||
if (user == null) {
|
||||
// Redirect to home page
|
||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
Trace.WriteLine("User has login");
|
||||
var userProfile = loginInfo(user);
|
||||
if (userProfile == null) {
|
||||
// Redirect to home page, and remove cookies
|
||||
Response.Cookies["psg_auth_token"].Expires = DateTime.Now.AddDays(-1);
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
Trace.WriteLine("User login available");
|
||||
// Detect if user logined is patient
|
||||
if (userProfile.role != 1) {
|
||||
// Redirect to home page
|
||||
return Redirect("/Appointments/Index");
|
||||
}
|
||||
Trace.WriteLine("User is patient");
|
||||
|
||||
// Transfer MM/dd/yyyy (18/10/2023) to C# DateTime
|
||||
Trace.WriteLine(collection["appointmentDate"]);
|
||||
DateTime date = DateTime.ParseExact(collection["appointmentDate"], "dd/MM/yyyy", CultureInfo.InvariantCulture);
|
||||
Trace.WriteLine(date);
|
||||
|
||||
// The date cannot be earlier than today 0:00
|
||||
|
||||
if (date < DateTime.Today) {
|
||||
ViewBag.tip = "The date cannot be earlier than today.";
|
||||
ViewBag.doctorId = collection["doctorUuid"];
|
||||
ViewBag.doctorUser = db.Users.Find(collection["doctorUuid"]);
|
||||
return View();
|
||||
}
|
||||
|
||||
// Create appointment
|
||||
var uuid = Guid.NewGuid().ToString();
|
||||
Appointments appointment = new Appointments {
|
||||
uuid = uuid,
|
||||
patient = userProfile.uuid,
|
||||
responsibleBy = collection["doctorUuid"],
|
||||
createdAt = DateTime.Now,
|
||||
appointmentDate = date,
|
||||
status = 0,
|
||||
createdBy = 0
|
||||
};
|
||||
db.Appointments.Add(appointment);
|
||||
db.SaveChanges();
|
||||
|
||||
TempData["tip"] = "The appointment has been booked.";
|
||||
return Redirect("/Appointments/Index");
|
||||
}
|
||||
catch {
|
||||
ViewBag.tip = "System error";
|
||||
ViewBag.doctorId = collection["doctorUuid"];
|
||||
ViewBag.doctorUser = db.Users.Find(collection["doctorUuid"]);
|
||||
return View();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace FIT5032_Assignment.Controllers {
|
|||
public DbSet<Sessions> Sessions { get; set; }
|
||||
public DbSet<Patients> Patients { get; set; }
|
||||
public DbSet<Doctors> Doctors { get; set; }
|
||||
public DbSet<Appointments> Appointments { get; set; }
|
||||
}
|
||||
public class HomeController : Controller {
|
||||
public static string GetMd5Hash(string input) {
|
||||
|
|
|
@ -5,6 +5,12 @@
|
|||
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||
}
|
||||
|
||||
@if (ViewBag.tip != null) {
|
||||
<div class="alert alert-success" role="alert">
|
||||
@ViewBag.tip
|
||||
</div>
|
||||
}
|
||||
|
||||
<h2>Book an appointment</h2>
|
||||
|
||||
<hr />
|
||||
|
@ -32,11 +38,12 @@
|
|||
}
|
||||
} else {
|
||||
<h3>Book an appointment with @ViewBag.doctorUser.displayName</h3>
|
||||
<form>
|
||||
<form method="post">
|
||||
<input type="hidden" name="doctorUuid" value="@ViewBag.doctorUser.uuid" />
|
||||
<div class="form-group">
|
||||
<label for="datepicker">Select the appointment date</label>
|
||||
<div class='input-group'>
|
||||
<input data-provide="datepicker" id="datepicker" class="form-control" />
|
||||
<input data-provide="datepicker" id="datepicker" class="form-control" name="appointmentDate" />
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Submit</button>
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
Layout = "~/Views/Shared/_Layout.cshtml";
|
||||
}
|
||||
|
||||
@if (ViewBag.tip != null) {
|
||||
<div class="alert alert-success" role="alert">
|
||||
@ViewBag.tip
|
||||
</div>
|
||||
}
|
||||
|
||||
<h2>Appointments</h2>
|
||||
|
||||
<ul>
|
||||
|
|
Loading…
Reference in New Issue
Block a user