Skip to content

Commit

Permalink
feat(auth): add login and refresh mutation
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Older rest endpoint to login and refresh removed
  • Loading branch information
cyberhck committed Jul 4, 2021
1 parent 755c65b commit ec5cef7
Show file tree
Hide file tree
Showing 18 changed files with 197 additions and 219 deletions.

This file was deleted.

150 changes: 0 additions & 150 deletions Micro.Auth.Api/Authentication/SessionController.cs

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Micro.Auth.Api.GraphQL.Extensions.Exceptions
{
public class InvalidTokenTypeException : Exception
{
public InvalidTokenTypeException(string expectedType) : base($"{expectedType} token not found")
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Micro.Auth.Api.GraphQL.Extensions.Exceptions
{
public class MissingHeaderException : Exception
{
public MissingHeaderException(string headerName) : base($"Missing {headerName} header")
{
}
}
}
22 changes: 22 additions & 0 deletions Micro.Auth.Api/GraphQL/Extensions/LoginRequestExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Micro.Auth.Api.Internal.UserData.Extensions;
using Micro.Auth.Business.Sessions;
using Microsoft.AspNetCore.Http;

namespace Micro.Auth.Api.GraphQL.Extensions
{
public static class LoginRequestExtension
{
public static LoginRequest GetLoginRequest(this IHttpContextAccessor httpContextAccessor)
{
var (login, password) = httpContextAccessor.MustGetBasicToken();
return new LoginRequest
{
Login = login,
Password = password,
IpAddress = httpContextAccessor.GetIpAddress(),
UserAgent = httpContextAccessor.GetUserAgent(),
Location = httpContextAccessor.GetRoughLocation()
};
}
}
}
53 changes: 53 additions & 0 deletions Micro.Auth.Api/GraphQL/Extensions/Tokens.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
using System;
using System.Text;
using Micro.Auth.Api.GraphQL.Extensions.Exceptions;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;

namespace Micro.Auth.Api.GraphQL.Extensions
{
public static class Tokens
{
public static string MustGetBearerToken(this IHttpContextAccessor httpContextAccessor)
{
var headerValue = httpContextAccessor.MustGetAuthHeader();
if (!headerValue.StartsWith("Bearer "))
{
throw new InvalidTokenTypeException("Bearer");
}
return headerValue.Substring("Bearer ".Length).Trim();
}

private static string MustGetAuthHeader(this IHttpContextAccessor httpContextAccessor)
{
var header = StringValues.Empty;
var exists = httpContextAccessor.HttpContext?.Request.Headers.TryGetValue("Authorization", out header);
if (exists == false || header.ToString() == "")
{
throw new MissingHeaderException("Authorization");
}

return header.ToString();
}

public static (string, string) MustGetBasicToken(this IHttpContextAccessor httpContextAccessor)
{
try
{
var headerValue = httpContextAccessor.MustGetAuthHeader();
if (!headerValue.StartsWith("Basic "))
{
throw new InvalidTokenTypeException("Basic");
}

var token = headerValue.Substring("Basic ".Length).Trim();
var parts = Encoding.UTF8.GetString(Convert.FromBase64String(token)).Split(":");
return (parts[0], parts[1]);
}
catch (Exception e)
{
throw new InvalidTokenTypeException(e.Message);
}
}
}
}
10 changes: 9 additions & 1 deletion Micro.Auth.Api/GraphQL/Mutation.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
using GraphQL;
using GraphQL.Types;
using Micro.Auth.Api.GraphQL.Directives.Extensions;
using Micro.Auth.Api.GraphQL.Extensions;
using Micro.Auth.Api.GraphQL.Inputs;
using Micro.Auth.Api.GraphQL.Types;
using Micro.Auth.Api.Internal.UserData.Extensions;
using Micro.Auth.Business.Common;
using Micro.Auth.Business.EmailVerification;
using Micro.Auth.Business.PasswordManager;
using Micro.Auth.Business.Sessions;
using Micro.Auth.Business.Users;
using Microsoft.AspNetCore.Http;

namespace Micro.Auth.Api.GraphQL
{
public class Mutation : ObjectGraphType
{
public Mutation(IUserService userService, IPasswordManager passwordManager, IEmailVerificationService verification, IHttpContextAccessor contextAccessor)
public Mutation(IUserService userService, IPasswordManager passwordManager, IEmailVerificationService verification, ISessionService sessionService, IHttpContextAccessor contextAccessor)
{
FieldAsync<NonNullGraphType<UserType>, User>("register",
arguments: new QueryArguments(RegisterInputType.BuildArgument()),
resolve: x => userService.Create(x.GetArgument<RegisterInput>("input")));

FieldAsync<NonNullGraphType<StringGraphType>, string>("refreshToken",
resolve: x => sessionService.Refresh(contextAccessor.MustGetBearerToken()));

FieldAsync<NonNullGraphType<TokensType>, LoginSuccessResponse>("login",
resolve: x => sessionService.Login(contextAccessor.GetLoginRequest()));

FieldAsync<NonNullGraphType<UserType>, User>("verifyEmail",
arguments: new QueryArguments(VerifyEmailInputType.BuildArgument()),
resolve: x => verification.ConfirmEmail(x.GetArgument<VerifyEmailInput>("input")));
Expand Down
15 changes: 15 additions & 0 deletions Micro.Auth.Api/GraphQL/Types/TokensType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Micro.Auth.Business.Sessions;

namespace Micro.Auth.Api.GraphQL.Types
{
public sealed class TokensType : Micro.GraphQL.Federation.ObjectGraphType<LoginSuccessResponse>
{
public TokensType()
{
Name = "Token";
Field("jwt", x => x.Jwt).Description("JWT");
Field("refreshToken", x => x.RefreshToken, true)
.Description("Once JWT expires, use this token to create a new session");
}
}
}
1 change: 1 addition & 0 deletions Micro.Auth.Api/Internal/StartupExtensions/GraphQl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public static void ConfigureGraphQl(this IServiceCollection services)
services.AddTransient<UserType>();
services.AddTransient<AvailabilityResultType>();
services.AddTransient<ResultType>();
services.AddTransient<TokensType>();
services.AddTransient<RegisterInputType>();
services.AddTransient<RefreshTokenType>();
services.AddTransient<ChangePasswordInput>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Micro.Auth.Api.Internal.UserData.Extensions
Expand All @@ -10,5 +11,10 @@ public static IPAddress GetIpAddress(this ControllerBase controller)
// todo: this might not be accurate behind a load balancer, so we might have to get X-Forwarded-For
return controller?.HttpContext?.Connection?.RemoteIpAddress;
}
public static IPAddress GetIpAddress(this IHttpContextAccessor ctx)
{
// todo: this might not be accurate behind a load balancer, so we might have to get X-Forwarded-For
return ctx.HttpContext?.Connection.RemoteIpAddress;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Micro.Auth.Api.Internal.UserData.Extensions
Expand All @@ -8,5 +9,9 @@ public static string GetRoughLocation(this ControllerBase controller)
{
return "Bangkok";
}
public static string GetRoughLocation(this IHttpContextAccessor ctx)
{
return "Bangkok";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;

Expand All @@ -11,5 +12,11 @@ public static class UserAgentExtension
var containsData = controller?.HttpContext?.Request?.Headers?.TryGetValue("User-Agent", out userAgent);
return containsData.HasValue && containsData.Value ? userAgent.ToString() : null;
}
public static string? GetUserAgent(this IHttpContextAccessor ctx)
{
var userAgent = StringValues.Empty;
var containsData = ctx?.HttpContext?.Request?.Headers?.TryGetValue("User-Agent", out userAgent);
return containsData.HasValue && containsData.Value ? userAgent.ToString() : null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;

namespace Micro.Auth.Business.Sessions.Exceptions
{
public class InvalidCredentialsException : Exception
{
public InvalidCredentialsException(string message) : base(message)
{
}
}
}
Loading

0 comments on commit ec5cef7

Please sign in to comment.