Ignore:
Timestamp:
09/01/26 06:11:34 (4 weeks ago)
Author:
mmilevski <markomilevski3@…>
Branches:
main
Children:
d2eccb3
Parents:
08aefc6
Message:

Added major improvements.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • KernelRecordsMVC.Web/Controllers/AccountController.cs

    r08aefc6 rfa0fbaf  
    1 using Microsoft.AspNetCore.Mvc;
    2 using KernelRecordsMVC.Data;
     1using System.Security.Claims;
     2using KernelRecordsMVC.Application.ViewModels;
     3using KernelRecordsMVC.Infrastructure.Data;
    34using KernelRecordsMVC.Models;
    4 using KernelRecordsMVC.Application.ViewModels;
    5 using Microsoft.AspNetCore.Http;
    6 
    7 namespace KernelRecordsMVC.Controllers;
     5using Microsoft.AspNetCore.Authentication;
     6using Microsoft.AspNetCore.Mvc;
     7using Microsoft.EntityFrameworkCore;
     8
     9namespace KernelRecordsMVC.Web.Controllers;
    810
    911public class AccountController : Controller
    … …  
    1618    }
    1719
    18     // ==============================
     20
     21    // =========================================================
    1922    // REGISTER - GET
    20     // ==============================
     23    // =========================================================
    2124
    2225    [HttpGet]
    … …  
    2730
    2831
    29     // ==============================
     32    // =========================================================
    3033    // REGISTER - POST
    31     // ==============================
     34    // =========================================================
    3235
    3336    [HttpPost]
    … …  
    6164            Username = model.Username,
    6265
    63             // We'll replace this with proper password hashing
    64             // in the security cleanup section.
     66            // TODO:
     67            // Replace with password hashing later.
    6568            Password = model.Password,
    6669
    … …  
    7477        _context.SaveChanges();
    7578
     79
    7680        // Every normal registered user is a Consumer.
    7781        var consumer = new Consumer
    … …  
    8993
    9094
    91     // ==============================
     95    // =========================================================
    9296    // LOGIN - GET
    93     // ==============================
     97    // =========================================================
    9498
    9599    [HttpGet]
    … …  
    100104
    101105
    102     // ==============================
     106    // =========================================================
    103107    // LOGIN - POST
    104     // ==============================
     108    // =========================================================
    105109
    106110    [HttpPost]
    107111    [ValidateAntiForgeryToken]
    108     public IActionResult Login(LoginViewModel model)
     112    public async Task<IActionResult> Login(
     113        LoginViewModel model)
    109114    {
    110115        if (!ModelState.IsValid)
    … …  
    125130        }
    126131
     132
     133        // =====================================================
     134        // DETERMINE ACCOUNT TYPE
     135        // =====================================================
     136
     137        var admin = _context.Admins
     138            .FirstOrDefault(x => x.UserId == user.UserId);
     139
     140        string role;
     141
     142        if (admin != null)
     143        {
     144            role = "Admin";
     145        }
     146        else
     147        {
     148            role = "Consumer";
     149        }
     150
     151
     152        // =====================================================
     153        // CREATE CLAIMS
     154        // =====================================================
     155
     156        var claims = new List<Claim>
     157        {
     158            new Claim(
     159                ClaimTypes.NameIdentifier,
     160                user.UserId.ToString()),
     161
     162            new Claim(
     163                ClaimTypes.Name,
     164                user.Username),
     165
     166            new Claim(
     167                ClaimTypes.Email,
     168                user.Email),
     169
     170            new Claim(
     171                ClaimTypes.Role,
     172                role)
     173        };
     174
     175
     176        if (admin != null)
     177        {
     178            claims.Add(
     179                new Claim(
     180                    "AdminType",
     181                    admin.Type.ToString()));
     182        }
     183
     184
     185        var identity = new ClaimsIdentity(
     186            claims,
     187            "Cookies");
     188
     189        var principal =
     190            new ClaimsPrincipal(identity);
     191
     192
     193        // =====================================================
     194        // SIGN IN
     195        // =====================================================
     196
     197        await HttpContext.SignInAsync(
     198            "Cookies",
     199            principal);
     200
     201
     202        // =====================================================
     203        // KEEP SESSION FOR EXISTING CODE
     204        // =====================================================
     205
    127206        HttpContext.Session.SetInt32(
    128207            "UserId",
    … …  
    133212            user.Username);
    134213
    135         // Determine account type from the actual
    136         // ADMINS / CONSUMERS tables.
    137         var admin = _context.Admins
    138             .FirstOrDefault(x => x.UserId == user.UserId);
     214        HttpContext.Session.SetString(
     215            "Role",
     216            role);
    139217
    140218        if (admin != null)
    141219        {
    142             HttpContext.Session.SetString(
    143                 "Role",
    144                 "Admin");
    145 
    146220            HttpContext.Session.SetString(
    147221                "AdminType",
    148222                admin.Type.ToString());
    149223        }
    150         else
    151         {
    152             HttpContext.Session.SetString(
    153                 "Role",
    154                 "Consumer");
    155         }
     224
    156225
    157226        return RedirectToAction(
    … …  
    161230
    162231
    163     // ==============================
     232    // =========================================================
     233    // PROFILE - GET
     234    // =========================================================
     235
     236    [HttpGet]
     237    public IActionResult Profile()
     238    {
     239        // Get logged-in user's ID from authentication claims.
     240        var userIdClaim = User.FindFirst(
     241            ClaimTypes.NameIdentifier);
     242
     243        if (userIdClaim == null)
     244            return RedirectToAction(nameof(Login));
     245
     246        if (!long.TryParse(
     247                userIdClaim.Value,
     248                out var userId))
     249        {
     250            return RedirectToAction(nameof(Login));
     251        }
     252
     253
     254        // Load user + consumer information.
     255        var user = _context.Users
     256            .Include(x => x.Consumer)
     257            .FirstOrDefault(x =>
     258                x.UserId == userId);
     259
     260        if (user == null)
     261            return NotFound();
     262
     263
     264        var model = new ProfileViewModel
     265        {
     266            UserId = user.UserId,
     267
     268            Username = user.Username,
     269
     270            Email = user.Email,
     271
     272            TelephoneNumber =
     273                user.TelephoneNumber,
     274
     275            ShippingAddress =
     276                user.ShippingAddress,
     277
     278            DateCreated =
     279                user.DateCreated,
     280
     281            PointsCollected =
     282                user.Consumer?.PointsCollected ?? 0
     283        };
     284
     285
     286        return View(model);
     287    }
     288
     289
     290    // =========================================================
     291    // PROFILE - POST
     292    // =========================================================
     293
     294    [HttpPost]
     295    [ValidateAntiForgeryToken]
     296    public async Task<IActionResult> Profile(
     297        ProfileViewModel model)
     298    {
     299        // Get the currently authenticated user.
     300        var userIdClaim = User.FindFirst(
     301            ClaimTypes.NameIdentifier);
     302
     303        if (userIdClaim == null)
     304            return RedirectToAction(nameof(Login));
     305
     306        if (!long.TryParse(
     307                userIdClaim.Value,
     308                out var userId))
     309        {
     310            return RedirectToAction(nameof(Login));
     311        }
     312
     313
     314        if (!ModelState.IsValid)
     315            return View(model);
     316
     317
     318        var user = _context.Users
     319            .FirstOrDefault(x =>
     320                x.UserId == userId);
     321
     322        if (user == null)
     323            return NotFound();
     324
     325
     326        // =====================================================
     327        // CHECK EMAIL
     328        // =====================================================
     329
     330        var emailExists = _context.Users.Any(x =>
     331            x.Email == model.Email &&
     332            x.UserId != userId);
     333
     334        if (emailExists)
     335        {
     336            ModelState.AddModelError(
     337                nameof(model.Email),
     338                "This email is already registered.");
     339
     340            return View(model);
     341        }
     342
     343
     344        // =====================================================
     345        // UPDATE USER
     346        // =====================================================
     347
     348        user.Email = model.Email;
     349
     350        user.TelephoneNumber =
     351            model.TelephoneNumber;
     352
     353        user.ShippingAddress =
     354            model.ShippingAddress;
     355
     356
     357        _context.SaveChanges();
     358
     359
     360        TempData["Success"] =
     361            "Your profile has been updated successfully.";
     362
     363
     364        // =====================================================
     365        // REFRESH EMAIL CLAIM
     366        // =====================================================
     367
     368        var claims = new List<Claim>
     369        {
     370            new Claim(
     371                ClaimTypes.NameIdentifier,
     372                user.UserId.ToString()),
     373
     374            new Claim(
     375                ClaimTypes.Name,
     376                user.Username),
     377
     378            new Claim(
     379                ClaimTypes.Email,
     380                user.Email),
     381
     382            new Claim(
     383                ClaimTypes.Role,
     384                User.IsInRole("Admin")
     385                    ? "Admin"
     386                    : "Consumer")
     387        };
     388
     389
     390        var identity = new ClaimsIdentity(
     391            claims,
     392            "Cookies");
     393
     394        var principal =
     395            new ClaimsPrincipal(identity);
     396
     397
     398        await HttpContext.SignInAsync(
     399            "Cookies",
     400            principal);
     401
     402
     403        // Keep session synchronized.
     404        HttpContext.Session.SetString(
     405            "Username",
     406            user.Username);
     407
     408
     409        return RedirectToAction(nameof(Profile));
     410    }
     411
     412
     413    // =========================================================
    164414    // LOGOUT
    165     // ==============================
    166 
    167     public IActionResult Logout()
    168     {
     415    // =========================================================
     416
     417    [HttpPost]
     418    [ValidateAntiForgeryToken]
     419    public async Task<IActionResult> Logout()
     420    {
     421        await HttpContext.SignOutAsync("Cookies");
     422
    169423        HttpContext.Session.Clear();
    170424
Note: See TracChangeset for help on using the changeset viewer.