2023-12-24 12:33:51 +03:00

236 lines
7.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
namespace CyberBoom.Controllers;
[ApiController]
[Route("/api/[controller]")]
public class UsersController : ControllerBase
{
private readonly ApplicationContext _applicationContext;
private readonly UserManager<User> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public UsersController(
ApplicationContext applicationContext,
UserManager<User> userManager,
RoleManager<IdentityRole> roleManager
)
{
_applicationContext = applicationContext;
_userManager = userManager;
_roleManager = roleManager;
}
async Task AddUerToRole(User user, string role)
{
var isExists = await _roleManager.RoleExistsAsync(role);
if (!isExists)
{
var roleResult = await _roleManager.CreateAsync(new IdentityRole(role));
if (!roleResult.Succeeded)
throw new Exception("cannot create role");
}
var addingRole = await _userManager.AddToRoleAsync(user, role);
if (!addingRole.Succeeded)
throw new Exception("cannot create role");
}
[AllowAnonymous]
[HttpPost]
public async Task<IActionResult> Post([FromForm] UserPost user)
{
await user.Avatar.WriteFileToDirectory();
var userWr = new User
{
AvatarUrl = user.Avatar.FileName,
Fio = user.Fio,
Specialities = user.Specialities,
TelegramBotUrl = user.TelegramBotUrl,
UserName = user.Username,
Email = user.Email
};
var result = await _userManager.CreateAsync(userWr);
if (!result.Succeeded)
return BadRequest(result.Errors);
var role = user.Username == "moderator" ? "модератор" : "спикер";
await AddUerToRole(userWr, role);
var token = GetToken(userWr, role);
return Ok(new { userWr.Id, Token = token });
}
string GetToken(User user, string role)
{
var claims = new List<Claim>
{
new Claim(ClaimsIdentity.DefaultNameClaimType, user.UserName!),
new Claim(ClaimsIdentity.DefaultRoleClaimType, role)
};
var bOpt = new BearerAccessTokenOptions();
return bOpt.GetBearerToken(claims);
}
[Authorize(Roles = "модератор")]
[HttpPut]
public async Task<IActionResult> Put([FromForm] UserPut user)
{
await user.Avatar.WriteFileToDirectory();
var fuser = await _userManager.FindByIdAsync(user.Id);
if (fuser is null)
throw new Exception("user not found");
fuser.AvatarUrl = user.Avatar.FileName;
fuser.Fio = user.Fio;
fuser.Specialities = user.Specialities;
fuser.TelegramBotUrl = user.TelegramBotUrl;
fuser.UserName = user.Username;
fuser.Email = user.Email;
var result = await _userManager.UpdateAsync(fuser);
if (result.Succeeded)
return Ok();
return BadRequest(result.Errors);
}
[Authorize(Roles = "модератор")]
[HttpPost("moderator")]
public async Task<IActionResult> PostModerator([FromForm] UserPost user)
{
await user.Avatar.WriteFileToDirectory();
var userWr = new User
{
AvatarUrl = user.Avatar.FileName,
Fio = user.Fio,
Specialities = user.Specialities,
TelegramBotUrl = user.TelegramBotUrl,
UserName = user.Username
};
var result = await _userManager.CreateAsync(userWr);
if (!result.Succeeded)
return BadRequest(result.Errors);
var role = "модератор";
await AddUerToRole(userWr, role);
var token = GetToken(userWr, role);
return Ok(new { userWr.Id, Token = token });
}
[AllowAnonymous]
[HttpGet("signin-google")]
public IActionResult SignInWithGoogle()
{
var properties = new AuthenticationProperties { RedirectUri = Url.Action(nameof(SignInWithGoogleCallback)) };
return Challenge(properties, GoogleDefaults.AuthenticationScheme);
}
[AllowAnonymous]
[HttpGet("signin-google-callback")]
public async Task<IActionResult> SignInWithGoogleCallback()
{
var result = await HttpContext.AuthenticateAsync(GoogleDefaults.AuthenticationScheme);
if (result?.Succeeded != true)
{
return BadRequest("Ошибка аутентификации Google");
}
// Извлеките информацию о пользователе из результата аутентификации
var claims = result.Principal!.Identities
.FirstOrDefault(y => y.AuthenticationType == GoogleDefaults.AuthenticationScheme)?
.Claims;
var email = claims?.FirstOrDefault(x => x.Type == ClaimTypes.Email)!.Value;
var name = claims?.FirstOrDefault(x => x.Type == ClaimTypes.Name)!.Value;
var user = await _userManager.FindByEmailAsync(email!);
var role = "спикер";
if(user is null)
{
user = new User
{
Fio = name!,
Specialities = string.Empty,
TelegramBotUrl = string.Empty,
AvatarUrl = $"https://www.gravatar.com/avatar/{BitConverter.ToString(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(email!))).Replace("-", "").ToLowerInvariant()}?d=identicon",
UserName = name,
Email = email
};
var createResult = await _userManager.CreateAsync(user);
if (!createResult.Succeeded)
return BadRequest(createResult.Errors);
await AddUerToRole(user, role);
}
var token = GetToken(user, role);
// Здесь вы можете создать JWT или другой токен для аутентификации в вашем приложении
// и отправить его пользователю.
return Ok(new {
Token = token,
User = user
});
}
[Authorize]
[HttpGet]
public async Task<IActionResult> GetUserData(string id)
{
var user = await _userManager.FindByIdAsync(id);
if (user is null)
return BadRequest();
var role = await _userManager.GetRolesAsync(user);
return Ok(new { user, role });
}
[Authorize]
[HttpGet("stats")]
public async Task<IActionResult> GetUserStats(string id)
{
var user = await _userManager.FindByIdAsync(id);
if (user is null)
return BadRequest();
var stats = await _applicationContext.GetStatistic(id);
var achievmnets = _applicationContext.Achievments.Where(c => c.UserId == id);
return Ok(new { Stats = stats, Achievments = achievmnets });
}
}