Skip to content

Commit 10649fb

Browse files
committed
Add additional async overloads + convert existing filter attrs to use async APIs
1 parent 2f9cf01 commit 10649fb

19 files changed

+356
-70
lines changed

src/ServiceStack.Authentication.OAuth2/GoogleOAuth2Provider.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public override async Task<object> AuthenticateAsync(IServiceBase authService, I
6969
}
7070
catch (WebException we)
7171
{
72-
string errorBody = we.GetResponseBody();
72+
string errorBody = await we.GetResponseBodyAsync(token);
7373
var statusCode = ((HttpWebResponse)we.Response).StatusCode;
7474
if (statusCode == HttpStatusCode.BadRequest)
7575
{

src/ServiceStack.Common/EnumerableExtensions.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
using System.Collections.Generic;
44
using System.Linq;
55
using System.Runtime.CompilerServices;
6+
using System.Threading.Tasks;
7+
using ServiceStack.Text;
68

79
namespace ServiceStack
810
{
@@ -378,5 +380,68 @@ public static Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(this IEnume
378380

379381
[MethodImpl(MethodImplOptions.AggressiveInlining)]
380382
public static IEnumerable Safe(this IEnumerable enumerable) => enumerable ?? TypeConstants.EmptyObjectArray;
383+
384+
public static async Task<bool> AllAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> predicate)
385+
{
386+
if (source == null)
387+
throw new ArgumentNullException(nameof(source));
388+
if (predicate == null)
389+
throw new ArgumentNullException(nameof(predicate));
390+
foreach (var item in source)
391+
{
392+
var result = await predicate(item).ConfigAwait();
393+
if (!result)
394+
return false;
395+
}
396+
return true;
397+
}
398+
399+
// This is for synchronous predicates with an async source.
400+
public static async Task<bool> AllAsync<T>(this IEnumerable<Task<T>> source, Func<T, bool> predicate)
401+
{
402+
if (source == null)
403+
throw new ArgumentNullException(nameof(source));
404+
if (predicate == null)
405+
throw new ArgumentNullException(nameof(predicate));
406+
foreach (var item in source)
407+
{
408+
var awaitedItem = await item.ConfigAwait();
409+
if (!predicate(awaitedItem))
410+
return false;
411+
}
412+
return true;
413+
}
414+
415+
public static async Task<bool> AnyAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> predicate)
416+
{
417+
if (source == null)
418+
throw new ArgumentNullException(nameof(source));
419+
if (predicate == null)
420+
throw new ArgumentNullException(nameof(predicate));
421+
foreach (var item in source)
422+
{
423+
var result = await predicate(item).ConfigAwait();
424+
if (result)
425+
return true;
426+
}
427+
return false;
428+
}
429+
430+
// This is for synchronous predicates with an async source.
431+
public static async Task<bool> AnyAsync<T>(this IEnumerable<Task<T>> source, Func<T, bool> predicate)
432+
{
433+
if (source == null)
434+
throw new ArgumentNullException(nameof(source));
435+
if (predicate == null)
436+
throw new ArgumentNullException(nameof(predicate));
437+
foreach (var item in source)
438+
{
439+
var awaitedItem = await item.ConfigAwait();
440+
if (predicate(awaitedItem))
441+
return true;
442+
}
443+
return false;
444+
}
445+
381446
}
382447
}

src/ServiceStack.Extensions/Auth/AppleAuthProvider.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,11 +210,11 @@ private static byte[] ConvertPrivateKeyToBytes(string keyText)
210210
return Convert.FromBase64String(keyText);
211211
}
212212

213-
protected override string GetAccessTokenJson(string code)
213+
protected override async Task<string> GetAccessTokenJsonAsync(string code, CancellationToken token=default)
214214
{
215215
var clientSecret = GetClientSecret();
216216
var accessTokenUrl = $"{AccessTokenUrl}?code={code}&client_id={ClientId}&client_secret={clientSecret}&redirect_uri={this.CallbackUrl.UrlEncode()}&grant_type=authorization_code";
217-
var contents = AccessTokenUrlFilter(this, accessTokenUrl).PostToUrl("");
217+
var contents = await AccessTokenUrlFilter(this, accessTokenUrl).PostToUrlAsync("").ConfigAwait();
218218
return contents;
219219
}
220220

src/ServiceStack.Mvc/RazorFormat.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,33 +1214,33 @@ public HtmlString GetErrorHtml()
12141214

12151215
public virtual bool IsAuthenticated => ServiceStackProvider.IsAuthenticated;
12161216

1217-
protected virtual IAuthSession GetSession(bool reload = false) => ServiceStackProvider.GetSession(reload);
1217+
public virtual IAuthSession GetSession(bool reload = false) => ServiceStackProvider.GetSession(reload);
12181218

1219-
protected virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default) =>
1219+
public virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default) =>
12201220
ServiceStackProvider.GetSessionAsync(reload, token);
12211221

1222-
protected virtual IAuthSession UserSession => GetSession();
1222+
public virtual IAuthSession UserSession => GetSession();
12231223

1224-
protected virtual TUserSession SessionAs<TUserSession>() => ServiceStackProvider.SessionAs<TUserSession>();
1224+
public virtual TUserSession SessionAs<TUserSession>() => ServiceStackProvider.SessionAs<TUserSession>();
12251225

1226-
protected virtual Task<TUserSession> SessionAsAsync<TUserSession>(CancellationToken token=default) =>
1226+
public virtual Task<TUserSession> SessionAsAsync<TUserSession>(CancellationToken token=default) =>
12271227
ServiceStackProvider.SessionAsAsync<TUserSession>(token);
12281228

12291229
[Obsolete("Use SaveSessionAsync")]
12301230
protected virtual void SaveSession(IAuthSession session, TimeSpan? expiresIn = null) => ServiceStackProvider.Request.SaveSession(session, expiresIn);
12311231

1232-
protected virtual Task SaveSessionAsync(IAuthSession session, TimeSpan? expiresIn = null, CancellationToken token=default) =>
1232+
public virtual Task SaveSessionAsync(IAuthSession session, TimeSpan? expiresIn = null, CancellationToken token=default) =>
12331233
ServiceStackProvider.Request.SaveSessionAsync(session, expiresIn, token);
12341234

1235-
protected virtual void ClearSession() => ServiceStackProvider.ClearSession();
1235+
public virtual void ClearSession() => ServiceStackProvider.ClearSession();
12361236

1237-
protected virtual Task ClearSessionAsync(CancellationToken token=default) => ServiceStackProvider.ClearSessionAsync(token);
1237+
public virtual Task ClearSessionAsync(CancellationToken token=default) => ServiceStackProvider.ClearSessionAsync(token);
12381238

1239-
protected virtual TDependency TryResolve<TDependency>() => ServiceStackProvider.TryResolve<TDependency>();
1239+
public virtual TDependency TryResolve<TDependency>() => ServiceStackProvider.TryResolve<TDependency>();
12401240

1241-
protected virtual TService ResolveService<TService>() => ServiceStackProvider.ResolveService<TService>();
1241+
public virtual TService ResolveService<TService>() => ServiceStackProvider.ResolveService<TService>();
12421242

1243-
protected virtual object ForwardRequestToServiceStack(IRequest request = null) => ServiceStackProvider.Execute(request ?? ServiceStackProvider.Request);
1243+
public virtual object ForwardRequestToServiceStack(IRequest request = null) => ServiceStackProvider.Execute(request ?? ServiceStackProvider.Request);
12441244

12451245
public virtual IServiceGateway Gateway => ServiceStackProvider.Gateway;
12461246

src/ServiceStack.Mvc/ServiceStackController.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -201,28 +201,28 @@ public override JsonResult Json(object data)
201201

202202
public virtual IAuthSession GetSession(bool reload = true) => ServiceStackProvider.GetSession(reload);
203203

204-
protected virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default) =>
204+
public virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default) =>
205205
ServiceStackProvider.GetSessionAsync(reload, token);
206206

207-
protected virtual Task<TUserSession> SessionAsAsync<TUserSession>(CancellationToken token=default) =>
207+
public virtual Task<TUserSession> SessionAsAsync<TUserSession>(CancellationToken token=default) =>
208208
ServiceStackProvider.SessionAsAsync<TUserSession>(token);
209209

210210
//don't expose public generic methods in MVC Controllers
211-
protected virtual TUserSession SessionAs<TUserSession>() => ServiceStackProvider.SessionAs<TUserSession>();
211+
public virtual TUserSession SessionAs<TUserSession>() => ServiceStackProvider.SessionAs<TUserSession>();
212212

213213
[Obsolete("Use SaveSessionAsync")]
214214
public virtual void SaveSession(IAuthSession session, TimeSpan? expiresIn = null) => ServiceStackProvider.Request.SaveSession(session, expiresIn);
215215

216-
protected virtual Task SaveSessionAsync(IAuthSession session, TimeSpan? expiresIn = null, CancellationToken token=default) =>
216+
public virtual Task SaveSessionAsync(IAuthSession session, TimeSpan? expiresIn = null, CancellationToken token=default) =>
217217
ServiceStackProvider.Request.SaveSessionAsync(session, expiresIn, token);
218218

219219
public virtual void ClearSession() => ServiceStackProvider.ClearSession();
220220

221-
protected virtual Task ClearSessionAsync(CancellationToken token=default) => ServiceStackProvider.ClearSessionAsync(token);
221+
public virtual Task ClearSessionAsync(CancellationToken token=default) => ServiceStackProvider.ClearSessionAsync(token);
222222

223-
protected virtual T TryResolve<T>() => ServiceStackProvider.TryResolve<T>();
223+
public virtual T TryResolve<T>() => ServiceStackProvider.TryResolve<T>();
224224

225-
protected virtual T ResolveService<T>() => ServiceStackProvider.ResolveService<T>();
225+
public virtual T ResolveService<T>() => ServiceStackProvider.ResolveService<T>();
226226

227227
public virtual object ForwardRequestToServiceStack(IRequest request = null) => ServiceStackProvider.Execute(request ?? ServiceStackProvider.Request);
228228

src/ServiceStack/AspNet/ServiceStackPage.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
using System;
44
using System.Data;
5+
using System.Threading;
6+
using System.Threading.Tasks;
57
using System.Web;
68
using System.Web.UI;
79
using ServiceStack.Auth;
@@ -93,28 +95,50 @@ protected virtual void ServiceStack_PreLoad(object sender, EventArgs e)
9395

9496
public new virtual ICacheClient Cache => ServiceStackProvider.Cache;
9597

98+
public virtual ICacheClientAsync CacheAsync => ServiceStackProvider.CacheAsync;
99+
96100
public virtual IDbConnection Db => ServiceStackProvider.Db;
97101

98102
public virtual IRedisClient Redis => ServiceStackProvider.Redis;
103+
104+
#if NET472 || NETSTANDARD2_0
105+
public virtual ValueTask<IRedisClientAsync> GetRedisAsync() => ServiceStackProvider.GetRedisAsync();
106+
#endif
99107

100108
public virtual IMessageProducer MessageProducer => ServiceStackProvider.MessageProducer;
101109

102110
public virtual IAuthRepository AuthRepository => ServiceStackProvider.AuthRepository;
111+
112+
public virtual IAuthRepositoryAsync AuthRepositoryAsync => ServiceStackProvider.AuthRepositoryAsync;
103113

104114
public virtual ISessionFactory SessionFactory => ServiceStackProvider.SessionFactory;
105115

106116
public virtual ISession SessionBag => ServiceStackProvider.SessionBag;
117+
118+
public virtual Caching.ISessionAsync SessionBagAsync => ServiceStackProvider.SessionBagAsync;
107119

108120
public virtual bool IsAuthenticated => ServiceStackProvider.IsAuthenticated;
109121

110122
public virtual IAuthSession GetSession(bool reload = true) => ServiceStackProvider.GetSession(reload);
111123

124+
public virtual Task<IAuthSession> GetSessionAsync(bool reload = false, CancellationToken token=default) =>
125+
ServiceStackProvider.GetSessionAsync(reload, token);
126+
112127
public virtual TUserSession SessionAs<TUserSession>() => ServiceStackProvider.SessionAs<TUserSession>();
113128

129+
public virtual Task<TUserSession> SessionAsAsync<TUserSession>(CancellationToken token=default) =>
130+
ServiceStackProvider.SessionAsAsync<TUserSession>(token);
131+
132+
[Obsolete("Use SaveSessionAsync")]
114133
protected virtual void SaveSession(IAuthSession session, TimeSpan? expiresIn = null) =>
115134
ServiceStackProvider.Request.SaveSession(session, expiresIn);
116135

136+
public virtual Task SaveSessionAsync(IAuthSession session, TimeSpan? expiresIn = null, CancellationToken token=default) =>
137+
ServiceStackProvider.Request.SaveSessionAsync(session, expiresIn, token);
138+
117139
public virtual void ClearSession() => ServiceStackProvider.ClearSession();
140+
141+
public virtual Task ClearSessionAsync(CancellationToken token=default) => ServiceStackProvider.ClearSessionAsync(token);
118142

119143
public virtual T TryResolve<T>() => ServiceStackProvider.TryResolve<T>();
120144

src/ServiceStack/Auth/FacebookAuthProvider.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public override async Task<object> AuthenticateAsync(IServiceBase authService, I
5454
//Transferring AccessToken/Secret from Mobile/Desktop App to Server
5555
if (request?.AccessToken != null)
5656
{
57-
if (!await AuthHttpGateway.VerifyFacebookAccessTokenAsync(AppId, request.AccessToken, token))
57+
if (!await AuthHttpGateway.VerifyFacebookAccessTokenAsync(AppId, request.AccessToken, token).ConfigAwait())
5858
return HttpError.Unauthorized("AccessToken is not for App: " + AppId);
5959

6060
var isHtml = authService.Request.IsHtml();
@@ -86,14 +86,14 @@ public override async Task<object> AuthenticateAsync(IServiceBase authService, I
8686
{
8787
var preAuthUrl = $"{PreAuthUrl}?client_id={AppId}&redirect_uri={this.CallbackUrl.UrlEncode()}&scope={string.Join(",", Permissions)}&{Keywords.State}={session.Id}";
8888

89-
await this.SaveSessionAsync(authService, session, SessionExpiry, token: token);
89+
await this.SaveSessionAsync(authService, session, SessionExpiry, token).ConfigAwait();
9090
return authService.Redirect(PreAuthUrlFilter(this, preAuthUrl));
9191
}
9292

9393
try
9494
{
9595
var accessTokenUrl = $"{AccessTokenUrl}?client_id={AppId}&redirect_uri={this.CallbackUrl.UrlEncode()}&client_secret={AppSecret}&code={code}";
96-
var contents = await AccessTokenUrlFilter(this, accessTokenUrl).GetJsonFromUrlAsync();
96+
var contents = await AccessTokenUrlFilter(this, accessTokenUrl).GetJsonFromUrlAsync().ConfigAwait();
9797
var authInfo = JsonObject.Parse(contents);
9898

9999
var accessToken = authInfo["access_token"];

src/ServiceStack/Auth/GithubAuthProvider.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,14 @@ public override async Task<object> AuthenticateAsync(IServiceBase authService, I
101101
var scopes = Scopes.Join("%20");
102102
string preAuthUrl = $"{PreAuthUrl}?client_id={ClientId}&redirect_uri={CallbackUrl.UrlEncode()}&scope={scopes}&{Keywords.State}={session.Id}";
103103

104-
this.SaveSession(authService, session, SessionExpiry);
104+
await this.SaveSessionAsync(authService, session, SessionExpiry, token).ConfigAwait();
105105
return authService.Redirect(PreAuthUrlFilter(this, preAuthUrl));
106106
}
107107

108108
try
109109
{
110110
string accessTokenUrl = $"{AccessTokenUrl}?client_id={ClientId}&redirect_uri={CallbackUrl.UrlEncode()}&client_secret={ClientSecret}&code={code}";
111-
var contents = AccessTokenUrlFilter(this, accessTokenUrl).GetStringFromUrl();
111+
var contents = await AccessTokenUrlFilter(this, accessTokenUrl).GetStringFromUrlAsync().ConfigAwait();
112112
var authInfo = PclExportClient.Instance.ParseQueryString(contents);
113113

114114
//GitHub does not throw exception, but just return error with descriptions
@@ -144,7 +144,7 @@ protected virtual async Task<object> AuthenticateWithAccessTokenAsync(IServiceBa
144144
{
145145
tokens.AccessTokenSecret = accessToken;
146146

147-
var json = await AuthHttpGateway.DownloadGithubUserInfoAsync(accessToken, token);
147+
var json = await AuthHttpGateway.DownloadGithubUserInfoAsync(accessToken, token).ConfigAwait();
148148
var authInfo = JsonObject.Parse(json);
149149

150150
session.IsAuthenticated = true;

src/ServiceStack/Auth/IAuthSession.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Threading.Tasks;
34
using ServiceStack.Web;
45

56
namespace ServiceStack.Auth
@@ -29,7 +30,9 @@ public interface IAuthSession
2930
string Sequence { get; set; }
3031

3132
bool HasRole(string role, IAuthRepository authRepo);
33+
Task<bool> HasRoleAsync(string role, IAuthRepositoryAsync authRepo);
3234
bool HasPermission(string permission, IAuthRepository authRepo);
35+
Task<bool> HasPermissionAsync(string permission, IAuthRepositoryAsync authRepo);
3336

3437
bool IsAuthorized(string provider);
3538

src/ServiceStack/Auth/MicrosoftGraphAuthProvider.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,11 @@ public MicrosoftGraphAuthProvider(IAppSettings appSettings)
8181
};
8282
}
8383

84-
protected override string GetAccessTokenJson(string code)
84+
protected override async Task<string> GetAccessTokenJsonAsync(string code, CancellationToken token = default)
8585
{
8686
var accessTokenParams = $"code={code}&client_id={ConsumerKey}&client_secret={ConsumerSecret}&redirect_uri={this.CallbackUrl.UrlEncode()}&grant_type=authorization_code";
87-
var contents = AccessTokenUrlFilter(this, AccessTokenUrl)
88-
.PostToUrl(accessTokenParams, requestFilter:req => req.ContentType = MimeTypes.FormUrlEncoded);
87+
var contents = await AccessTokenUrlFilter(this, AccessTokenUrl)
88+
.PostToUrlAsync(accessTokenParams, requestFilter:req => req.ContentType = MimeTypes.FormUrlEncoded).ConfigAwait();
8989
return contents;
9090
}
9191

0 commit comments

Comments
 (0)