Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Косарева & Пичугин & Сычев & Титаренко #22

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions PhotosApp/Areas/Identity/Data/PhotosAppUser.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;

namespace PhotosApp.Areas.Identity.Data
{
// Add profile data for application users by adding properties to the PhotosAppUser class
public class PhotosAppUser : IdentityUser
{
public bool Paid { get; set; }
}
}
117 changes: 117 additions & 0 deletions PhotosApp/Areas/Identity/IdentityHostingStartup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
using System;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.UI;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PhotosApp.Areas.Identity.Data;
using PhotosApp.Services;
using PhotosApp.Services.Authorization;
using PhotosApp.Services.TicketStores;

[assembly: HostingStartup(typeof(PhotosApp.Areas.Identity.IdentityHostingStartup))]

namespace PhotosApp.Areas.Identity
{
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) =>
{
services.AddDbContext<UsersDbContext>(options =>
options.UseSqlite(
context.Configuration.GetConnectionString("UsersDbContextConnection")));
services.AddDbContext<TicketsDbContext>(options =>
{
options.UseSqlite(
context.Configuration.GetConnectionString("TicketsDbContextConnection")
);
});
services.ConfigureApplicationCookie(options =>
{
var serviceProvider = services.BuildServiceProvider();
options.SessionStore = serviceProvider.GetRequiredService<EntityTicketStore>();
/* добавленный ранее код конфигурации */
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.Cookie.Name = "PhotosApp.Auth";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(60);
options.LoginPath = "/Identity/Account/Login";
// ReturnUrlParameter requires
//using Microsoft.AspNetCore.Authentication.Cookies;
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
});
services.AddTransient<EntityTicketStore>();
services.AddTransient<IEmailSender, SimpleEmailSender>(serviceProvider =>
new SimpleEmailSender(
serviceProvider.GetRequiredService<ILogger<SimpleEmailSender>>(),
serviceProvider.GetRequiredService<IWebHostEnvironment>(),
context.Configuration["SimpleEmailSender:Host"],
context.Configuration.GetValue<int>("SimpleEmailSender:Port"),
context.Configuration.GetValue<bool>("SimpleEmailSender:EnableSSL"),
context.Configuration["SimpleEmailSender:UserName"],
context.Configuration["SimpleEmailSender:Password"]
));
services.AddScoped<IAuthorizationHandler, MustOwnPhotoHandler>();
services.AddAuthentication()
.AddGoogle("Google", options =>
{
options.ClientId = context.Configuration["Authentication:Google:ClientId"];
options.ClientSecret = context.Configuration["Authentication:Google:ClientSecret"];
});
services.AddAuthorization(options =>
{
options.AddPolicy(
"Beta",
policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.RequireClaim("testing", "beta");
});
options.AddPolicy(
"CanAddPhoto",
policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.RequireClaim("subscription", "paid");
}
);
options.AddPolicy(
"MustOwnPhoto",
policyBuilder =>
{
policyBuilder.RequireAuthenticatedUser();
policyBuilder.AddRequirements(new MustOwnPhotoRequirement());
}
);
});

services.AddDefaultIdentity<PhotosAppUser>(options => options.SignIn.RequireConfirmedAccount = false)
.AddRoles<IdentityRole>()
.AddClaimsPrincipalFactory<CustomClaimsPrincipalFactory>()
.AddPasswordValidator<UsernameAsPasswordValidator<PhotosAppUser>>()
.AddEntityFrameworkStores<UsersDbContext>()
.AddErrorDescriber<RussianIdentityErrorDescriber>();
services.Configure<IdentityOptions>(options =>
{
options.Password.RequireDigit = false;
options.Password.RequireLowercase = true;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequiredLength = 6;
options.Password.RequiredUniqueChars = 1;
options.SignIn.RequireConfirmedAccount = true;
options.SignIn.RequireConfirmedEmail = false;
options.SignIn.RequireConfirmedPhoneNumber = false;
});
});
}
}
}
6 changes: 4 additions & 2 deletions PhotosApp/Controllers/DevController.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace PhotosApp.Controllers
{
public class DevController : Controller
{
[Authorize(Roles = "Dev")]
public IActionResult Decode()
{
return View();
}
}
}
}
27 changes: 20 additions & 7 deletions PhotosApp/Controllers/PhotosController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using PhotosApp.Data;
Expand Down Expand Up @@ -32,6 +34,7 @@ public async Task<IActionResult> Index()
return View(model);
}

[Authorize(Policy = "MustOwnPhoto")]
public async Task<IActionResult> GetPhoto(Guid id)
{
var photoEntity = await photosRepository.GetPhotoMetaAsync(id);
Expand All @@ -43,8 +46,9 @@ public async Task<IActionResult> GetPhoto(Guid id)
var model = new GetPhotoModel(photo);
return View(model);
}

[HttpGet("photos/{id}")]
[Authorize(Policy = "MustOwnPhoto")]
public async Task<IActionResult> GetPhotoFile(Guid id)
{
var photoContent = await photosRepository.GetPhotoContentAsync(id);
Expand All @@ -53,12 +57,14 @@ public async Task<IActionResult> GetPhotoFile(Guid id)

return File(photoContent.Content, photoContent.ContentType, photoContent.FileName);
}


[Authorize(Policy = "CanAddPhoto")]
public IActionResult AddPhoto()
{
return View();
}


[Authorize(Policy = "CanAddPhoto")]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddPhoto(AddPhotoModel addPhotoModel)
Expand Down Expand Up @@ -88,7 +94,9 @@ public async Task<IActionResult> AddPhoto(AddPhotoModel addPhotoModel)

return RedirectToAction("Index");
}


[Authorize(Policy = "Beta")]
[Authorize(Policy = "MustOwnPhoto")]
public async Task<IActionResult> EditPhoto(Guid id)
{
var photo = await photosRepository.GetPhotoMetaAsync(id);
Expand All @@ -100,9 +108,12 @@ public async Task<IActionResult> EditPhoto(Guid id)
Id = photo.Id,
Title = photo.Title
};

return View(viewModel);
}


[Authorize(Policy = "Beta")]
[Authorize(Policy = "MustOwnPhoto")]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> EditPhoto(EditPhotoModel editPhotoModel)
Expand All @@ -122,6 +133,7 @@ public async Task<IActionResult> EditPhoto(EditPhotoModel editPhotoModel)
return RedirectToAction("Index");
}

[Authorize(Policy = "MustOwnPhoto")]
[HttpPost]
public async Task<IActionResult> DeletePhoto(Guid id)
{
Expand All @@ -135,9 +147,10 @@ public async Task<IActionResult> DeletePhoto(Guid id)
return RedirectToAction("Index");
}

[Authorize]
private string GetOwnerId()
{
return "a83b72ed-3f99-44b5-aa32-f9d03e7eb1fd";
return User.FindFirstValue(ClaimTypes.NameIdentifier);
}
}
}
}
Loading