Backend for the Teso project written in 2022
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
4.9 KiB

3 months ago
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.Google;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Teso_API.Models;
namespace Teso_API.AuthControllers
{
[AllowAnonymous, Route("account")]
[ApiController]
public class AccountController : Controller
{
readonly HttpClient Http = new HttpClient();
public IConfiguration _configuration;
private readonly TESOContext _context;
public AccountController(TESOContext context, IConfiguration config)
{
_context = context;
_configuration = config;
}
[Route("google-login")]
public IActionResult GoogleLogin()
{
var properties = new AuthenticationProperties { RedirectUri = Url.Action("GoogleResponse") };
return Challenge(properties, GoogleDefaults.AuthenticationScheme);
}
[Route("google-response")]
public async Task<IActionResult> GoogleResponse()
{
var response = await HttpContext.AuthenticateAsync(CookieAuthenticationDefaults.AuthenticationScheme);
GoogleUser user = new GoogleUser();
user.Firstname = response.Principal.FindFirstValue(ClaimTypes.GivenName);
user.Surname = response.Principal.FindFirstValue(ClaimTypes.Surname);
user.Email = response.Principal.FindFirstValue(ClaimTypes.Email);
user.Gender = response.Principal.FindFirstValue(ClaimTypes.Gender);
user.Country = response.Principal.FindFirstValue(ClaimTypes.Country);
string peopleApiKey = "";
var googleAccountId = response.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
if (!UserAuthExists(googleAccountId))
{
var request = new HttpRequestMessage(HttpMethod.Get, $"https://people.googleapis.com/v1/people/{googleAccountId}?personFields=photos&key={peopleApiKey}");
using var httpResponse = await Http.SendAsync(request);
var photosResponse = await httpResponse.Content.ReadFromJsonAsync<PeopleApiPhotos>();
user.pictureUri = photosResponse?.photos.FirstOrDefault()?.url;
if (user.pictureUri != null)
user.pictureUri = await GetImageAsBase64Url(user.pictureUri);
UserAuth auth = new UserAuth();
auth.UserGUID = googleAccountId;
auth.Status = "verified";
auth.AccountType = await _context.AccountTypes.AsQueryable().Where(u => u.TypeName.ToLower() == "google").Select(f => f.TypeCode).FirstOrDefaultAsync();
string[] splitted = user.Email.Split("@"[0]);
auth.Username = splitted[0];
TesoUserDetail detail = new TesoUserDetail();
detail.UserGUID = googleAccountId;
detail.Username = splitted[0];
detail.ThumbnailDp = user.pictureUri;
detail.Email = user.Email;
detail.Gender = user.Gender;
detail.Country = "+233";
detail.Firstname = user.Firstname;
detail.Surname = user.Surname;
Registrar registrar = new Registrar();
registrar.user = detail;
registrar.authentication = auth;
return await PostUserAuth(registrar);
}
return Ok("already Exists " + googleAccountId);
}
public async static Task<string> GetImageAsBase64Url(string url)
{
using (var client = new HttpClient())
{
var bytes = await client.GetByteArrayAsync(url);
return Convert.ToBase64String(bytes);
}
}
public async Task<ActionResult> PostUserAuth(Registrar userAuth)
{
_context.UserAuths.Add(userAuth.authentication);
_context.TesoUserDetails.Add(userAuth.user);
try
{
await _context.SaveChangesAsync();
return Ok(userAuth.authentication.UserGUID);
}
catch (DbUpdateException)
{
if (UserAuthExists(userAuth.authentication.UserGUID))
{
return Conflict();
}
else
{
return BadRequest();
}
}
}
private bool UserAuthExists(string id)
{
return _context.UserAuths.Any(e => e.UserGUID == id);
}
}
}