Create User
This commit is contained in:
parent
72b29d9c78
commit
fc38cb0651
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,3 +2,6 @@ bin
|
|||
obj
|
||||
/.vscode
|
||||
/.vs/FIT5032-Assignment
|
||||
packages/
|
||||
FIT5032-Assignment/App_Data/FIT5032_Assignment.mdf
|
||||
FIT5032-Assignment/App_Data/FIT5032_Assignment_log.ldf
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -20,11 +20,11 @@ namespace FIT5032_Assignment
|
|||
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
|
||||
);
|
||||
|
||||
/*routes.MapRoute(
|
||||
name: "Default",
|
||||
routes.MapRoute(
|
||||
name: "HomeAlternative",
|
||||
url: "{controller}/{action}/{id}",
|
||||
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
|
||||
);*/
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,27 @@ using System.Collections.Generic;
|
|||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Data.Entity;
|
||||
using FIT5032_Assignment.Models;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using BCryptNet = BCrypt.Net.BCrypt;
|
||||
|
||||
namespace FIT5032_Assignment.Controllers
|
||||
{
|
||||
public class HomeController : Controller
|
||||
{
|
||||
private Database1Entities db = new Database1Entities();
|
||||
|
||||
private string GenerateRandomString(int length)
|
||||
{
|
||||
const string validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
var rng = new RNGCryptoServiceProvider();
|
||||
var bytes = new byte[length];
|
||||
rng.GetBytes(bytes);
|
||||
return new string(bytes.Select(x => validChars[x % validChars.Length]).ToArray());
|
||||
}
|
||||
|
||||
public ActionResult Index()
|
||||
{
|
||||
return View();
|
||||
|
@ -18,8 +34,93 @@ namespace FIT5032_Assignment.Controllers
|
|||
return View();
|
||||
}
|
||||
|
||||
// POST /CreateAccount
|
||||
[HttpPost]
|
||||
public ActionResult CreateAccount(Models.CreateAccountForm model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
ModelState.AddModelError("emailaddress", "Form not valid");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// Email address is not valid
|
||||
// Use regular expression to verify email address
|
||||
if (!System.Text.RegularExpressions.Regex.IsMatch(model.emailaddress, @"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"))
|
||||
{
|
||||
ModelState.AddModelError("emailaddress", "Email address is not valid");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// If email address existed in database
|
||||
var users = db.Credentials.Where(res => (res.uniqueIdCode == model.emailaddress) && (res.provider == 0));
|
||||
if (users.Count() > 0)
|
||||
{
|
||||
ModelState.AddModelError("emailaddress", "Email address existed");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// MD5 hash email to get avatar from gravatar
|
||||
var md5 = MD5.Create();
|
||||
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(model.emailaddress);
|
||||
byte[] hash = md5.ComputeHash(inputBytes);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < hash.Length; i++)
|
||||
{
|
||||
sb.Append(hash[i].ToString("X2")); // X2 means uppercase
|
||||
}
|
||||
string avatarUrl = "https://www.gravatar.com/avatar/" + sb.ToString();
|
||||
|
||||
// Create a new credential and a new user
|
||||
string userUuid = Guid.NewGuid().ToString();
|
||||
Users user = new Users
|
||||
{
|
||||
uuid = userUuid,
|
||||
displayName = model.fullname,
|
||||
role = Int16.Parse(model.role),
|
||||
avatar = avatarUrl
|
||||
};
|
||||
Credentials credential = new Credentials
|
||||
{
|
||||
uuid = Guid.NewGuid().ToString(),
|
||||
user = userUuid,
|
||||
uniqueIdCode = model.emailaddress,
|
||||
provider = 0,
|
||||
};
|
||||
|
||||
// Assign a new session for user
|
||||
// Generate 32-bit random string as session token
|
||||
string token = GenerateRandomString(32);
|
||||
|
||||
// Use bcrypt to hash token
|
||||
string hashedToken = BCryptNet.HashPassword(token);
|
||||
|
||||
string sessionUuid = Guid.NewGuid().ToString();
|
||||
|
||||
Sessions session = new Sessions
|
||||
{
|
||||
uuid = sessionUuid,
|
||||
user = userUuid,
|
||||
token = token,
|
||||
alias = "Web",
|
||||
validFrom = DateTime.Now,
|
||||
validTo = DateTime.Now.AddDays(7)
|
||||
};
|
||||
|
||||
// Add them into database
|
||||
db.Users.Add(user);
|
||||
db.Credentials.Add(credential);
|
||||
db.Sessions.Add(session);
|
||||
db.SaveChanges();
|
||||
|
||||
// write cookie (`session`)
|
||||
HttpCookie cookie = new HttpCookie("session", sessionUuid + ":" + token);
|
||||
cookie.Expires = DateTime.Now.AddDays(7);
|
||||
Response.Cookies.Add(cookie);
|
||||
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// POST /CreateAccount
|
||||
|
||||
}
|
|
@ -46,6 +46,9 @@
|
|||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="BCrypt.Net-Next, Version=4.0.3.0, Culture=neutral, PublicKeyToken=1e11be04b6288443, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\BCrypt.Net-Next.4.0.3\lib\net48\BCrypt.Net-Next.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\EntityFramework.6.4.4\lib\net45\EntityFramework.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -54,8 +57,21 @@
|
|||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.5.3\lib\net461\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Security" />
|
||||
<Reference Include="System.Web.DynamicData" />
|
||||
|
@ -252,8 +268,11 @@
|
|||
<Content Include="Views\Home\Contact.cshtml" />
|
||||
<Content Include="Views\Home\Index.cshtml" />
|
||||
<Content Include="Views\Home\CreateAccount.cshtml" />
|
||||
<Content Include="Views\Test.cshtml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\Test\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Content Include="Content\bootstrap.rtl.min.css.map" />
|
||||
<Content Include="Content\bootstrap.rtl.css.map" />
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
<WebStackScaffolding_IsPartialViewSelected>False</WebStackScaffolding_IsPartialViewSelected>
|
||||
<WebStackScaffolding_IsReferencingScriptLibrariesSelected>True</WebStackScaffolding_IsReferencingScriptLibrariesSelected>
|
||||
<WebStackScaffolding_DbContextTypeFullName>FIT5032_Assignment.Models.Database1Entities</WebStackScaffolding_DbContextTypeFullName>
|
||||
<WebStackScaffolding_IsViewGenerationSelected>True</WebStackScaffolding_IsViewGenerationSelected>
|
||||
<WebStackScaffolding_IsViewGenerationSelected>False</WebStackScaffolding_IsViewGenerationSelected>
|
||||
<WebStackScaffolding_IsAsyncSelected>False</WebStackScaffolding_IsAsyncSelected>
|
||||
<View_SelectedScaffolderID>MvcViewScaffolder</View_SelectedScaffolderID>
|
||||
<View_SelectedScaffolderCategoryPath>root/Common/MVC/View</View_SelectedScaffolderCategoryPath>
|
||||
|
|
|
@ -18,6 +18,6 @@ namespace FIT5032_Assignment.Models
|
|||
|
||||
[Required]
|
||||
[Display(Name = "Which role do you want to assign?")]
|
||||
public Int16 role { get; set; }
|
||||
public String role { get; set; }
|
||||
}
|
||||
}
|
|
@ -12,40 +12,45 @@
|
|||
{
|
||||
@Html.AntiForgeryToken()
|
||||
|
||||
<div class="form-horizontal">
|
||||
<h4>CreateAccountForm</h4>
|
||||
<hr />
|
||||
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.emailaddress, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
@Html.EditorFor(model => model.emailaddress, new { htmlAttributes = new { @class = "form-control" } })
|
||||
@Html.ValidationMessageFor(model => model.emailaddress, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.fullname, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
@Html.EditorFor(model => model.fullname, new { htmlAttributes = new { @class = "form-control" } })
|
||||
@Html.ValidationMessageFor(model => model.fullname, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.role, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
@Html.EditorFor(model => model.role, new { htmlAttributes = new { @class = "form-control" } })
|
||||
@Html.ValidationMessageFor(model => model.role, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<input type="submit" value="Create" class="btn btn-default" />
|
||||
</div>
|
||||
<div class="form-horizontal">
|
||||
<h4>CreateAccountForm</h4>
|
||||
<hr />
|
||||
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.emailaddress, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
@Html.EditorFor(model => model.emailaddress, new { htmlAttributes = new { @class = "form-control" } })
|
||||
@Html.ValidationMessageFor(model => model.emailaddress, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.fullname, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
@Html.EditorFor(model => model.fullname, new { htmlAttributes = new { @class = "form-control" } })
|
||||
@Html.ValidationMessageFor(model => model.fullname, "", new { @class = "text-danger" })
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Dropdown menu -->
|
||||
<div class="form-group">
|
||||
@Html.LabelFor(model => model.role, htmlAttributes: new { @class = "control-label col-md-2" })
|
||||
<div class="col-md-10">
|
||||
<select class="form-control" id="role" name="role">
|
||||
<option value="1">Patient</option>
|
||||
<option value="2">Doctor</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10">
|
||||
<p>Next, you need to assign a passkey for authentication. Don't worry, it's safer than a password and uses your existing screen-unlocking authentication methods.</p>
|
||||
<input type="submit" value="Set Passkey" class="btn btn-default" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
|
||||
<div>
|
||||
|
@ -55,3 +60,20 @@
|
|||
@section Scripts {
|
||||
@Scripts.Render("~/bundles/jqueryval")
|
||||
}
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
||||
<script type="module">
|
||||
import {Passage, TokenStore} from "https://cdn.passage.id/passage-js.js"
|
||||
|
||||
export class MyTokenStore extends TokenStore {
|
||||
getAuthToken() {
|
||||
// get token from a cookie named "session"
|
||||
const authToken = document.cookie
|
||||
.split('; ')
|
||||
.find((row) => row.startsWith('session='))
|
||||
?.split('=')[1];
|
||||
return Promise.resolve(authToken);
|
||||
}
|
||||
};
|
||||
const psg = new Passage('seT6IaaZLyXcPBmd00SmPvTb', { MyTokenStore });
|
||||
</script>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Antlr" version="3.5.0.2" targetFramework="net48" />
|
||||
<package id="BCrypt.Net-Next" version="4.0.3" targetFramework="net48" />
|
||||
<package id="bootstrap" version="5.2.3" targetFramework="net48" />
|
||||
<package id="EntityFramework" version="6.4.4" targetFramework="net48" />
|
||||
<package id="jQuery" version="3.4.1" targetFramework="net48" />
|
||||
|
@ -14,5 +15,9 @@
|
|||
<package id="Microsoft.Web.Infrastructure" version="2.0.1" targetFramework="net48" />
|
||||
<package id="Modernizr" version="2.8.3" targetFramework="net48" />
|
||||
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net48" />
|
||||
<package id="System.Buffers" version="4.5.1" targetFramework="net48" />
|
||||
<package id="System.Memory" version="4.5.4" targetFramework="net48" />
|
||||
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net48" />
|
||||
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.3" targetFramework="net48" />
|
||||
<package id="WebGrease" version="1.6.0" targetFramework="net48" />
|
||||
</packages>
|
4
paket.dependencies
Normal file
4
paket.dependencies
Normal file
|
@ -0,0 +1,4 @@
|
|||
source https://api.nuget.org/v3/index.json
|
||||
|
||||
storage: none
|
||||
framework: net5.0, netstandard2.0, netstandard2.1
|
Loading…
Reference in New Issue
Block a user