Skip to content

Commit d60370a

Browse files
authored
Merge pull request #13 from CodeBeamOrg/dev
More AuthService Features
2 parents e3bbfae + adfec31 commit d60370a

File tree

5 files changed

+131
-16
lines changed

5 files changed

+131
-16
lines changed

GoogleApis.Blazor/AllEnums.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,6 @@
22
#pragma warning disable CS1591
33
namespace GoogleApis.Blazor
44
{
5-
public static class EnumExtensions
6-
{
7-
public static string ToDescriptionString(this Enum val)
8-
{
9-
var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
10-
11-
return attributes.Length > 0
12-
? attributes[0].Description
13-
: val.ToString();
14-
}
15-
}
165

176
public enum Scope
187
{
@@ -80,4 +69,14 @@ public enum EventValueType
8069
Location,
8170
}
8271

72+
public enum PromptType
73+
{
74+
[Description("none")]
75+
None,
76+
[Description("consent")]
77+
Consent,
78+
[Description("select_account")]
79+
SelectAccount,
80+
}
81+
8382
}

GoogleApis.Blazor/Auth/AuthService.cs

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using Microsoft.AspNetCore.Components;
1+
using GoogleApis.Blazor.Extensions;
2+
using Microsoft.AspNetCore.Components;
3+
using Microsoft.Extensions.Configuration;
24
using Microsoft.JSInterop;
35
using System;
46
using System.Collections.Generic;
@@ -19,26 +21,30 @@ public class AuthService
1921
{
2022
[Inject] IHttpClientFactory HttpClientFactory { get; set; }
2123
[Inject] IJSRuntime JSRuntime { get; set; }
24+
[Inject] IConfiguration Configuration { get; set; }
2225

2326
/// <summary>
2427
/// Constructs the class.
2528
/// </summary>
2629
/// <param name="jsRuntime"></param>
2730
/// <param name="httpClientFactory"></param>
28-
public AuthService(IJSRuntime jsRuntime, IHttpClientFactory httpClientFactory)
31+
/// <param name="configuration"></param>
32+
public AuthService(IJSRuntime jsRuntime, IHttpClientFactory httpClientFactory, IConfiguration configuration)
2933
{
3034
JSRuntime = jsRuntime;
3135
HttpClientFactory = httpClientFactory;
36+
Configuration = configuration;
3237
}
3338

3439
/// <summary>
35-
/// oAuth2 Step 1. Opens "Select Google Account" page in a new tab and return the value into redirectUrl.
40+
/// oAuth2 Step 1. Opens "Select Google Account" page in a new tab and return the value into redirectUrl. Default prompt is consent, which asked for user permission each time (none for not opening consent page and select account for account select account page).
3641
/// </summary>
3742
/// <param name="clientId"></param>
3843
/// <param name="scopes"></param>
3944
/// <param name="redirectUrl"></param>
45+
/// <param name="promptType"></param>
4046
/// <returns></returns>
41-
public async Task RequestAuthorizationCode(string clientId, List<Scope> scopes, string redirectUrl)
47+
public async Task RequestAuthorizationCode(string clientId, List<Scope> scopes, string redirectUrl, PromptType promptType = PromptType.Consent)
4248
{
4349
string encodedRedirectUrl = HttpUtility.UrlEncode(redirectUrl);
4450
if (scopes == null || scopes.Count == 0)
@@ -52,7 +58,7 @@ public async Task RequestAuthorizationCode(string clientId, List<Scope> scopes,
5258
}
5359
string scopeString = string.Join("+", scopeStringList);
5460

55-
await JSRuntime.InvokeAsync<object>("open", $"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id={clientId}&scope={scopeString}&redirect_uri={encodedRedirectUrl}&flowName=GeneralOAuthFlow&access_type=offline&prompt=consent", "_blank");
61+
await JSRuntime.InvokeAsync<object>("open", $"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id={clientId}&scope={scopeString}&redirect_uri={encodedRedirectUrl}&flowName=GeneralOAuthFlow&access_type=offline&prompt={promptType.ToDescriptionString()}", "_blank");
5662
}
5763

5864
/// <summary>
@@ -77,6 +83,81 @@ public string AuthorizeCredential(string authorizationCode, string clientId, str
7783
return request.Content.ReadAsStringAsync().Result;
7884
}
7985

86+
/// <summary>
87+
/// Refresh and create new access token with given resfresh token.
88+
/// </summary>
89+
/// <param name="refreshToken"></param>
90+
/// <param name="clientId"></param>
91+
/// <param name="clientSecret"></param>
92+
/// <param name="redirectUrl"></param>
93+
/// <returns></returns>
94+
public string RefreshAccessToken(string refreshToken, string clientId, string clientSecret, string redirectUrl)
95+
{
96+
string encodedRedirectUrl = HttpUtility.UrlEncode(redirectUrl);
97+
98+
var client = HttpClientFactory.CreateClient();
99+
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
100+
var content = new StringContent($"refresh_token={refreshToken}&client_id={clientId}&client_secret={clientSecret}&redirect_uri={encodedRedirectUrl}&scope=&grant_type=refresh_token", Encoding.UTF8, "application/x-www-form-urlencoded");
101+
102+
var request = client.PostAsync("https://oauth2.googleapis.com/token", content).Result;
103+
104+
var result = request.Content.ReadAsStringAsync().Result;
105+
106+
var jsonResult = JsonDocument.Parse(result);
107+
string accessToken = jsonResult.RootElement.GetProperty("access_token").ToString();
108+
109+
return accessToken;
110+
}
111+
112+
/// <summary>
113+
/// Get client id. Only works when client id stored in appsettings.json. You can choose the root value that google credentials stored.
114+
/// </summary>
115+
/// <param name="rootValue"></param>
116+
/// <returns></returns>
117+
public string GetClientId(string rootValue = "GoogleClient")
118+
{
119+
return Configuration.GetSection(rootValue).GetSection("client_id").Value;
120+
}
121+
122+
/// <summary>
123+
/// Get client secret. Only works when client id stored in appsettings.json. You can choose the root value that google credentials stored.
124+
/// </summary>
125+
/// <param name="rootValue"></param>
126+
/// <returns></returns>
127+
public string GetClientSecret(string rootValue = "GoogleClient")
128+
{
129+
return Configuration.GetSection(rootValue).GetSection("client_secret").Value;
130+
}
131+
132+
/// <summary>
133+
/// Get project id. Only works when client id stored in appsettings.json. You can choose the root value that google credentials stored.
134+
/// </summary>
135+
/// <param name="rootValue"></param>
136+
/// <returns></returns>
137+
public string GetProjectId(string rootValue = "GoogleClient")
138+
{
139+
return Configuration.GetSection(rootValue).GetSection("project_id").Value;
140+
}
141+
142+
/// <summary>
143+
/// Gets access token expired or not with given content result. Most of the methods' result can be the contentResult parameter directly.
144+
/// </summary>
145+
/// <param name="contentResult"></param>
146+
/// <returns></returns>
147+
public bool IsAccessTokenExpired(string contentResult)
148+
{
149+
var jsonResult = JsonDocument.Parse(contentResult);
150+
string errorMessage = jsonResult.RootElement.GetPropertyExtension("error")?.GetProperty("errors")[0].GetProperty("message").ToString();
151+
string errorReason = jsonResult.RootElement.GetPropertyExtension("error")?.GetProperty("errors")[0].GetProperty("reason").ToString();
152+
153+
if (errorMessage == "Invalid Credentials" || errorReason == "authError")
154+
{
155+
return true;
156+
}
157+
158+
return false;
159+
}
160+
80161
/// <summary>
81162
/// Get authenticated user's e-mail adress.
82163
/// </summary>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma warning disable CS1591
2+
using System.ComponentModel;
3+
4+
namespace GoogleApis.Blazor.Extensions
5+
{
6+
public static class EnumExtensions
7+
{
8+
public static string ToDescriptionString(this Enum val)
9+
{
10+
var attributes = (DescriptionAttribute[])val.GetType().GetField(val.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
11+
12+
return attributes.Length > 0
13+
? attributes[0].Description
14+
: val.ToString();
15+
}
16+
}
17+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Text.Json;
2+
#pragma warning disable CS1591
3+
namespace GoogleApis.Blazor.Extensions
4+
{
5+
public static class JsonElementExtenstion
6+
{
7+
public static JsonElement? GetPropertyExtension(this JsonElement jsonElement, string propertyName)
8+
{
9+
if (jsonElement.TryGetProperty(propertyName, out JsonElement returnElement))
10+
{
11+
return returnElement;
12+
}
13+
14+
return null;
15+
}
16+
}
17+
}

GoogleApis.Blazor/GoogleApis.Blazor.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
<ItemGroup>
2929
<PackageReference Include="Microsoft.AspNetCore.Components" Version="6.0.4" />
30+
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
3031
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
3132
<PackageReference Include="Microsoft.JSInterop" Version="6.0.4" />
3233
</ItemGroup>

0 commit comments

Comments
 (0)