зеркало из https://github.com/microsoft/winsdkfb.git
Fix up other sample apps to handle app deauthorized and individual permissions revoked by re-requesting.
This commit is contained in:
Родитель
5400c4d092
Коммит
aa5cd013a5
|
@ -86,7 +86,14 @@ DateTime FBAccessTokenData::ExpirationDate::get()
|
|||
|
||||
IMapView<String^, String^>^ FBAccessTokenData::Permissions::get()
|
||||
{
|
||||
return m_permissions->GetView();
|
||||
IMapView<String^, String^>^ result = nullptr;
|
||||
|
||||
if (m_permissions)
|
||||
{
|
||||
result = m_permissions->GetView();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String^ FBAccessTokenData::UserID::get()
|
||||
|
|
|
@ -19,19 +19,19 @@
|
|||
namespace Facebook
|
||||
{
|
||||
/*!
|
||||
* \brief error categories.
|
||||
* \brief error codes.
|
||||
*/
|
||||
public enum class ErrorCategory
|
||||
public enum class ErrorCode : int
|
||||
{
|
||||
ErrorCategoryInvalid = 0,
|
||||
ErrorCategoryRetry = 1,
|
||||
ErrorCategoryAuthenticateReopenSession = 2,
|
||||
ErrorCategoryPermissions = 3,
|
||||
ErrorCategoryServer = 4,
|
||||
ErrorCategoryThrottling = 5,
|
||||
ErrorCategoryUserCancelled = 6,
|
||||
ErrorCategoryFacebookOther = -1,
|
||||
ErrorCategoryBadRequest = -2
|
||||
ErrorCodeOauthException = 190
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief error subcodes.
|
||||
*/
|
||||
public enum class ErrorSubcode : int
|
||||
{
|
||||
ErrorSubcodeSessionInvalidated = 466
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -854,10 +854,9 @@ IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
|||
return create_task([=]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
task<FBResult^> authTask;
|
||||
|
||||
//task<FBResult^> authTask = TryLoginViaWebView(Parameters);
|
||||
//result = authTask.get();
|
||||
task<FBResult^> authTask = TryLoginViaWebView(Parameters);
|
||||
result = authTask.get();
|
||||
if (!result)
|
||||
{
|
||||
authTask = TryLoginViaWebAuthBroker(Parameters);
|
||||
|
@ -873,6 +872,16 @@ IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
|||
.then([this](FBResult^ userInfoResult) -> task<FBResult^>
|
||||
{
|
||||
return TryGetAppPermissionsAfterLogin(userInfoResult);
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (!finalResult->Succeeded)
|
||||
{
|
||||
m_loggedIn = false;
|
||||
AccessTokenData = nullptr;
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -63,22 +63,26 @@ MainPage::MainPage()
|
|||
{
|
||||
InitializeComponent();
|
||||
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
|
||||
OutputDebugString(whatever->Data());
|
||||
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
// TODO: Commenting this out for now - resource loader isn't working for me in UWP app.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
|
@ -98,6 +102,7 @@ String^ MainPage::BuildPermissionsString(
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
|
@ -110,7 +115,7 @@ BOOL MainPage::DidGetAllRequestedPermissions(
|
|||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
String^ perm = ref new String(requested_permissions[i]);
|
||||
if (data->Permissions->HasKey(perm))
|
||||
if (data->Permissions && (data->Permissions->HasKey(perm)))
|
||||
{
|
||||
String^ Value = data->Permissions->Lookup(perm);
|
||||
if (!String::CompareOrdinal(Value, PermissionGranted))
|
||||
|
@ -154,6 +159,20 @@ void MainPage::NavigateToOptionsPage()
|
|||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
@ -172,28 +191,44 @@ void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::Rout
|
|||
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (DidGetAllRequestedPermissions())
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
parameters->Insert(L"auth_type", L"rerequest");
|
||||
create_task(sess->LoginAsync(parameters))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,9 @@ namespace LoginCpp
|
|||
MainPage();
|
||||
|
||||
private:
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
);
|
||||
|
||||
|
@ -43,6 +46,10 @@ namespace LoginCpp
|
|||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
|
|
|
@ -47,72 +47,184 @@ using namespace Facebook;
|
|||
|
||||
#define FBAppIDName L"FBApplicationId"
|
||||
#define FBStoreAppIDName L"FBWindowsAppId"
|
||||
#define PermissionGranted L"granted"
|
||||
|
||||
const wchar_t* requested_permissions[] =
|
||||
{
|
||||
L"public_profile",
|
||||
L"user_friends",
|
||||
L"user_likes",
|
||||
L"user_groups",
|
||||
L"user_location"
|
||||
};
|
||||
|
||||
MainPage::MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
)
|
||||
{
|
||||
String^ result = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
result += L",";
|
||||
}
|
||||
|
||||
result += ref new String(requested_permissions[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
|
||||
unsigned int grantedCount = 0;
|
||||
|
||||
if (data)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
String^ perm = ref new String(requested_permissions[i]);
|
||||
if (data->Permissions && (data->Permissions->HasKey(perm)))
|
||||
{
|
||||
String^ Value = data->Permissions->Lookup(perm);
|
||||
if (!String::CompareOrdinal(Value, PermissionGranted))
|
||||
{
|
||||
grantedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grantedCount == ARRAYSIZE(requested_permissions))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
sess->Logout();
|
||||
LoginButton->Content = L"Logout";
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(MainPage::typeid);
|
||||
}
|
||||
else
|
||||
{
|
||||
sess->AddPermission("public_profile");
|
||||
sess->AddPermission("user_friends");
|
||||
sess->AddPermission("user_likes");
|
||||
sess->AddPermission("user_groups");
|
||||
sess->AddPermission("user_location");
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
sess->Logout();
|
||||
LoginButton->Content = L"Logout";
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(MainPage::typeid);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
|
||||
create_task(sess->LoginAsync()).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,22 @@ namespace LoginCpp
|
|||
MainPage();
|
||||
|
||||
private:
|
||||
void login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
void login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -46,25 +46,22 @@ using namespace Facebook;
|
|||
|
||||
#define FBAppIDName L"FBApplicationId"
|
||||
#define FBPhoneAppIDName L"FBWinPhoneAppId"
|
||||
#define PermissionGranted L"granted"
|
||||
|
||||
const wchar_t* requested_permissions[] =
|
||||
{
|
||||
L"public_profile",
|
||||
L"user_friends",
|
||||
L"user_likes",
|
||||
L"user_groups",
|
||||
L"user_location"
|
||||
};
|
||||
|
||||
|
||||
MainPage::MainPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBPhoneAppIDName);
|
||||
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -100,57 +97,166 @@ void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
|
|||
}
|
||||
}
|
||||
|
||||
void LoginCpp::MainPage::LoginButton_Click(
|
||||
Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
)
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
// Get the active session, set it up with the parameters it needs, and
|
||||
// start Login process.
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
sess->Logout();
|
||||
LoginButton->Content = L"Login";
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(MainPage::typeid);
|
||||
}
|
||||
else
|
||||
{
|
||||
sess->AddPermission("public_profile");
|
||||
sess->AddPermission("user_friends");
|
||||
sess->AddPermission("user_likes");
|
||||
sess->AddPermission("user_groups");
|
||||
sess->AddPermission("user_location");
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been saved
|
||||
// in the default resource file.
|
||||
ResourceLoader^ rl = ResourceLoader::GetForCurrentView();
|
||||
|
||||
create_task(sess->LoginAsync()).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBPhoneAppIDName);
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
String^ MainPage::BuildPermissionsString(
|
||||
)
|
||||
{
|
||||
String^ result = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
result += L",";
|
||||
}
|
||||
|
||||
result += ref new String(requested_permissions[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
|
||||
unsigned int grantedCount = 0;
|
||||
|
||||
if (data)
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
String^ perm = ref new String(requested_permissions[i]);
|
||||
if (data->Permissions && (data->Permissions->HasKey(perm)))
|
||||
{
|
||||
String^ Value = data->Permissions->Lookup(perm);
|
||||
if (!String::CompareOrdinal(Value, PermissionGranted))
|
||||
{
|
||||
grantedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grantedCount == ARRAYSIZE(requested_permissions))
|
||||
{
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
// We're redirecting to a page that shows simple user info, so
|
||||
// have to dispatch back to the UI thread.
|
||||
CoreWindow^ wind = CoreApplication::MainView->CoreWindow;
|
||||
|
||||
if (wind)
|
||||
{
|
||||
CoreDispatcher^ disp = wind->Dispatcher;
|
||||
if (disp)
|
||||
{
|
||||
disp->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task<FBResult^> MainPage::LoginViaRerequest(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
Parameters->Insert(L"auth_type", L"rerequest");
|
||||
return create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
SetSessionAppIds();
|
||||
|
||||
return FBSession::ActiveSession->LoginAsync(Parameters);
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LoginButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
sess->Logout();
|
||||
LoginButton->Content = L"Logout";
|
||||
LoginCpp::App^ a = dynamic_cast<LoginCpp::App^>(Application::Current);
|
||||
Windows::UI::Xaml::Controls::Frame^ f = a->CreateRootFrame();
|
||||
f->Navigate(MainPage::typeid);
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
|
||||
parameters->Insert(L"scope", BuildPermissionsString());
|
||||
|
||||
create_task(sess->LoginAsync(parameters)).then([=](FBResult^ result)
|
||||
{
|
||||
task<FBResult^> nextResult = create_task([=]()
|
||||
{
|
||||
return result;
|
||||
});
|
||||
|
||||
if ((!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == 190) && (result->ErrorInfo->Subcode == 466)))
|
||||
{
|
||||
nextResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
|
||||
return nextResult;
|
||||
})
|
||||
.then([=](FBResult^ loginResult)
|
||||
{
|
||||
task<FBResult^> finalResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
if (!DidGetAllRequestedPermissions())
|
||||
{
|
||||
finalResult = LoginViaRerequest(parameters);
|
||||
}
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (finalResult->Succeeded)
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,23 @@ namespace LoginCpp
|
|||
private:
|
||||
void StartLogin(
|
||||
Facebook::FBSession^ Session
|
||||
);
|
||||
);
|
||||
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Platform::String^ BuildPermissionsString(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> MainPage::LoginViaRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
void LoginButton_Click(
|
||||
Platform::Object^ sender,
|
||||
|
|
|
@ -47,6 +47,64 @@ namespace LoginCs
|
|||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private const string _granted = "granted";
|
||||
|
||||
private string[] requested_permissions =
|
||||
{
|
||||
"public_profile",
|
||||
"email",
|
||||
"user_friends",
|
||||
"publish_actions"
|
||||
};
|
||||
|
||||
private string BuildPermissionsString()
|
||||
{
|
||||
string permissions = "";
|
||||
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
permissions += ",";
|
||||
}
|
||||
|
||||
permissions += requested_permissions[i];
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
private bool DidGetRequestedPermissions(
|
||||
)
|
||||
{
|
||||
bool gotPermissions = false;
|
||||
uint grantedCount = 0;
|
||||
|
||||
if (FBSession.ActiveSession.AccessTokenData != null)
|
||||
{
|
||||
IReadOnlyDictionary<string, string> Permissions =
|
||||
FBSession.ActiveSession.AccessTokenData.Permissions;
|
||||
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
if (Permissions.ContainsKey(requested_permissions[i]))
|
||||
{
|
||||
if (String.CompareOrdinal(Permissions[requested_permissions[i]], _granted) == 0)
|
||||
{
|
||||
grantedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (grantedCount == requested_permissions.Length)
|
||||
{
|
||||
gotPermissions = true;
|
||||
}
|
||||
}
|
||||
|
||||
return gotPermissions;
|
||||
}
|
||||
|
||||
private async void LoginToFB()
|
||||
{
|
||||
Uri endURI =
|
||||
|
@ -55,11 +113,35 @@ namespace LoginCs
|
|||
PropertySet parameters = new PropertySet();
|
||||
|
||||
parameters.Add(new KeyValuePair<String, Object>("scope",
|
||||
"public_profile,email,user_friends,publish_actions"));
|
||||
BuildPermissionsString()));
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
if ((!result.Succeeded) &&
|
||||
(((ErrorCode)result.ErrorInfo.Code == ErrorCode.ErrorCodeOauthException) &&
|
||||
((ErrorSubcode)result.ErrorInfo.Subcode == ErrorSubcode.ErrorSubcodeSessionInvalidated)))
|
||||
{
|
||||
parameters.Add(new KeyValuePair<String, Object>("auth_type", "rerequest"));
|
||||
result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
}
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
if (DidGetRequestedPermissions())
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!parameters.ContainsKey("auth_type"))
|
||||
{
|
||||
parameters.Add(new KeyValuePair<String, Object>("auth_type", "rerequest"));
|
||||
}
|
||||
result = await FBSession.ActiveSession.LoginAsync(parameters);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче