Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
6ab25d0
create solution structure
Jan 21, 2020
45585d3
Merge pull request #1 from teduinternational/feature/create_solution_…
teducolabs Jan 22, 2020
9db6519
Add Entity
Jan 22, 2020
6f5ed9c
Configuration entites with Fluent API
Jan 24, 2020
e5865ab
Complete configuration
Jan 24, 2020
04d13dc
Migration database
Jan 29, 2020
259e40a
Merge pull request #2 from teduinternational/feature/database_design
teducolabs Jan 29, 2020
b2211f0
seeding database
Jan 29, 2020
8463337
Merge pull request #3 from teduinternational/feature/data_seeding
teducolabs Jan 31, 2020
8d17ea9
Add identity database and seed data
Jan 31, 2020
703929f
Merge pull request #4 from teduinternational/feature/aspnetcore_ident…
teducolabs Jan 31, 2020
42bbff4
Create structure
Feb 16, 2020
835c699
update read me
Feb 17, 2020
2ba0285
Add paging method
Feb 20, 2020
93deed9
Complete application for product
Feb 27, 2020
2e38050
Add product image table
Feb 27, 2020
58a6c5d
Add image manage
Mar 5, 2020
3e76602
Add web api
Mar 7, 2020
6366569
add Swagger
Mar 8, 2020
69bb26a
Merge branch 'feature/application_layer' into develop
Mar 8, 2020
43c2865
Add product apis
Mar 16, 2020
8bfa523
Image manage
Mar 17, 2020
ec2fad0
Update login
Mar 18, 2020
21201e3
Add JWT tokent to Swagger
Mar 23, 2020
896e482
Using fluent validation
Mar 26, 2020
548d3fd
Admin app layout
Mar 27, 2020
dd97ff8
add admin template url
Mar 27, 2020
63f838e
Add login page
Mar 27, 2020
7e782a7
Add cookie authentication without identity
Mar 28, 2020
97c4dd8
Get user list using token
Apr 19, 2020
12d9cc0
Update create user
Apr 24, 2020
090b12b
Update user
Apr 26, 2020
87ed338
User detail and paging
Apr 26, 2020
62548d4
Complete user delete
Apr 26, 2020
b7effc1
User filter
Apr 26, 2020
066d57c
Sending message to list using tempdata
Apr 26, 2020
aaa01de
Role assign
Apr 26, 2020
acb5899
Setting language to session and refactoring code
May 20, 2020
47b477c
Merge pull request #5 from teduinternational/feature/35_setting_language
teducolabs May 20, 2020
9f3a43e
Product list manage
May 26, 2020
f809b4a
Merge branch 'develop' of https://github.com/teduinternational/eShopS…
Jul 30, 2020
769d605
Create product form
Aug 2, 2020
ab033ff
Add ckeditor
Aug 12, 2020
721db2f
Filtering product by categoryid
Aug 24, 2020
0fec157
Assign product to category
Aug 27, 2020
c93b436
Merge branch 'feature/40_assing_product_to_category' into develop
Aug 29, 2020
44ca14b
Add template to webportal
Aug 29, 2020
4c85176
Merge pull request #6 from teduinternational/feature/41_add_webportal…
teducolabs Sep 1, 2020
7d074be
Add multiple languages
Sep 2, 2020
7adb21b
Merge pull request #7 from teduinternational/feature/42_multiple-lang…
teducolabs Sep 2, 2020
be7c444
Move API integration to separate project
Sep 2, 2020
0913cd5
Update database
Sep 2, 2020
6f4f361
Binding featured products
Sep 2, 2020
c6293b4
Merge pull request #8 from teduinternational/feature/43-binding-home-…
teducolabs Sep 7, 2020
3cb5230
Load categories product
Sep 7, 2020
ee93c53
Update product
Sep 20, 2020
40947ef
Merge pull request #9 from teduinternational/feature/45_update_product
teducolabs Sep 20, 2020
7ba342e
Product category
Oct 25, 2020
6704155
fix bug
Oct 25, 2020
d313565
Login for webportal
Nov 10, 2020
5c3042c
Register
Nov 11, 2020
dcc22bd
Merge pull request #10 from teduinternational/feature/50_register
teducolabs Nov 11, 2020
0e0be9b
add cart item
Nov 12, 2020
e9d25ab
List cart
Nov 14, 2020
5ee99c8
Update the cart
Nov 16, 2020
6ae29ca
Merge pull request #11 from teduinternational/feature/53_update_cart
teducolabs Nov 16, 2020
8a7f150
Checkout the order
Nov 17, 2020
417e1bc
Deploy config
Nov 17, 2020
1f004dc
Merge pull request #12 from teduinternational/feature/55_deploy_to_iis
teducolabs Nov 17, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,5 @@ ASALocalRun/
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb
/eShopSolution.BackendApi/wwwroot/user-content
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@
## Technologies
- ASP.NET Core 3.1
- Entity Framework Core 3.1
## Install Tools
- .NET Core SDK 3.1
- Git client
- Visual Studio 2019
- SQL Server 2019
## Youtube tutorial
- Video list: https://www.youtube.com/playlist?list=PLRhlTlpDUWsyN_FiVQrDWMtHix_E2A_UD
- TEDU Course: https://tedu.com.vn/khoa-hoc/lam-du-an-voi-aspnet-core-31-34.html
## How to configure and run
## How to contribute
- Clone code from Github: git clone https://github.com/teduinternational/eShopSolution
- Open solution eShopSolution.sln in Visual Studio 2019
- Set startup project is eShopSolution.Data
- Change connection string in Appsetting.json in eShopSolution.Data project
- Open Tools --> Nuget Package Manager --> Package Manager Console in Visual Studio
- Run Update-database and Enter.
- After migrate database successful, set Startup Project is eShopSolution.WebApp
- Change database connection in appsettings.Development.json in eShopSolution.WebApp project.
- Choose profile to run or press F5
## How to contribute
- Fork and create your branch
- Create Pull request to us.

## Admin template: https://startbootstrap.com/templates/sb-admin/
## Portal template: https://www.free-css.com/free-css-templates/page194/bootstrap-shop

## I18N (Internalization)
- References: https://medium.com/swlh/step-by-step-tutorial-to-build-multi-cultural-asp-net-core-web-app-3fac9a960c43
- Source code: https://github.com/LazZiya/ExpressLocalizationSampleCore3
25 changes: 25 additions & 0 deletions eShopSolution.AdminApp/Controllers/BaseController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace eShopSolution.AdminApp.Controllers
{
[Authorize]
public class BaseController : Controller
{
public override void OnActionExecuting(ActionExecutingContext context)
{
var sessions = context.HttpContext.Session.GetString("Token");
if (sessions == null)
{
context.Result = new RedirectToActionResult("Index", "Login", null);
}
base.OnActionExecuting(context);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using eShopSolution.AdminApp.Models;
using eShopSolution.ApiIntegration;
using eShopSolution.Utilities.Constants;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Linq;
using System.Threading.Tasks;

namespace eShopSolution.AdminApp.Controllers.Components
{
public class NavigationViewComponent : ViewComponent
{
private readonly ILanguageApiClient _languageApiClient;

public NavigationViewComponent(ILanguageApiClient languageApiClient)
{
_languageApiClient = languageApiClient;
}

public async Task<IViewComponentResult> InvokeAsync()
{
var languages = await _languageApiClient.GetAll();
var currentLanguageId = HttpContext
.Session
.GetString(SystemConstants.AppSettings.DefaultLanguageId);
var items = languages.ResultObj.Select(x => new SelectListItem()
{
Text = x.Name,
Value = x.Id.ToString(),
Selected = currentLanguageId == null ? x.IsDefault : currentLanguageId == x.Id.ToString()
});
var navigationVm = new NavigationViewModel()
{
CurrentLanguageId = currentLanguageId,
Languages = items.ToList()
};

return View("Default", navigationVm);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using eShopSolution.ViewModels.Common;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace eShopSolution.AdminApp.Controllers.Components
{
public class PagerViewComponent : ViewComponent
{
public Task<IViewComponentResult> InvokeAsync(PagedResultBase result)
{
return Task.FromResult((IViewComponentResult)View("Default", result));
}
}
}
50 changes: 50 additions & 0 deletions eShopSolution.AdminApp/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using eShopSolution.AdminApp.Models;
using Microsoft.AspNetCore.Authorization;
using eShopSolution.Utilities.Constants;
using Microsoft.AspNetCore.Http;

namespace eShopSolution.AdminApp.Controllers
{
public class HomeController : BaseController
{
private readonly ILogger<HomeController> _logger;

public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}

public IActionResult Index()
{
var user = User.Identity.Name;
return View();
}

public IActionResult Privacy()
{
return View();
}

[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}

[HttpPost]
public IActionResult Language(NavigationViewModel viewModel)
{
HttpContext.Session.SetString(SystemConstants.AppSettings.DefaultLanguageId,
viewModel.CurrentLanguageId);

return Redirect(viewModel.ReturnUrl);
}
}
}
86 changes: 86 additions & 0 deletions eShopSolution.AdminApp/Controllers/LoginController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using eShopSolution.ApiIntegration;
using eShopSolution.Utilities.Constants;
using eShopSolution.ViewModels.System.Users;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Logging;
using Microsoft.IdentityModel.Tokens;

namespace eShopSolution.AdminApp.Controllers
{
public class LoginController : Controller
{
private readonly IUserApiClient _userApiClient;
private readonly IConfiguration _configuration;

public LoginController(IUserApiClient userApiClient,
IConfiguration configuration)
{
_userApiClient = userApiClient;
_configuration = configuration;
}

[HttpGet]
public async Task<IActionResult> Index()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return View();
}

[HttpPost]
public async Task<IActionResult> Index(LoginRequest request)
{
if (!ModelState.IsValid)
return View(ModelState);

var result = await _userApiClient.Authenticate(request);
if (result.ResultObj == null)
{
ModelState.AddModelError("", result.Message);
return View();
}
var userPrincipal = this.ValidateToken(result.ResultObj);
var authProperties = new AuthenticationProperties
{
ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
IsPersistent = false
};
HttpContext.Session.SetString(SystemConstants.AppSettings.DefaultLanguageId, _configuration[SystemConstants.AppSettings.DefaultLanguageId]);
HttpContext.Session.SetString(SystemConstants.AppSettings.Token, result.ResultObj);
await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme,
userPrincipal,
authProperties);

return RedirectToAction("Index", "Home");
}

private ClaimsPrincipal ValidateToken(string jwtToken)
{
IdentityModelEventSource.ShowPII = true;

SecurityToken validatedToken;
TokenValidationParameters validationParameters = new TokenValidationParameters();

validationParameters.ValidateLifetime = true;

validationParameters.ValidAudience = _configuration["Tokens:Issuer"];
validationParameters.ValidIssuer = _configuration["Tokens:Issuer"];
validationParameters.IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Tokens:Key"]));

ClaimsPrincipal principal = new JwtSecurityTokenHandler().ValidateToken(jwtToken, validationParameters, out validatedToken);

return principal;
}
}
}
Loading