////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        private static App ValidateAndGetApp(IOperationContext pOpCtx, IOauthLoginTasks pTasks,
                                             string pClientId, string pRedirUri)
        {
            if (pRedirUri == null || pRedirUri.Length <= 0)
            {
                throw pTasks.NewFault(LoginErrors.invalid_request, LoginErrorDescs.NoRedirUri);
            }

            long appId = pTasks.AppIdToLong(pClientId);
            App  app   = pTasks.GetApp(pOpCtx.Data, appId);

            pTasks.VerifyAppDomain(app, pRedirUri);
            return(app);
        }
        /*--------------------------------------------------------------------------------------------*/
        public OauthLoginResult ExecuteScope(IOperationContext pOpCtx, IOauthLoginTasks pTasks,
                                             string pClientId, string pRedirUri, bool pAllowScope)
        {
            App app = ValidateAndGetApp(pOpCtx, pTasks, pClientId, pRedirUri);

            if (pOpCtx.Auth.CookieUserId == null)
            {
                throw pTasks.NewFault(LoginErrors.access_denied, LoginErrorDescs.NotLoggedIn);
            }

            //The member may not be ready immediately after the first login.
            var    sw     = Stopwatch.StartNew();
            long   userId = (long)pOpCtx.Auth.CookieUserId;
            Member mem    = null;

            while (mem == null)
            {
                if (sw.ElapsedMilliseconds > 10000)
                {
                    pTasks.NewFault(LoginErrors.server_error, LoginErrorDescs.Unexpected);
                }

                mem = pTasks.GetMember(pOpCtx.Data, app.VertexId, userId);

                if (mem == null)
                {
                    Thread.Sleep(200);
                }
            }

            if (!pAllowScope)
            {
                pTasks.DenyScope(pOpCtx.Data, mem);
                throw pTasks.NewFault(LoginErrors.access_denied, LoginErrorDescs.AccessDeny);
            }

            pTasks.UpdateGrant(pOpCtx, mem, pRedirUri);

            return(new OauthLoginResult {
                Redirect = pRedirUri,
                Code = mem.OauthGrantCode
            });
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        public OauthLoginResult ExecuteLogin(IOperationContext pOpCtx, IOauthLoginTasks pTasks,
                                             string pClientId, string pRedirUri, string pUsername, string pPassword)
        {
            var result = new OauthLoginResult();

            App app = ValidateAndGetApp(pOpCtx, pTasks, pClientId, pRedirUri);

            result.AppId   = app.VertexId;
            result.AppName = app.Name;

            User user = pTasks.GetUserByCredentials(pOpCtx.Data, pUsername, pPassword);

            if (user == null)
            {
                result.ShowLoginPage  = true;
                result.LoginErrorText = "The Username or Password was incorrect.";
                return(result);
            }

            result.LoggedUserId   = user.VertexId;
            result.LoggedUserName = user.Name;

            Member mem = pTasks.GetMember(pOpCtx.Data, app.VertexId, user.VertexId);

            if (mem == null)
            {
                mem = pTasks.AddMember(pOpCtx,
                                       new CreateMemberOperation(), app.VertexId, user.VertexId);
            }

            if (mem.OauthScopeAllow == true)
            {
                result.Code     = mem.OauthGrantCode;
                result.Redirect = pRedirUri;
            }

            return(result);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////
        /*--------------------------------------------------------------------------------------------*/
        public OauthLoginResult Execute(IOperationContext pOpCtx, IOauthLoginTasks pTasks,
                                        string pClientId, string pRedirUri, string pResponseType, string pSwitchMode)
        {
            /*var fake = new OauthLoginResult();
             * fake.ShowLoginPage = false;
             * fake.AppId = 123;
             * fake.AppName = "Test App";
             * fake.LoggedUserId = 345;
             * fake.LoggedUserName = "******";
             * fake.Code = "TestCode";
             * fake.Redirect = "http://test.redirect.url";
             * return fake;*/

            if (pResponseType != "code")
            {
                throw pTasks.NewFault(LoginErrors.invalid_request, LoginErrorDescs.BadRespType);
            }

            if (pSwitchMode != null && pSwitchMode != "0" && pSwitchMode != "1")
            {
                throw pTasks.NewFault(LoginErrors.invalid_request, LoginErrorDescs.BadSwitch);
            }

            if (pRedirUri == null || pRedirUri.Length <= 0)
            {
                throw pTasks.NewFault(LoginErrors.invalid_request, LoginErrorDescs.NoRedirUri);
            }

            long appId = pTasks.AppIdToLong(pClientId);
            App  app   = pTasks.GetApp(pOpCtx.Data, appId);

            pTasks.VerifyAppDomain(app, pRedirUri);

            var  result     = new OauthLoginResult();
            bool forceLogin = (pSwitchMode == "1");
            long?userId     = pOpCtx.Auth.CookieUserId;

            if (userId != null)
            {
                Member mem = pTasks.GetMember(pOpCtx.Data, appId, (long)userId);

                if (mem.OauthScopeAllow == true && !forceLogin)
                {
                    pTasks.UpdateGrant(pOpCtx, mem, pRedirUri);

                    result.Code     = mem.OauthGrantCode;
                    result.Redirect = mem.OauthGrantRedirectUri;
                    return(result);
                }
            }

            User user = (userId == null ? null : pTasks.GetUser(pOpCtx.Data, (long)userId));

            result.ShowLoginPage  = (user == null || forceLogin);
            result.AppId          = appId;
            result.AppName        = app.Name;
            result.LoggedUserId   = (user == null ? 0 : user.VertexId);
            result.LoggedUserName = (user == null ? null : user.Name);

            return(result);
        }
 /*--------------------------------------------------------------------------------------------*/
 public void ExecuteCancel(IOauthLoginTasks pTasks)
 {
     throw pTasks.NewFault(LoginErrors.access_denied, LoginErrorDescs.LoginCancel);
 }