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.
368 lines
17 KiB
368 lines
17 KiB
using Google.Apis.Auth.OAuth2;
|
|
using Google.Cloud.Firestore;
|
|
using Grpc.Auth;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Configuration;
|
|
using Microsoft.IdentityModel.Tokens;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IdentityModel.Tokens.Jwt;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Net.Http;
|
|
using System.Security.Claims;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Teso_API.Methods;
|
|
using Teso_API.Methods.Controllers;
|
|
using Teso_API.Models;
|
|
|
|
namespace Teso_API.AuthControllers
|
|
{
|
|
[Route("api/facebookauth")]
|
|
[ApiController]
|
|
public class FacebookAuthController : ControllerBase
|
|
{
|
|
public IConfiguration _configuration;
|
|
private readonly TESOContext _context;
|
|
private FirestoreDb db;
|
|
readonly ITokenService tokenService;
|
|
public FacebookAuthController(TESOContext context, IConfiguration config, ITokenService tokenService)
|
|
{
|
|
_context = context;
|
|
_configuration = config;
|
|
db = new FirestoreDbBuilder
|
|
{
|
|
ProjectId = ServerLocation.credentials.project_id,
|
|
ChannelCredentials = GoogleCredential.FromJson(JsonConvert.SerializeObject(ServerLocation.credentials)).ToChannelCredentials(),
|
|
}.Build();
|
|
this.tokenService = tokenService ?? throw new ArgumentNullException(nameof(tokenService));
|
|
}
|
|
|
|
[HttpPost]
|
|
public async Task<ActionResult<Models.TokenHandler>> Post(FacebookUser user)
|
|
{
|
|
Models.TokenHandler tokenHandler = new Models.TokenHandler();
|
|
|
|
if (!UserAuthExists(user.UserGUID))
|
|
{
|
|
//if (user.pictureUri != null)
|
|
// user.pictureUri = await GetImageAsBase64Url(user.pictureUri);
|
|
|
|
UserAuth auth = new UserAuth();
|
|
auth.UserGUID = user.UserGUID;
|
|
auth.Status = "verified";
|
|
auth.AccountType = await _context.AccountTypes.AsQueryable().Where(u => u.TypeName.ToLower() == "facebook").Select(f => f.TypeCode).FirstOrDefaultAsync();
|
|
string[] splitted = user.Email.Split("@"[0]);
|
|
auth.Username = splitted[0];
|
|
auth.DeviceToken = user.devicetoken;
|
|
|
|
TesoUserDetail detail = new TesoUserDetail();
|
|
detail.UserGUID = user.UserGUID;
|
|
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;
|
|
|
|
if (TesoUserDetailExists(detail.Username))
|
|
{
|
|
detail.Username = user.UserGUID;
|
|
auth.Username = user.UserGUID;
|
|
}
|
|
|
|
Registrar registrar = new Registrar();
|
|
registrar.user = detail;
|
|
registrar.authentication = auth;
|
|
registrar.referral = user.referral;
|
|
|
|
if (!EmailExists(user.Email))
|
|
{
|
|
int statusCode = await RegisterUser(registrar);
|
|
|
|
if (statusCode == 200)
|
|
{
|
|
return await Authenticate(auth);
|
|
}
|
|
else
|
|
{
|
|
return BadRequest();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return BadRequest();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UserAuth auth = new UserAuth();
|
|
auth.UserGUID = user.UserGUID;
|
|
auth.Status = "verified";
|
|
auth.AccountType = await _context.AccountTypes.AsQueryable().Where(u => u.TypeName.ToLower() == "facebook").Select(f => f.TypeCode).FirstOrDefaultAsync();
|
|
string[] splitted = user.Email.Split("@"[0]);
|
|
auth.DeviceToken = user.devicetoken;
|
|
|
|
return await Authenticate(auth);
|
|
}
|
|
}
|
|
public async Task<int> RegisterUser(Registrar userAuth)
|
|
{
|
|
WriteBatch batch = db.StartBatch();
|
|
if (String.IsNullOrEmpty(userAuth.referral) || (!String.IsNullOrEmpty(userAuth.referral) && (_context.Referrals.AsQueryable().Where(r => r.Referrer == userAuth.referral &&
|
|
r.Datejoined.Value.Date == DateTime.Now.Date).Count()) >= 50))
|
|
{
|
|
UserFinance finance = new UserFinance();
|
|
finance.Gold = 0;
|
|
finance.Silver = 52;
|
|
finance.UserGUID = userAuth.user.UserGUID;
|
|
|
|
UserTransaction transaction = new UserTransaction();
|
|
transaction.RealCash = 0;
|
|
transaction.CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync();
|
|
transaction.Comments = "Welcome bonus";
|
|
transaction.CoinAmount = 52;
|
|
transaction.Timestamp = DateTime.Now;
|
|
transaction.TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userAuth.user.UserGUID;
|
|
transaction.UserGUID = userAuth.user.UserGUID;
|
|
transaction.TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver credit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync();
|
|
_context.UserTransactions.Add(transaction);
|
|
|
|
bool possible = await SilverBankOperations.WithdrawFromBank(5, _context);
|
|
|
|
if (!possible)
|
|
return 400;
|
|
|
|
if (!String.IsNullOrEmpty(userAuth.referral))
|
|
{
|
|
_context.Referrals.Add(new Referral
|
|
{
|
|
Datejoined = DateTime.Now,
|
|
Referred = userAuth.user.UserGUID,
|
|
Referrer = userAuth.referral,
|
|
Rewarded = false,
|
|
});
|
|
}
|
|
|
|
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(userAuth.user.UserGUID).Collection(userAuth.user.UserGUID).Document();
|
|
Dictionary<string, object> user = new Dictionary<string, object>
|
|
{
|
|
{ "notificationType", "welcome" },
|
|
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
|
|
{ "message", "Welcome to Teso App, as your welcome package you have been gifted 52 Silvers Coins for free. You may use them to acquire discount and freebie coupons!!!" },
|
|
{ "recipient", userAuth.user.UserGUID },
|
|
};
|
|
batch.Set(docRef, user);
|
|
_context.UserFinances.Add(finance);
|
|
}
|
|
else
|
|
{
|
|
List<UserFinance> finances = new List<UserFinance>{
|
|
new UserFinance
|
|
{
|
|
Gold = 0,
|
|
Silver = 52,
|
|
UserGUID = userAuth.user.UserGUID,
|
|
},
|
|
new UserFinance
|
|
{
|
|
Gold = 0,
|
|
Silver = 10,
|
|
UserGUID = userAuth.referral,
|
|
},
|
|
};
|
|
|
|
List<UserTransaction> transactions = new List<UserTransaction>() {
|
|
new UserTransaction
|
|
{
|
|
RealCash = 0,
|
|
CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync(),
|
|
Comments = "Welcome bonus",
|
|
CoinAmount = 52,
|
|
Timestamp = DateTime.Now,
|
|
TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userAuth.user.UserGUID,
|
|
UserGUID = userAuth.user.UserGUID,
|
|
TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver credit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync(),
|
|
},
|
|
new UserTransaction
|
|
{
|
|
RealCash = 0,
|
|
CoinType = await _context.CoinTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver")).Select(s => s.TypeCode).AsNoTracking().FirstOrDefaultAsync(),
|
|
Comments = "Referral bonus",
|
|
CoinAmount = 10,
|
|
Timestamp = DateTime.Now,
|
|
TransactionID = String.Format("{0:d9}", (DateTime.Now.Ticks / 10) % 10000000) + userAuth.user.UserGUID,
|
|
UserGUID = userAuth.referral,
|
|
TransactionType = await _context.TransactionTypes.AsQueryable().Where(c => c.TypeName.ToLower().Contains("silver credit")).Select(c => c.TypeCode).AsNoTracking().FirstOrDefaultAsync(),
|
|
},
|
|
};
|
|
bool possible = await SilverBankOperations.WithdrawFromBank(62, _context);
|
|
if (!possible)
|
|
return 400;
|
|
DocumentReference docRef = db.Collection(ServerLocation.user_notifications).Document(userAuth.user.UserGUID).Collection(userAuth.user.UserGUID).Document();
|
|
Dictionary<string, object> user = new Dictionary<string, object>
|
|
{
|
|
{ "notificationType", "welcome" },
|
|
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
|
|
{ "message", "Welcome to Teso App, as your welcome package we have gifted 52 Silvers Coins for free. You may use them to acquire discount and freebie coupons!!!" },
|
|
{ "recipient", userAuth.user.UserGUID },
|
|
};
|
|
batch.Set(docRef, user);
|
|
|
|
DocumentReference docRef2 = db.Collection(ServerLocation.user_notifications).Document(userAuth.referral).Collection(userAuth.referral).Document();
|
|
Dictionary<string, object> user2 = new Dictionary<string, object>
|
|
{
|
|
{ "notificationType", "referral" },
|
|
{ "timestamp", new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds()},
|
|
{ "message", "You just earned 10 Silver coins as your referral link was used!!!" },
|
|
{ "recipient", userAuth.user.UserGUID },
|
|
};
|
|
batch.Set(docRef2, user2);
|
|
|
|
_context.UserFinances.AddRange(finances);
|
|
_context.UserTransactions.AddRange(transactions);
|
|
_context.Referrals.Add(new Referral
|
|
{
|
|
Datejoined = DateTime.Now,
|
|
Referred = userAuth.user.UserGUID,
|
|
Referrer = userAuth.referral,
|
|
Rewarded = true,
|
|
});
|
|
}
|
|
userAuth.user.ThumbnailDp = await UploadedFile(userAuth.user.UserGUID, userAuth.user.ThumbnailDp);
|
|
_context.UserAuths.Add(userAuth.authentication);
|
|
_context.TesoUserDetails.Add(userAuth.user);
|
|
try
|
|
{
|
|
await _context.SaveChangesAsync();
|
|
await batch.CommitAsync();
|
|
}
|
|
catch (DbUpdateException)
|
|
{
|
|
return 400;
|
|
}
|
|
return 200;
|
|
}
|
|
private bool UserAuthExists(string id)
|
|
{
|
|
return _context.UserAuths.Any(e => e.UserGUID == id);
|
|
}
|
|
private async Task<string> UploadedFile(string id, string url)
|
|
{
|
|
try
|
|
{
|
|
string uniqueFileName;
|
|
uniqueFileName = id + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "dp.jpg";
|
|
string filePath = Path.Combine(ServerLocation.displayPicture, uniqueFileName);
|
|
using (WebClient wc = new WebClient())
|
|
wc.DownloadFile(url, filePath);
|
|
|
|
return uniqueFileName;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.WriteLine(ex.ToString());
|
|
return null;
|
|
}
|
|
}
|
|
private async Task<UserAuth> GetUser(string uid)
|
|
{
|
|
return await _context.UserAuths.AsQueryable().FirstOrDefaultAsync(u => u.UserGUID == uid);
|
|
}
|
|
public async Task<ActionResult<Models.TokenHandler>> Authenticate(UserAuth _userData)
|
|
{
|
|
|
|
var user = await GetUser(_userData.UserGUID);
|
|
|
|
if (user != null)
|
|
{
|
|
TesoUserDetail detail = await _context.TesoUserDetails.AsQueryable().Where(usr => usr.UserGUID == user.UserGUID).FirstOrDefaultAsync();
|
|
int friends = await _context.Relationships.AsQueryable().Where(t => t.UserGuid == user.UserGUID).CountAsync();
|
|
UserFinance finance = await _context.UserFinances.AsQueryable().Where(usr => usr.UserGUID == user.UserGUID).FirstOrDefaultAsync();
|
|
if (finance == null)
|
|
{
|
|
finance = new UserFinance();
|
|
finance.Gold = 0;
|
|
finance.Silver = 0;
|
|
}
|
|
TesoUser tesouser = new TesoUser();
|
|
tesouser.userGUID = detail.UserGUID;
|
|
tesouser.username = detail.Username;
|
|
tesouser.firstname = detail.Firstname;
|
|
tesouser.lastname = detail.Surname;
|
|
tesouser.description = detail.Description;
|
|
tesouser.email = detail.Email;
|
|
tesouser.phonenumber = detail.Phonenumber.HasValue ? detail.Phonenumber.Value.ToString() : "";
|
|
tesouser.address = detail.Address;
|
|
tesouser.country = detail.Country;
|
|
tesouser.DateOfBirth = detail.DateOfBirth;
|
|
tesouser.gender = detail.Gender;
|
|
tesouser.gold = finance.Gold.ToString();
|
|
tesouser.silver = finance.Silver.ToString();
|
|
tesouser.friends = friends.ToString();
|
|
tesouser.thumbnail_dp = detail.ThumbnailDp;
|
|
|
|
int timestamp_issued = (int)new DateTimeOffset(DateTimeOffset.UtcNow.DateTime).ToUnixTimeMilliseconds();
|
|
int timestamp_expires = (int)new DateTimeOffset(DateTimeOffset.UtcNow.DateTime.AddDays(14)).ToUnixTimeMilliseconds();
|
|
int timestamp_issuednbf = (int)new DateTimeOffset(DateTimeOffset.UtcNow.DateTime.AddMinutes(1)).ToUnixTimeMilliseconds();
|
|
|
|
//create claims details based on the user information
|
|
var claims = new[] {
|
|
new Claim(JwtRegisteredClaimNames.Iat, timestamp_issued.ToString()),
|
|
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
|
|
new Claim(JwtRegisteredClaimNames.Iss, ServerLocation.issuer),
|
|
new Claim(JwtRegisteredClaimNames.Exp, timestamp_expires.ToString()),
|
|
new Claim(JwtRegisteredClaimNames.Nbf, timestamp_issuednbf.ToString()),
|
|
new Claim(JwtRegisteredClaimNames.Sub, user.UserGUID.ToString()),
|
|
new Claim("username", user.Username.ToString()),
|
|
new Claim("userGUID", user.UserGUID.ToString()),
|
|
new Claim("deviceToken", _userData.DeviceToken),
|
|
|
|
};
|
|
|
|
//var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(ServerLocation.key));
|
|
|
|
//var signIn = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
|
|
|
|
//var token = new JwtSecurityToken(ServerLocation.issuer, ServerLocation.audience, claims, expires: DateTime.UtcNow.AddDays(14), signingCredentials: signIn);
|
|
//string tokenwriter = new JwtSecurityTokenHandler().WriteToken(token);
|
|
string tokenwriter = this.tokenService.GenerateAccessToken(claims);
|
|
|
|
Models.TokenHandler handler = new Models.TokenHandler();
|
|
handler.tokenTeso = tokenwriter;
|
|
handler.user = tesouser;
|
|
|
|
user.DeviceToken = _userData.DeviceToken;
|
|
_context.Entry(user).State = EntityState.Modified;
|
|
|
|
try
|
|
{
|
|
await _context.SaveChangesAsync();
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
return handler;
|
|
}
|
|
else
|
|
{
|
|
return BadRequest("Invalid credentials");
|
|
}
|
|
}
|
|
private bool TesoUserDetailExists(string id)
|
|
{
|
|
return _context.TesoUserDetails.Any(e => e.Username == id);
|
|
}
|
|
private bool EmailExists(string email)
|
|
{
|
|
return _context.TesoUserDetails.Any(e => e.Email == email);
|
|
}
|
|
}
|
|
}
|
|
|