0

The Situation

I'm working on a OAuth2 Api Wrapper. Some api routes are for logged people and some for anonymous and logged.

Here is an example of one method in my wrapper :

public async Task<UploadListResponse> List(bool pagination = false, int page = 1, int limit = 10)
    {
        var request = UploadRequests.List(pagination, page, limit);

        var cancellationTokenSource = new CancellationTokenSource();

        var restResponse = await Context.Client.ExecuteTaskAsync(request, cancellationTokenSource.Token);

        return restResponse.Handle<UploadListResponse>();
    }

I build a request with all parameter set up then execute the request and then handle the answer in case I have an api error and then output an object containing all the data that request gave me.

The problem

With OAuth2, when you log to the API you'll receive an access token and a refresh token. If your access token is expired you have to contact the api with your refresh token to get a fresh new access token.

As I said earlier some of my method needs you to be logged but if your access token is expired I want to try to refresh token before throwing an exception like with this method :

public async Task<bool> NeedRelog()
    {
        try
        {
            var validAuth = await ValidAuth();
        }
        catch
        {
            try
            {
                var refresh = await Refresh(Context.Client.Config.RefreshToken);
            }
            catch
            {
                return true;
            }
        }
        return false;
    }

ValidAuth check with the API if you are logged and if I have an exception then I'll try to refreshToken.

I want to tag method that need logged to call NeedRelog() and those who aren't tag to not call it.

I may just do it in every method but it wouldn't be clean.

What I've done so far

I've found a great tool : PostSharp that seems to fit my needs.

I've started to do a checkLog aspect like this :

[Serializable]
public class CheckLog : OnMethodBoundaryAspect, IOnStateMachineBoundaryAspect
{
    public CheckLog()
    {
        ApplyToStateMachine = false;
    }

    public override void OnEntry(MethodExecutionArgs args)
    {
        var instance = (ApiService)args.Instance;
        var res = instance.Parent.OAuth.NeedRelog().Result;

        if (!res)
        {
            args.Exception = new Exception("Need to relog");
            args.FlowBehavior = FlowBehavior.Return;
        }
    }
}

Where I'm stuck

The Main problem is with the call to my NeedRelog() Method. Due to the fact this is an async method I'm struggling to make my aspect await for it.

  • If my OnEntry method is async then It won't block the call if you are not logged.
  • If my OnEntry method is not async and I wait for needLog it freeze and nothing happen.

I really want to know to use this kind of "conditional method call" with postsharp, it looks awesome but the fact is after looking for hours in the documentation I didn't find a way to do what I want.

I'm starting to ask myself if it is even possible to achieve what I'm aiming to do.

1 Answers1

1

Did you try using a way to make the call synchronous maybe with something like this stackoverflow.com/a/25097498/3131696 ? – M22an 5 hours ago

As I can't mark a comment as answering a question I quote your comment to make this question answered as it is said here : link

Thanks you for this M22an.

Community
  • 1
  • 1