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 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(); 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 GetImageAsBase64Url(string url) { using (var client = new HttpClient()) { var bytes = await client.GetByteArrayAsync(url); return Convert.ToBase64String(bytes); } } public async Task 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); } } }