зеркало из https://github.com/microsoft/winsdkfb.git
Merge pull request #44 from Microsoft/3_rerequest_permissions
3 rerequest permissions
This commit is contained in:
Коммит
c76878059b
|
@ -1,4 +1,5 @@
|
|||
.nuget
|
||||
*.csproj.user
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.suo
|
||||
|
|
|
@ -318,6 +318,7 @@ popd
|
|||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaObject.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaStream.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPaginatedArray.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.h" />
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml.h">
|
||||
<DependentUpon>..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
|
@ -355,6 +356,7 @@ popd
|
|||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaObject.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookMediaStream.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPaginatedArray.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.cpp" />
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml.cpp">
|
||||
<DependentUpon>..\..\FBWinSDK\FBWinSDK.Shared\FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
</ClCompile>
|
||||
|
|
|
@ -117,6 +117,9 @@
|
|||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\ScaleConverter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\FBWinSDK\FBWinSDK.Shared\Generated\FBAppRequest.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -208,6 +211,9 @@
|
|||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\ScaleConverter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\FacebookPermissions.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\FBWinSDK\FBWinSDK.Shared\Generated\FBAppRequest.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaObject.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaStream.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPermissions.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePicture.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml.h">
|
||||
<DependentUpon>$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml</DependentUpon>
|
||||
</ClInclude>
|
||||
|
@ -63,6 +65,7 @@
|
|||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaObject.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaStream.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPermissions.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBAppRequest.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBCursors.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBGroup.cpp" />
|
||||
|
@ -137,4 +140,4 @@
|
|||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePicture.xml" />
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePictureData.xml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -1,329 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookAccessTokenData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookError.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookFeedRequest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookResult.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookSession.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookAppRequest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookClient.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaStream.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)JsonClassFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)SDKMessage.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)HttpMethod.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPaging.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPermission.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBUser.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FBSingleValue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookLoginButton.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ScaleConverter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBCursors.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBGroup.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPage.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ColorLuminosityConverter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)HlsColor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBProfilePicture.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBProfilePictureData.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBAppRequest.h">
|
||||
<Filter>Generated Code\Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)pch.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookAccessTokenData.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookError.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookResult.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookSession.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookAppRequest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookFeedRequest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ColorLuminosityConverter.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookAccessTokenData.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookAppRequest.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookClient.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookError.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookFeedRequest.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookLoginButton.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaObject.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaStream.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPermissions.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBAppRequest.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBCursors.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBGroup.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPage.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookClient.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookMediaStream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPage.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBCursors.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBGroup.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPaging.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPermission.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBUser.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FBSingleValue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookLoginButton.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ScaleConverter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ColorLuminosityConverter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)HlsColor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBProfilePicture.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBProfilePictureData.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBAppRequest.cpp">
|
||||
<Filter>Generated Code\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookResult.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FacebookSession.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPaging.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBPermission.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)FBSingleValue.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBProfilePicture.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBProfilePictureData.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)Generated\FBUser.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)HlsColor.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)pch.cpp" />
|
||||
<ClCompile Include="$(MSBuildThisFileDirectory)ScaleConverter.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{6fda0532-8f76-4061-805f-cadacc3567c1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{19282f9a-e3ac-43d5-8f16-4a166f4446c4}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Dialogs">
|
||||
<UniqueIdentifier>{185de443-a507-413c-8f10-dfdfca8c41f3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Object Templates">
|
||||
<UniqueIdentifier>{abf1700a-de38-49e0-ab23-e41f4ee96a66}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Object Templates\Header Files">
|
||||
<UniqueIdentifier>{237da76a-f2e5-4e11-8bb8-716dff7e1a71}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Object Templates\Source Files">
|
||||
<UniqueIdentifier>{58814571-c055-464e-9a3c-c8f0d8d7f63d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Object Templates\Base Files">
|
||||
<UniqueIdentifier>{8a6dbed3-7173-4ed1-895e-ad685d0c0c50}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Generated Code">
|
||||
<UniqueIdentifier>{c2211756-eeee-429b-b19a-acb8080b4a2e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Generated Code\Header Files">
|
||||
<UniqueIdentifier>{89875dc9-21a5-45e6-baee-bd86a737a7e1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Generated Code\Source Files">
|
||||
<UniqueIdentifier>{5fcce5e7-7283-4e6b-a5cc-24782d389f3f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Object Templates\Class Definitions">
|
||||
<UniqueIdentifier>{aa250d6e-590e-40b6-aaf0-e4e36baed9b6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Images">
|
||||
<UniqueIdentifier>{5ad83b80-62f4-45a1-ae13-9111ee04a1e2}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Themes">
|
||||
<UniqueIdentifier>{0a1b477a-dafa-4fce-847b-3ba6c88b08f6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ColorLuminosityConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookAccessTokenData.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookAppRequest.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookClient.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookError.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookFeedRequest.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookLoginButton.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaObject.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookMediaStream.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPaginatedArray.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookPermissions.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePicture.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookResult.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FacebookSession.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBAppRequest.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBCursors.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBGroup.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPage.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPaging.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBPermission.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)FBSingleValue.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBProfilePicture.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBProfilePictureData.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)Generated\FBUser.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)HlsColor.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)HttpMethod.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)JsonClassFactory.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)pch.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)ScaleConverter.h" />
|
||||
<ClInclude Include="$(MSBuildThisFileDirectory)SDKMessage.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBAppRequest.xml" />
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePicture.xml" />
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePictureData.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="$(MSBuildThisFileDirectory)Images\fb_blank_profile_portrait.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBAppRequest.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBAppRequest.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGraphObjectHeader.ttinclude" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGraphObjectImplementation.ttinclude" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPage.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPage.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPageCategory.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPageCategory.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePicture.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePictureData.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePictureData.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.cpp.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.h.tt" />
|
||||
<None Include="$(MSBuildThisFileDirectory)Utility.ttinclude" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FacebookPage.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FacebookPageCategory.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.xml" />
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml" />
|
||||
<Page Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml">
|
||||
<Filter>Dialogs</Filter>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Generic.xaml">
|
||||
<Filter>Themes</Filter>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles.xaml">
|
||||
<Filter>Themes</Filter>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Controls\FacebookLoginButton.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPage.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPageCategory.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPage.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPageCategory.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGraphObjectHeader.ttinclude">
|
||||
<Filter>Object Templates\Base Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGraphObjectImplementation.ttinclude">
|
||||
<Filter>Object Templates\Base Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Utility.ttinclude">
|
||||
<Filter>Object Templates\Base Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FacebookPage.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FacebookPageCategory.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBCursors.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBGroup.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPaging.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBPermission.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBUser.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePicture.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePictureData.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBProfilePictureData.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBAppRequest.h.tt">
|
||||
<Filter>Object Templates\Header Files</Filter>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)FBAppRequest.cpp.tt">
|
||||
<Filter>Object Templates\Source Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="$(MSBuildThisFileDirectory)Images\fb_blank_profile_portrait.png">
|
||||
<Filter>Images</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePicture.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</Xml>
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBProfilePictureData.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</Xml>
|
||||
<Xml Include="$(MSBuildThisFileDirectory)FBAppRequest.xml">
|
||||
<Filter>Object Templates\Class Definitions</Filter>
|
||||
</Xml>
|
||||
<Page Include="$(MSBuildThisFileDirectory)FacebookDialog.xaml" />
|
||||
<Page Include="$(MSBuildThisFileDirectory)FacebookProfilePictureControl.xaml" />
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Generic.xaml" />
|
||||
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -41,7 +41,8 @@ FBAccessTokenData::FBAccessTokenData(
|
|||
) :
|
||||
_accessToken(AccessToken),
|
||||
_appId(nullptr),
|
||||
_permissions(nullptr),
|
||||
_grantedPermissions(nullptr),
|
||||
_declinedPermissions(nullptr),
|
||||
_userId(nullptr)
|
||||
{
|
||||
if (Expiration)
|
||||
|
@ -60,13 +61,15 @@ FBAccessTokenData::FBAccessTokenData(
|
|||
) :
|
||||
_accessToken(AccessToken),
|
||||
_appId(nullptr),
|
||||
_permissions(nullptr),
|
||||
_grantedPermissions(nullptr),
|
||||
_declinedPermissions(nullptr),
|
||||
_userId(nullptr),
|
||||
_expirationDate(Expiration)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
DebugPrintExpirationTime();
|
||||
#endif
|
||||
InitPermissions();
|
||||
}
|
||||
|
||||
String^ FBAccessTokenData::AccessToken::get()
|
||||
|
@ -84,9 +87,14 @@ DateTime FBAccessTokenData::ExpirationDate::get()
|
|||
return _expirationDate;
|
||||
}
|
||||
|
||||
IMapView<String^, String^>^ FBAccessTokenData::Permissions::get()
|
||||
FBPermissions^ FBAccessTokenData::GrantedPermissions::get()
|
||||
{
|
||||
return _permissions->GetView();
|
||||
return _grantedPermissions;
|
||||
}
|
||||
|
||||
FBPermissions^ FBAccessTokenData::DeclinedPermissions::get()
|
||||
{
|
||||
return _declinedPermissions;
|
||||
}
|
||||
|
||||
String^ FBAccessTokenData::UserID::get()
|
||||
|
@ -94,6 +102,14 @@ String^ FBAccessTokenData::UserID::get()
|
|||
return _userId;
|
||||
}
|
||||
|
||||
void FBAccessTokenData::InitPermissions()
|
||||
{
|
||||
Vector<String^>^ v = ref new Vector<String^>(0);
|
||||
|
||||
_grantedPermissions = ref new FBPermissions(v->GetView());
|
||||
_declinedPermissions = ref new FBPermissions(v->GetView());
|
||||
}
|
||||
|
||||
WwwFormUrlDecoder^ FBAccessTokenData::ParametersFromResponse(
|
||||
Uri^ Response
|
||||
)
|
||||
|
@ -185,17 +201,31 @@ bool FBAccessTokenData::IsExpired(
|
|||
return expired;
|
||||
}
|
||||
|
||||
void FBAccessTokenData::AddPermissions(
|
||||
void FBAccessTokenData::SetPermissions(
|
||||
IVectorView<Object^>^ perms
|
||||
)
|
||||
{
|
||||
_permissions = ref new Map<String^, String^>();
|
||||
_grantedPermissions = nullptr;
|
||||
_declinedPermissions = nullptr;
|
||||
Vector<String^>^ granted = ref new Vector<String^>(0);
|
||||
Vector<String^>^ declined = ref new Vector<String^>(0);
|
||||
|
||||
for (unsigned int i = 0; i < perms->Size; i++)
|
||||
{
|
||||
FBPermission^ perm =
|
||||
static_cast<FBPermission^>(perms->GetAt(i));
|
||||
_permissions->Insert(perm->Permission, perm->Status);
|
||||
FBPermission^ perm = static_cast<FBPermission^>(perms->GetAt(i));
|
||||
|
||||
if (!String::CompareOrdinal(perm->Status, L"granted"))
|
||||
{
|
||||
granted->Append(perm->Permission);
|
||||
}
|
||||
else if (!String::CompareOrdinal(perm->Status, L"declined"))
|
||||
{
|
||||
declined->Append(perm->Permission);
|
||||
}
|
||||
}
|
||||
|
||||
_grantedPermissions = ref new FBPermissions(granted->GetView());
|
||||
_declinedPermissions = ref new FBPermissions(declined->GetView());
|
||||
}
|
||||
|
||||
void FBAccessTokenData::CalculateExpirationDateTime(
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
/*!\brief How user was/will be logged in. Preferred method should be app,
|
||||
|
@ -71,12 +73,14 @@ namespace Facebook
|
|||
}
|
||||
|
||||
//! Returns the list of permissions
|
||||
property
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^,
|
||||
Platform::String^>^ Permissions
|
||||
property Facebook::FBPermissions^ GrantedPermissions
|
||||
{
|
||||
Windows::Foundation::Collections::IMapView<Platform::String^,
|
||||
Platform::String^>^ get();
|
||||
Facebook::FBPermissions^ get();
|
||||
}
|
||||
|
||||
property Facebook::FBPermissions^ DeclinedPermissions
|
||||
{
|
||||
Facebook::FBPermissions^ get();
|
||||
}
|
||||
|
||||
//! Returns user ID for the token, if available.
|
||||
|
@ -88,7 +92,7 @@ namespace Facebook
|
|||
bool IsExpired(
|
||||
);
|
||||
|
||||
void AddPermissions(
|
||||
void SetPermissions(
|
||||
Windows::Foundation::Collections::IVectorView<Object^>^ perms
|
||||
);
|
||||
|
||||
|
@ -99,6 +103,9 @@ namespace Facebook
|
|||
Platform::String^ State
|
||||
);
|
||||
|
||||
void InitPermissions(
|
||||
);
|
||||
|
||||
void CalculateExpirationDateTime(
|
||||
Platform::String^ Expiration
|
||||
);
|
||||
|
@ -116,8 +123,8 @@ namespace Facebook
|
|||
Platform::String^ _accessToken;
|
||||
Platform::String^ _appId;
|
||||
Windows::Foundation::DateTime _expirationDate;
|
||||
Platform::Collections::Map<Platform::String^, Platform::String^>^
|
||||
_permissions;
|
||||
FBPermissions^ _grantedPermissions;
|
||||
FBPermissions^ _declinedPermissions;
|
||||
Platform::String^ _userId;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -621,11 +621,11 @@ Uri^ FBClient::PrepareRequestUri(
|
|||
host = L"graph.facebook.com";
|
||||
}
|
||||
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
|
||||
String^ uriString = L"https://" + host + L"/" + apiVersion + path + L"?" + queryString;
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ using namespace std;
|
|||
#define FACEBOOK_DESKTOP_SERVER_NAME L"www"
|
||||
#define FACEBOOK_MOBILE_SERVER_NAME L"m"
|
||||
#define FACEBOOK_LOGIN_SUCCESS_PATH L"/connect/login_success.html"
|
||||
#define FACEBOOK_DIALOG_CLOSE_PATH L"/dialog/close"
|
||||
|
||||
const wchar_t* ErrorObjectJson = L"{\"error\": {\"message\": " \
|
||||
L"\"Operation Canceled\", \"type\": " \
|
||||
|
@ -157,13 +158,14 @@ void FacebookDialog::ShowDialog(
|
|||
}
|
||||
|
||||
void FacebookDialog::ShowLoginDialog(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
TypedEventHandler<WebView^, WebViewNavigationStartingEventArgs^>^ handler =
|
||||
ref new TypedEventHandler<WebView^, WebViewNavigationStartingEventArgs^>(
|
||||
this, &FacebookDialog::dialogWebView_LoginNavStarting);
|
||||
ShowDialog(ref new DialogUriBuilder(this,
|
||||
&FacebookDialog::BuildLoginDialogUrl), handler, nullptr);
|
||||
&FacebookDialog::BuildLoginDialogUrl), handler, Parameters);
|
||||
}
|
||||
|
||||
void FacebookDialog::ShowFeedDialog(
|
||||
|
@ -240,26 +242,66 @@ String^ FacebookDialog::GetFBServer(
|
|||
return server;
|
||||
}
|
||||
|
||||
#define ScopeKey L"scope"
|
||||
#define DisplayKey L"display"
|
||||
#define ResponseTypeKey L"response_type"
|
||||
#define DefaultScope L"public_profile,email,user_friends"
|
||||
#define DefaultDisplay L"popup"
|
||||
#define DefaultResponse L"token"
|
||||
|
||||
Uri^ FacebookDialog::BuildLoginDialogUrl(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ dialogUriString =
|
||||
L"https://" + GetFBServer() +
|
||||
L".facebook.com/" + apiVersion + L"dialog/oauth?client_id=" + sess->FBAppId +
|
||||
L"&redirect_uri=" + GetRedirectUriString(L"login") + L"&app_id=" +
|
||||
sess->FBAppId + L"&scope=" + sess->PermissionsToString() +
|
||||
L"&display=popup" + L"&response_type=token";
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
String^ apiVersion = L"";
|
||||
if (s->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + s->APIMajorVersion.ToString() + L"." + s->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ uriString = L"https://" + GetFBServer() +
|
||||
L".facebook.com/" + apiVersion + L"dialog/oauth?client_id=" + s->FBAppId;
|
||||
|
||||
DebugPrintLine(L"Request string is " + dialogUriString);
|
||||
// Use some reasonable default login parameters
|
||||
String^ scope = DefaultScope;
|
||||
String^ displayType = DefaultDisplay;
|
||||
String^ responseType = DefaultResponse;
|
||||
|
||||
return ref new Uri(dialogUriString);
|
||||
uriString += L"&redirect_uri=" + GetRedirectUriString(L"login");
|
||||
|
||||
// Enumerate through all the parameters
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ first = Parameters->First();
|
||||
while (first && (first->HasCurrent))
|
||||
{
|
||||
String^ Key = first->Current->Key;
|
||||
String^ Value = dynamic_cast<String^>(first->Current->Value);
|
||||
if (Value)
|
||||
{
|
||||
if (!String::CompareOrdinal(Key, ScopeKey))
|
||||
{
|
||||
scope = Value;
|
||||
}
|
||||
else if (!String::CompareOrdinal(Key, DisplayKey))
|
||||
{
|
||||
displayType = Value;
|
||||
}
|
||||
else if (!String::CompareOrdinal(Key, ResponseTypeKey))
|
||||
{
|
||||
responseType = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
uriString += L"&" + Key + L"=" + Value;
|
||||
}
|
||||
}
|
||||
|
||||
first->MoveNext();
|
||||
}
|
||||
|
||||
uriString += L"&" + ScopeKey + L"=" + scope + L"&" + DisplayKey + L"=" +
|
||||
displayType + L"&" + ResponseTypeKey + L"=" + responseType;
|
||||
|
||||
return ref new Uri(uriString);
|
||||
}
|
||||
|
||||
Uri^ FacebookDialog::BuildFeedDialogUrl(
|
||||
|
@ -267,13 +309,13 @@ Uri^ FacebookDialog::BuildFeedDialogUrl(
|
|||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ dialogUriString =
|
||||
L"https://" + GetFBServer() +
|
||||
L"https://" + GetFBServer() +
|
||||
L".facebook.com/" + apiVersion + L"dialog/feed?access_token=" +
|
||||
sess->AccessTokenData->AccessToken +
|
||||
L"&redirect_uri=" + GetRedirectUriString(L"feed") +
|
||||
|
@ -292,11 +334,11 @@ Uri^ FacebookDialog::BuildRequestsDialogUrl(
|
|||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ apiVersion = L"";
|
||||
if (sess->APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + sess->APIMajorVersion.ToString() + L"." + sess->APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ dialogUriString =
|
||||
L"https://" + GetFBServer() +
|
||||
L".facebook.com/" + apiVersion + L"dialog/apprequests?access_token=" +
|
||||
|
@ -319,6 +361,13 @@ bool FacebookDialog::IsLoginSuccessRedirect(
|
|||
return (String::CompareOrdinal(Response->Path, FACEBOOK_LOGIN_SUCCESS_PATH) == 0);
|
||||
}
|
||||
|
||||
bool FacebookDialog::IsDialogCloseRedirect(
|
||||
Uri^ Response
|
||||
)
|
||||
{
|
||||
return (String::CompareOrdinal(Response->Path, FACEBOOK_DIALOG_CLOSE_PATH) == 0);
|
||||
}
|
||||
|
||||
void FacebookDialog::dialogWebView_LoginNavStarting(
|
||||
WebView^ sender,
|
||||
WebViewNavigationStartingEventArgs^ e
|
||||
|
@ -344,6 +393,15 @@ void FacebookDialog::dialogWebView_LoginNavStarting(
|
|||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
else if (IsDialogCloseRedirect(e->Uri))
|
||||
{
|
||||
dialogWebBrowser->Stop();
|
||||
|
||||
UninitDialog();
|
||||
|
||||
FBError^ err = FBError::FromJson(ref new String(ErrorObjectJson));
|
||||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
|
||||
void FacebookDialog::dialogWebView_FeedNavStarting(
|
||||
|
@ -373,6 +431,15 @@ void FacebookDialog::dialogWebView_FeedNavStarting(
|
|||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
else if (IsDialogCloseRedirect(e->Uri))
|
||||
{
|
||||
dialogWebBrowser->Stop();
|
||||
|
||||
UninitDialog();
|
||||
|
||||
FBError^ err = FBError::FromJson(ref new String(ErrorObjectJson));
|
||||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
|
||||
void FacebookDialog::dialogWebView_RequestNavStarting(
|
||||
|
@ -402,6 +469,15 @@ void FacebookDialog::dialogWebView_RequestNavStarting(
|
|||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
else if (IsDialogCloseRedirect(e->Uri))
|
||||
{
|
||||
dialogWebBrowser->Stop();
|
||||
|
||||
UninitDialog();
|
||||
|
||||
FBError^ err = FBError::FromJson(ref new String(ErrorObjectJson));
|
||||
_dialogResponse = ref new FBResult(err);
|
||||
}
|
||||
}
|
||||
|
||||
void FacebookDialog::CloseDialogButton_OnClick(
|
||||
|
|
|
@ -51,6 +51,7 @@ namespace Facebook
|
|||
);
|
||||
|
||||
void ShowLoginDialog(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
void ShowFeedDialog(
|
||||
|
@ -114,6 +115,10 @@ namespace Facebook
|
|||
Windows::Foundation::Uri^ Response
|
||||
);
|
||||
|
||||
bool IsDialogCloseRedirect(
|
||||
Windows::Foundation::Uri^ Response
|
||||
);
|
||||
|
||||
void OnSizeChanged(
|
||||
Windows::UI::Core::CoreWindow ^sender,
|
||||
Windows::UI::Core::WindowSizeChangedEventArgs ^args
|
||||
|
|
|
@ -19,19 +19,20 @@
|
|||
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
|
||||
{
|
||||
ErrorSubcodeAppNotAuthorized = 458,
|
||||
ErrorSubcodeSessionInvalidated = 466
|
||||
};
|
||||
|
||||
/*!
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "pch.h"
|
||||
#include "FacebookLoginButton.h"
|
||||
#include "FacebookSession.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
using namespace Concurrency;
|
||||
using namespace Facebook;
|
||||
|
@ -32,7 +33,6 @@ FBLoginButton::FBLoginButton() :
|
|||
{
|
||||
String^ styleKey = FBLoginButton::typeid->FullName;
|
||||
this->DefaultStyleKey = styleKey;
|
||||
_permissions = ref new Vector<String^>();
|
||||
}
|
||||
|
||||
void FBLoginButton::OnApplyTemplate(
|
||||
|
@ -58,54 +58,21 @@ void FBLoginButton::OnApplyTemplate(
|
|||
//}
|
||||
//
|
||||
|
||||
IVector<String^>^ FBLoginButton::Permissions::get()
|
||||
FBPermissions^ FBLoginButton::Permissions::get()
|
||||
{
|
||||
return _permissions;
|
||||
}
|
||||
|
||||
void FBLoginButton::Permissions::set(IVector<String^>^ Values)
|
||||
void FBLoginButton::Permissions::set(FBPermissions^ value)
|
||||
{
|
||||
_permissions->Clear();
|
||||
IIterator<String^>^ it = nullptr;
|
||||
for (it = Values->First(); it->HasCurrent; it->MoveNext())
|
||||
{
|
||||
String^ value = it->Current;
|
||||
_permissions->Append(value);
|
||||
}
|
||||
_permissions = value;
|
||||
}
|
||||
|
||||
void FBLoginButton::InitWithPermissions(
|
||||
IVector<String^>^ permissions
|
||||
FBPermissions^ permissions
|
||||
)
|
||||
{
|
||||
if (!_permissions)
|
||||
{
|
||||
_permissions = ref new Vector<String^>(0);
|
||||
}
|
||||
|
||||
_permissions->Clear();
|
||||
|
||||
for (IIterator<String^>^ iter = permissions->First();
|
||||
iter->HasCurrent;
|
||||
iter->MoveNext())
|
||||
{
|
||||
_permissions->Append(iter->Current);
|
||||
}
|
||||
}
|
||||
|
||||
void FBLoginButton::SetSessionPermissions(
|
||||
)
|
||||
{
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
s->ResetPermissions();
|
||||
if (_permissions)
|
||||
{
|
||||
IIterator<String^>^ iter = nullptr;
|
||||
for (iter = _permissions->First(); iter->HasCurrent; iter->MoveNext())
|
||||
{
|
||||
s->AddPermission(iter->Current);
|
||||
}
|
||||
}
|
||||
_permissions = permissions;
|
||||
}
|
||||
|
||||
void FBLoginButton::OnClick(
|
||||
|
@ -121,9 +88,7 @@ void FBLoginButton::OnClick(
|
|||
}
|
||||
else
|
||||
{
|
||||
SetSessionPermissions();
|
||||
|
||||
create_task(s->LoginAsync())
|
||||
create_task(s->LoginAsync(Permissions))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "FacebookSession.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
|
@ -58,16 +59,16 @@ namespace Facebook
|
|||
//}
|
||||
|
||||
//! Publish permissions for user
|
||||
property Windows::Foundation::Collections::IVector<Platform::String^>^
|
||||
property Facebook::FBPermissions^
|
||||
Permissions
|
||||
{
|
||||
Windows::Foundation::Collections::IVector<Platform::String^>^ get();
|
||||
void set(Windows::Foundation::Collections::IVector<Platform::String^>^);
|
||||
Facebook::FBPermissions^ get();
|
||||
void set(Facebook::FBPermissions^ value);
|
||||
}
|
||||
|
||||
//! Ask for read permissions at login
|
||||
void InitWithPermissions(
|
||||
Windows::Foundation::Collections::IVector<Platform::String^>^ permissions
|
||||
Facebook::FBPermissions^ permissions
|
||||
);
|
||||
|
||||
event FBLoginErrorHandler^ FBLoginError;
|
||||
|
@ -76,7 +77,7 @@ namespace Facebook
|
|||
event ShowingLoggedOutUserHandler^ ShowingLoggedOutUser;
|
||||
|
||||
private:
|
||||
void SetSessionPermissions(
|
||||
Platform::String^ GetPermissions(
|
||||
);
|
||||
|
||||
void OnClick(
|
||||
|
@ -84,7 +85,6 @@ namespace Facebook
|
|||
Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
|
||||
// SessionLoginBehavior _loginBehavior;
|
||||
Platform::Collections::Vector<Platform::String^>^ _permissions;
|
||||
Facebook::FBPermissions^ _permissions;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
//******************************************************************************
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
//******************************************************************************
|
||||
#include <ppltasks.h>
|
||||
|
||||
#include "pch.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
using namespace Facebook;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
|
||||
FBPermissions::FBPermissions(
|
||||
IVectorView<String^>^ Permissions
|
||||
)
|
||||
{
|
||||
_values = Permissions;
|
||||
}
|
||||
|
||||
IVectorView<String^>^ FBPermissions::Values::get()
|
||||
{
|
||||
return _values;
|
||||
};
|
||||
|
||||
Platform::String^ FBPermissions::ToString(
|
||||
)
|
||||
{
|
||||
String^ permissions = nullptr;
|
||||
if (_values)
|
||||
{
|
||||
permissions = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < _values->Size; i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
permissions += ",";
|
||||
}
|
||||
|
||||
permissions += _values->GetAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
//******************************************************************************
|
||||
//
|
||||
// Copyright (c) 2015 Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// This code is licensed under the MIT License (MIT).
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
//
|
||||
//******************************************************************************
|
||||
#pragma once
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
/*!\brief Simple class to contain a set of permissions for FB.
|
||||
*/
|
||||
public ref class FBPermissions sealed
|
||||
{
|
||||
public:
|
||||
//! Construct an instance with a given set of permissions
|
||||
FBPermissions(
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ Permissions
|
||||
);
|
||||
|
||||
//! The list of permissions
|
||||
property Windows::Foundation::Collections::IVectorView<Platform::String^>^ Values
|
||||
{
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ get();
|
||||
};
|
||||
|
||||
//! Handy override that provides a string version of permissions in
|
||||
// the format suitable for concatenating into a FB request URL.
|
||||
virtual Platform::String^ ToString(
|
||||
) override;
|
||||
|
||||
private:
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ _values;
|
||||
};
|
||||
}
|
||||
|
|
@ -67,38 +67,36 @@ FBSession::FBSession() :
|
|||
_loggedIn(false),
|
||||
_FBAppId(nullptr),
|
||||
_WinAppId(nullptr),
|
||||
_permissions(nullptr),
|
||||
_user(nullptr)
|
||||
{
|
||||
_permissions = ref new Vector<String^>;
|
||||
if (!login_evt)
|
||||
{
|
||||
login_evt = CreateEventEx(NULL, NULL, 0, DELETE | SYNCHRONIZE);
|
||||
}
|
||||
if (!login_evt)
|
||||
{
|
||||
login_evt = CreateEventEx(NULL, NULL, 0, DELETE | SYNCHRONIZE);
|
||||
}
|
||||
_showingDialog = FALSE;
|
||||
_APIMajorVersion = 2;
|
||||
_APIMinorVersion = 1;
|
||||
_APIMajorVersion = 2;
|
||||
_APIMinorVersion = 1;
|
||||
}
|
||||
|
||||
Facebook::FBSession::~FBSession()
|
||||
{
|
||||
if (login_evt)
|
||||
{
|
||||
CloseHandle(login_evt);
|
||||
login_evt = NULL;
|
||||
}
|
||||
if (login_evt)
|
||||
{
|
||||
CloseHandle(login_evt);
|
||||
login_evt = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
String^ FBSession::FBAppId::get()
|
||||
{
|
||||
if (!_FBAppId)
|
||||
{
|
||||
_FBAppId = ref new String(L"<INSERT YOUR APP ID HERE>");
|
||||
if (!_FBAppId)
|
||||
{
|
||||
_FBAppId = ref new String(L"<INSERT YOUR APP ID HERE>");
|
||||
|
||||
#ifdef _DEBUG
|
||||
OutputDebugString(L"!!! Missing App ID. Update your app to use a valid FB App ID in order for the FB API's to succeed");
|
||||
OutputDebugString(L"!!! Missing App ID. Update your app to use a valid FB App ID in order for the FB API's to succeed");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return _FBAppId;
|
||||
}
|
||||
|
@ -138,35 +136,13 @@ void FBSession::AccessTokenData::set(FBAccessTokenData^ value)
|
|||
_AccessTokenData = value;
|
||||
}
|
||||
|
||||
IVectorView<String^>^ FBSession::Permissions::get()
|
||||
{
|
||||
return _permissions->GetView();
|
||||
}
|
||||
|
||||
FBUser^ FBSession::User::get()
|
||||
{
|
||||
return _user;
|
||||
}
|
||||
|
||||
void FBSession::AddPermission(
|
||||
String^ permission
|
||||
)
|
||||
{
|
||||
_permissions->Append(permission);
|
||||
}
|
||||
|
||||
void FBSession::ResetPermissions(
|
||||
)
|
||||
{
|
||||
if (_permissions)
|
||||
{
|
||||
_permissions->Clear();
|
||||
}
|
||||
}
|
||||
|
||||
IAsyncAction^ FBSession::LogoutAsync()
|
||||
{
|
||||
_permissions->Clear();
|
||||
_user = nullptr;
|
||||
_FBAppId = nullptr;
|
||||
_WinAppId = nullptr;
|
||||
|
@ -192,23 +168,6 @@ task<FBResult^> FBSession::GetUserInfo(
|
|||
return create_task(value->GetAsync());
|
||||
}
|
||||
|
||||
String^ FBSession::PermissionsToString()
|
||||
{
|
||||
String^ permissionsString = ref new String();
|
||||
|
||||
for (unsigned int i = 0; i < _permissions->Size; i++)
|
||||
{
|
||||
if (i)
|
||||
{
|
||||
permissionsString += ",";
|
||||
}
|
||||
|
||||
permissionsString += _permissions->GetAt(i);
|
||||
}
|
||||
|
||||
return permissionsString;
|
||||
}
|
||||
|
||||
IAsyncOperation<IStorageItem^>^ FBSession::MyTryGetItemAsync(
|
||||
StorageFolder^ folder,
|
||||
String^ itemName
|
||||
|
@ -292,18 +251,18 @@ task<FBResult^> FBSession::CheckForExistingToken(
|
|||
.then([](task<IBuffer^> clearBufferTask) -> FBResult^
|
||||
{
|
||||
FBResult^ cachedResult = nullptr;
|
||||
IBuffer^ clearBuffer = nullptr;
|
||||
IBuffer^ clearBuffer = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
clearBuffer = clearBufferTask.get();
|
||||
}
|
||||
catch (InvalidArgumentException^ ex)
|
||||
{
|
||||
try
|
||||
{
|
||||
clearBuffer = clearBufferTask.get();
|
||||
}
|
||||
catch (InvalidArgumentException^ ex)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
OutputDebugString(L"Couldn't decrypt cached token. Continuing without cached token data.\n");
|
||||
OutputDebugString(L"Couldn't decrypt cached token. Continuing without cached token data.\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (clearBuffer)
|
||||
{
|
||||
|
@ -383,7 +342,7 @@ IAsyncAction^ FBSession::TryDeleteTokenData(
|
|||
{
|
||||
StorageFolder^ folder = ApplicationData::Current->LocalFolder;
|
||||
#ifdef _DEBUG
|
||||
String^ msg = L"Deleting cached token from " + folder->Path + L"\n";
|
||||
String^ msg = L"Deleting cached token from " + folder->Path + L"\n";
|
||||
OutputDebugString(msg->Data());
|
||||
#endif
|
||||
return create_async([=]()
|
||||
|
@ -423,7 +382,7 @@ IAsyncAction^ FBSession::TryDeleteTokenData(
|
|||
});
|
||||
}
|
||||
|
||||
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSession::ShowFeedDialogAsync(
|
||||
IAsyncOperation<FBResult^>^ FBSession::ShowFeedDialogAsync(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
|
@ -480,8 +439,8 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBSession::ShowFeedDialogAsync(
|
|||
return task;
|
||||
}
|
||||
|
||||
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSession::ShowRequestsDialogAsync(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
IAsyncOperation<FBResult^>^ FBSession::ShowRequestsDialogAsync(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
_dialog = ref new FacebookDialog();
|
||||
|
@ -538,6 +497,7 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBSession::ShowRequestsDialogAs
|
|||
}
|
||||
|
||||
task<FBResult^> FBSession::ShowLoginDialog(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
_dialog = ref new FacebookDialog();
|
||||
|
@ -549,7 +509,7 @@ task<FBResult^> FBSession::ShowLoginDialog(
|
|||
{
|
||||
try
|
||||
{
|
||||
_dialog->ShowLoginDialog();
|
||||
_dialog->ShowLoginDialog(Parameters);
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
|
@ -617,34 +577,73 @@ task<FBResult^> FBSession::GetAppPermissions(
|
|||
{
|
||||
IVectorView<Object^>^ perms =
|
||||
static_cast<IVectorView<Object^>^>(result->Object);
|
||||
_AccessTokenData->AddPermissions(perms);
|
||||
_AccessTokenData->SetPermissions(perms);
|
||||
}
|
||||
|
||||
return ref new FBResult(_user);
|
||||
});
|
||||
}
|
||||
|
||||
#define ScopeKey L"scope"
|
||||
#define DisplayKey L"display"
|
||||
#define ResponseTypeKey L"response_type"
|
||||
#define DefaultScope L"public_profile,email,user_friends"
|
||||
#define DefaultDisplay L"popup"
|
||||
#define DefaultResponse L"token"
|
||||
#define AuthTypeKey L"auth_type"
|
||||
#define Rerequest L"rerequest"
|
||||
|
||||
Uri^ FBSession::BuildLoginUri(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
String^ apiVersion = L"";
|
||||
if (APIMajorVersion)
|
||||
{
|
||||
apiVersion = L"v" + APIMajorVersion.ToString() + L"." + APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ uriString = L"https://www.facebook.com/" + apiVersion + L"dialog/oauth?client_id=" +
|
||||
_FBAppId;
|
||||
String^ permissionsString = PermissionsToString();
|
||||
|
||||
uriString += L"&redirect_uri=" + Uri::EscapeComponent(
|
||||
GetRedirectUriString()) + L"%2fauth";
|
||||
|
||||
if (!permissionsString->IsEmpty())
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
String^ apiVersion = L"";
|
||||
if (APIMajorVersion)
|
||||
{
|
||||
uriString += L"&scope=" + permissionsString;
|
||||
apiVersion = L"v" + APIMajorVersion.ToString() + L"." + APIMinorVersion.ToString() + L"/";
|
||||
}
|
||||
String^ uriString = L"https://" +
|
||||
L"www.facebook.com/" + apiVersion + L"dialog/oauth?client_id=" + s->FBAppId;
|
||||
|
||||
// Use some reasonable default login parameters
|
||||
String^ scope = DefaultScope;
|
||||
String^ displayType = DefaultDisplay;
|
||||
String^ responseType = DefaultResponse;
|
||||
|
||||
uriString += L"&redirect_uri=" + GetRedirectUriString();
|
||||
|
||||
// Enumerate through all the parameters
|
||||
IIterator<IKeyValuePair<String^, Object^>^>^ first = Parameters->First();
|
||||
while (first && (first->HasCurrent))
|
||||
{
|
||||
String^ Key = first->Current->Key;
|
||||
String^ Value = dynamic_cast<String^>(first->Current->Value);
|
||||
if (Value)
|
||||
{
|
||||
if (!String::CompareOrdinal(Key, ScopeKey))
|
||||
{
|
||||
scope = Value;
|
||||
}
|
||||
else if (!String::CompareOrdinal(Key, DisplayKey))
|
||||
{
|
||||
displayType = Value;
|
||||
}
|
||||
else if (!String::CompareOrdinal(Key, ResponseTypeKey))
|
||||
{
|
||||
responseType = Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
uriString += L"&" + Key + L"=" + Value;
|
||||
}
|
||||
}
|
||||
|
||||
first->MoveNext();
|
||||
}
|
||||
|
||||
uriString += L"&display=popup&response_type=token";
|
||||
uriString += L"&" + ScopeKey + L"=" + scope + L"&" + DisplayKey + L"=" +
|
||||
displayType + L"&" + ResponseTypeKey + L"=" + responseType;
|
||||
|
||||
return ref new Uri(uriString);
|
||||
}
|
||||
|
@ -653,155 +652,154 @@ String^ FBSession::GetRedirectUriString(
|
|||
)
|
||||
{
|
||||
Uri^ endURI = WebAuthenticationBroker::GetCurrentApplicationCallbackUri();
|
||||
String^ blerg = endURI->DisplayUri;
|
||||
OutputDebugString(blerg->Data());
|
||||
OutputDebugString(L"\n");
|
||||
return endURI->DisplayUri;
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::ProcessAuthResult(
|
||||
WebAuthenticationResult^ authResult
|
||||
)
|
||||
WebAuthenticationResult^ authResult
|
||||
)
|
||||
{
|
||||
return create_task([=]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
String^ uriString = nullptr;
|
||||
FBAccessTokenData^ tokenData = nullptr;
|
||||
Uri^ uri = nullptr;
|
||||
switch (authResult->ResponseStatus)
|
||||
{
|
||||
case WebAuthenticationStatus::ErrorHttp:
|
||||
//TODO: need a real error code
|
||||
result = ref new FBResult(ref new FBError(0,
|
||||
L"Communication error",
|
||||
L"An Http error occurred"));
|
||||
break;
|
||||
case WebAuthenticationStatus::Success:
|
||||
//TODO: need a real error code
|
||||
uriString = authResult->ResponseData;
|
||||
uri = ref new Uri(uriString);
|
||||
tokenData = FBAccessTokenData::FromUri(uri);
|
||||
if (!tokenData)
|
||||
{
|
||||
result = ref new FBResult(FBError::FromUri(uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ref new FBResult(tokenData);
|
||||
}
|
||||
break;
|
||||
case WebAuthenticationStatus::UserCancel:
|
||||
result = ref new FBResult(ref new FBError(0,
|
||||
L"User canceled",
|
||||
L"The login operation was canceled"));
|
||||
break;
|
||||
}
|
||||
return create_task([=]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
String^ uriString = nullptr;
|
||||
FBAccessTokenData^ tokenData = nullptr;
|
||||
Uri^ uri = nullptr;
|
||||
switch (authResult->ResponseStatus)
|
||||
{
|
||||
case WebAuthenticationStatus::ErrorHttp:
|
||||
//TODO: need a real error code
|
||||
result = ref new FBResult(ref new FBError(0,
|
||||
L"Communication error",
|
||||
L"An Http error occurred"));
|
||||
break;
|
||||
case WebAuthenticationStatus::Success:
|
||||
//TODO: need a real error code
|
||||
uriString = authResult->ResponseData;
|
||||
uri = ref new Uri(uriString);
|
||||
tokenData = FBAccessTokenData::FromUri(uri);
|
||||
if (!tokenData)
|
||||
{
|
||||
result = ref new FBResult(FBError::FromUri(uri));
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ref new FBResult(tokenData);
|
||||
}
|
||||
break;
|
||||
case WebAuthenticationStatus::UserCancel:
|
||||
result = ref new FBResult(ref new FBError(0,
|
||||
L"User canceled",
|
||||
L"The login operation was canceled"));
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::TryGetUserInfoAfterLogin(
|
||||
FBResult^ loginResult
|
||||
)
|
||||
FBResult^ loginResult
|
||||
)
|
||||
{
|
||||
task<FBResult^> innerResult;
|
||||
task<FBResult^> innerResult;
|
||||
|
||||
if (loginResult && loginResult->Succeeded)
|
||||
{
|
||||
_AccessTokenData = static_cast<FBAccessTokenData^>(loginResult->Object);
|
||||
_loggedIn = true;
|
||||
TrySaveTokenData();
|
||||
innerResult = GetUserInfo(_AccessTokenData);
|
||||
}
|
||||
else
|
||||
{
|
||||
innerResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
if (loginResult && loginResult->Succeeded)
|
||||
{
|
||||
_AccessTokenData = static_cast<FBAccessTokenData^>(loginResult->Object);
|
||||
_loggedIn = true;
|
||||
TrySaveTokenData();
|
||||
innerResult = GetUserInfo(_AccessTokenData);
|
||||
}
|
||||
else
|
||||
{
|
||||
innerResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
|
||||
return innerResult;
|
||||
return innerResult;
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::TryGetAppPermissionsAfterLogin(
|
||||
FBResult^ loginResult
|
||||
)
|
||||
FBResult^ loginResult
|
||||
)
|
||||
{
|
||||
task<FBResult^> finalResult;
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
_user = static_cast<FBUser^>(loginResult->Object);
|
||||
finalResult = GetAppPermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
finalResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
task<FBResult^> finalResult;
|
||||
if (loginResult->Succeeded)
|
||||
{
|
||||
_user = static_cast<FBUser^>(loginResult->Object);
|
||||
finalResult = GetAppPermissions();
|
||||
}
|
||||
else
|
||||
{
|
||||
finalResult = create_task([=]()
|
||||
{
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::RunOAuthOnUiThread(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
task<void> authTask = create_task(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
_loginTask = create_task(
|
||||
WebAuthenticationBroker::AuthenticateAsync(
|
||||
WebAuthenticationOptions::None, BuildLoginUri(),
|
||||
ref new Uri(GetRedirectUriString())))
|
||||
.then([this](WebAuthenticationResult^ authResult) -> task<FBResult^>
|
||||
{
|
||||
return ProcessAuthResult(authResult);
|
||||
task<void> authTask = create_task(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
_loginTask = create_task(
|
||||
WebAuthenticationBroker::AuthenticateAsync(
|
||||
WebAuthenticationOptions::None, BuildLoginUri(Parameters),
|
||||
ref new Uri(GetRedirectUriString())))
|
||||
.then([this](WebAuthenticationResult^ authResult) -> task<FBResult^>
|
||||
{
|
||||
return ProcessAuthResult(authResult);
|
||||
});
|
||||
})));
|
||||
})));
|
||||
|
||||
return create_task([=](void)
|
||||
{
|
||||
try
|
||||
{
|
||||
authTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
throw ref new InvalidArgumentException(SDKMessageLoginFailed);
|
||||
}
|
||||
})
|
||||
.then([this]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
return create_task([=](void)
|
||||
{
|
||||
try
|
||||
{
|
||||
authTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
throw ref new InvalidArgumentException(SDKMessageLoginFailed);
|
||||
}
|
||||
})
|
||||
.then([this]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
|
||||
try
|
||||
{
|
||||
result = _loginTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
throw ref new InvalidArgumentException(SDKMessageLoginFailed);
|
||||
}
|
||||
try
|
||||
{
|
||||
result = _loginTask.get();
|
||||
}
|
||||
catch (Exception^ ex)
|
||||
{
|
||||
throw ref new InvalidArgumentException(SDKMessageLoginFailed);
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::RunWebViewLoginOnUIThread(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
task<void> authTask = create_task(
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
_loginTask = ShowLoginDialog();
|
||||
_loginTask = ShowLoginDialog(Parameters);
|
||||
})));
|
||||
|
||||
return create_task([=](void)
|
||||
|
@ -833,21 +831,33 @@ task<FBResult^> FBSession::RunWebViewLoginOnUIThread(
|
|||
}
|
||||
|
||||
IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
||||
FBPermissions^ Permissions
|
||||
)
|
||||
{
|
||||
_dialog = ref new FacebookDialog();
|
||||
|
||||
return create_async([=]()
|
||||
{
|
||||
PropertySet^ parameters = ref new PropertySet();
|
||||
if (Permissions)
|
||||
{
|
||||
parameters->Insert(L"scope", Permissions->ToString());
|
||||
}
|
||||
|
||||
if (LoggedIn)
|
||||
{
|
||||
parameters->Insert(L"auth_type", L"rerequest");
|
||||
}
|
||||
|
||||
return create_task([=]() -> FBResult^
|
||||
{
|
||||
FBResult^ result = nullptr;
|
||||
|
||||
task<FBResult^> authTask = TryLoginViaWebView();
|
||||
task<FBResult^> authTask = TryLoginViaWebView(parameters);
|
||||
result = authTask.get();
|
||||
if (!result)
|
||||
{
|
||||
authTask = TryLoginViaWebAuthBroker();
|
||||
authTask = TryLoginViaWebAuthBroker(parameters);
|
||||
result = authTask.get();
|
||||
}
|
||||
|
||||
|
@ -860,64 +870,40 @@ IAsyncOperation<FBResult^>^ FBSession::LoginAsync(
|
|||
.then([this](FBResult^ userInfoResult) -> task<FBResult^>
|
||||
{
|
||||
return TryGetAppPermissionsAfterLogin(userInfoResult);
|
||||
})
|
||||
.then([=](FBResult^ finalResult)
|
||||
{
|
||||
if (!finalResult->Succeeded)
|
||||
{
|
||||
_loggedIn = false;
|
||||
AccessTokenData = nullptr;
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::TryLoginViaWebView(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
return CheckForExistingToken()
|
||||
.then([this](FBResult^ oauthResult) -> task<FBResult^>
|
||||
return create_task([=]() -> task<FBResult^>
|
||||
{
|
||||
task<FBResult^> graphTask = create_task([]() -> FBResult^
|
||||
{
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
if (oauthResult && oauthResult->Succeeded)
|
||||
if (!IsRerequest(Parameters))
|
||||
{
|
||||
Facebook::FBAccessTokenData^ tokenData =
|
||||
static_cast<Facebook::FBAccessTokenData^>(oauthResult->Object);
|
||||
if (!tokenData->IsExpired())
|
||||
{
|
||||
AccessTokenData = tokenData;
|
||||
graphTask = create_task([=]() -> FBResult^
|
||||
{
|
||||
return ref new FBResult(AccessTokenData);
|
||||
});
|
||||
}
|
||||
graphTask = CheckForExistingToken();
|
||||
}
|
||||
|
||||
return graphTask;
|
||||
})
|
||||
.then([this](FBResult^ graphResult)
|
||||
{
|
||||
FBResult^ loginResult = nullptr;
|
||||
|
||||
if (graphResult && graphResult->Succeeded)
|
||||
{
|
||||
loginResult = graphResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
loginResult = RunWebViewLoginOnUIThread().get();
|
||||
}
|
||||
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::TryLoginViaWebAuthBroker(
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
IAsyncOperation<FBResult^>^ result = nullptr;
|
||||
|
||||
return CheckForExistingToken()
|
||||
.then([this](FBResult^ oauthResult) -> task<FBResult^>
|
||||
{
|
||||
task<FBResult^> graphTask = create_task([]() -> FBResult^
|
||||
|
@ -941,7 +927,69 @@ task<FBResult^> FBSession::TryLoginViaWebAuthBroker(
|
|||
|
||||
return graphTask;
|
||||
})
|
||||
.then([this](FBResult^ graphResult)
|
||||
.then([=](FBResult^ graphResult)
|
||||
{
|
||||
FBResult^ loginResult = nullptr;
|
||||
|
||||
if (graphResult && graphResult->Succeeded)
|
||||
{
|
||||
loginResult = graphResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
loginResult = RunWebViewLoginOnUIThread(Parameters).get();
|
||||
}
|
||||
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
|
||||
task<FBResult^> FBSession::TryLoginViaWebAuthBroker(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
IAsyncOperation<FBResult^>^ result = nullptr;
|
||||
|
||||
return create_task([=]() -> task<FBResult^>
|
||||
{
|
||||
task<FBResult^> graphTask = create_task([]() -> FBResult^
|
||||
{
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
if (!IsRerequest(Parameters))
|
||||
{
|
||||
graphTask = CheckForExistingToken();
|
||||
}
|
||||
|
||||
return graphTask;
|
||||
})
|
||||
.then([=](FBResult^ oauthResult) -> task<FBResult^>
|
||||
{
|
||||
task<FBResult^> graphTask = create_task([]() -> FBResult^
|
||||
{
|
||||
return nullptr;
|
||||
});
|
||||
|
||||
if (oauthResult && oauthResult->Succeeded)
|
||||
{
|
||||
Facebook::FBAccessTokenData^ tokenData =
|
||||
static_cast<Facebook::FBAccessTokenData^>(oauthResult->Object);
|
||||
if (!tokenData->IsExpired())
|
||||
{
|
||||
AccessTokenData = tokenData;
|
||||
graphTask = create_task([=]() -> FBResult^
|
||||
{
|
||||
return ref new FBResult(AccessTokenData);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return graphTask;
|
||||
})
|
||||
.then([=](FBResult^ graphResult)
|
||||
{
|
||||
task<FBResult^> loginResult;
|
||||
|
||||
|
@ -954,28 +1002,47 @@ task<FBResult^> FBSession::TryLoginViaWebAuthBroker(
|
|||
}
|
||||
else
|
||||
{
|
||||
loginResult = RunOAuthOnUiThread();
|
||||
loginResult = RunOAuthOnUiThread(Parameters);
|
||||
}
|
||||
|
||||
return loginResult;
|
||||
});
|
||||
}
|
||||
|
||||
BOOL FBSession::IsRerequest(
|
||||
PropertySet^ Parameters
|
||||
)
|
||||
{
|
||||
BOOL isRerequest = FALSE;
|
||||
|
||||
if (Parameters && Parameters->HasKey(AuthTypeKey))
|
||||
{
|
||||
String^ Value = static_cast<String^>(Parameters->Lookup(AuthTypeKey));
|
||||
|
||||
if (!String::CompareOrdinal(Value, Rerequest))
|
||||
{
|
||||
isRerequest = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return isRerequest;
|
||||
}
|
||||
|
||||
void FBSession::SetAPIVersion(
|
||||
int MajorVersion,
|
||||
int MinorVersion
|
||||
)
|
||||
int MajorVersion,
|
||||
int MinorVersion
|
||||
)
|
||||
{
|
||||
_APIMajorVersion = MajorVersion;
|
||||
_APIMinorVersion = MinorVersion;
|
||||
_APIMajorVersion = MajorVersion;
|
||||
_APIMinorVersion = MinorVersion;
|
||||
}
|
||||
|
||||
int FBSession::APIMajorVersion::get()
|
||||
int FBSession::APIMajorVersion::get()
|
||||
{
|
||||
return _APIMajorVersion;
|
||||
return _APIMajorVersion;
|
||||
}
|
||||
|
||||
int FBSession::APIMinorVersion::get()
|
||||
int FBSession::APIMinorVersion::get()
|
||||
{
|
||||
return _APIMinorVersion;
|
||||
return _APIMinorVersion;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "FacebookResult.h"
|
||||
#include "FBUser.h"
|
||||
#include "FacebookDialog.xaml.h"
|
||||
#include "FacebookPermissions.h"
|
||||
|
||||
namespace Facebook
|
||||
{
|
||||
|
@ -81,29 +82,15 @@ namespace Facebook
|
|||
void set(FBAccessTokenData^ value);
|
||||
}
|
||||
|
||||
property int APIMajorVersion
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
property int APIMinorVersion
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
//! Returns the list of permissions
|
||||
property Windows::Foundation::Collections::IVectorView<Platform::String^>^ Permissions
|
||||
property int APIMajorVersion
|
||||
{
|
||||
Windows::Foundation::Collections::IVectorView<Platform::String^>^ get();
|
||||
int get();
|
||||
}
|
||||
|
||||
//! Request a new permission
|
||||
void AddPermission(
|
||||
Platform::String^ permission
|
||||
);
|
||||
|
||||
void ResetPermissions(
|
||||
);
|
||||
property int APIMinorVersion
|
||||
{
|
||||
int get();
|
||||
}
|
||||
|
||||
//! FBSession is a singleton object - ActiveSession is the way to
|
||||
//! acquire a reference to the object.
|
||||
|
@ -135,23 +122,22 @@ namespace Facebook
|
|||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
Platform::String^ PermissionsToString(
|
||||
);
|
||||
|
||||
Windows::Foundation::IAsyncOperation<FBResult^>^ LoginAsync(
|
||||
Facebook::FBPermissions^ Permissions
|
||||
);
|
||||
|
||||
void SetAPIVersion(
|
||||
int MajorVersion,
|
||||
int MinorVersion
|
||||
);
|
||||
void SetAPIVersion(
|
||||
int MajorVersion,
|
||||
int MinorVersion
|
||||
);
|
||||
|
||||
private:
|
||||
FBSession();
|
||||
|
||||
~FBSession();
|
||||
~FBSession();
|
||||
|
||||
Windows::Foundation::Uri^ BuildLoginUri(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
Platform::String^ GetRedirectUriString(
|
||||
|
@ -183,32 +169,41 @@ namespace Facebook
|
|||
concurrency::task<FBResult^> GetAppPermissions(
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^>
|
||||
ProcessAuthResult(
|
||||
Windows::Security::Authentication::Web::WebAuthenticationResult^ authResult
|
||||
);
|
||||
concurrency::task<Facebook::FBResult^>
|
||||
ProcessAuthResult(
|
||||
Windows::Security::Authentication::Web::WebAuthenticationResult^ authResult
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> TryGetUserInfoAfterLogin(
|
||||
Facebook::FBResult^ loginResult
|
||||
);
|
||||
concurrency::task<Facebook::FBResult^> TryGetUserInfoAfterLogin(
|
||||
Facebook::FBResult^ loginResult
|
||||
);
|
||||
|
||||
concurrency::task<Facebook::FBResult^> TryGetAppPermissionsAfterLogin(
|
||||
Facebook::FBResult^ loginResult
|
||||
);
|
||||
concurrency::task<Facebook::FBResult^> TryGetAppPermissionsAfterLogin(
|
||||
Facebook::FBResult^ loginResult
|
||||
);
|
||||
|
||||
concurrency::task<FBResult^> RunOAuthOnUiThread(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
concurrency::task<FBResult^> RunWebViewLoginOnUIThread(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
concurrency::task<FBResult^> ShowLoginDialog(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
concurrency::task<FBResult^> TryLoginViaWebView(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
concurrency::task<FBResult^> TryLoginViaWebAuthBroker(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
BOOL IsRerequest(
|
||||
Windows::Foundation::Collections::PropertySet^ Parameters
|
||||
);
|
||||
|
||||
Platform::String^ _FBAppId;
|
||||
|
@ -216,12 +211,11 @@ namespace Facebook
|
|||
bool _loggedIn;
|
||||
Platform::String^ _AppResponse;
|
||||
Facebook::FBAccessTokenData^ _AccessTokenData;
|
||||
Platform::Collections::Vector<Platform::String^>^ _permissions;
|
||||
Facebook::Graph::FBUser^ _user;
|
||||
concurrency::task<Facebook::FBResult^> _loginTask;
|
||||
concurrency::task<Facebook::FBResult^> _loginTask;
|
||||
Facebook::FacebookDialog^ _dialog;
|
||||
BOOL _showingDialog;
|
||||
int _APIMajorVersion;
|
||||
int _APIMinorVersion;
|
||||
int _APIMajorVersion;
|
||||
int _APIMinorVersion;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -224,4 +224,4 @@
|
|||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -21,13 +21,13 @@
|
|||
|
||||
#include "pch.h"
|
||||
#include "MainPage.xaml.h"
|
||||
#include "UserInfo.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
|
@ -48,30 +48,159 @@ using namespace Windows::UI::Xaml::Navigation;
|
|||
|
||||
#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();
|
||||
|
||||
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();
|
||||
|
||||
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;
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
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);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
return ref new FBPermissions(v->GetView());
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
|
||||
|
||||
if (data)
|
||||
{
|
||||
success = !data->DeclinedPermissions->Values->Size;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
(result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->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);
|
||||
}));
|
||||
}
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(
|
||||
Object^ sender,
|
||||
RoutedEventArgs^ e
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
|
@ -85,38 +214,32 @@ void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::Rout
|
|||
}
|
||||
else
|
||||
{
|
||||
sess->AddPermission("public_profile");
|
||||
sess->AddPermission("user_friends");
|
||||
sess->AddPermission("user_likes");
|
||||
sess->AddPermission("user_groups");
|
||||
sess->AddPermission("user_location");
|
||||
|
||||
create_task(sess->LoginAsync()).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
LogoutAndRetry();
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
else if (result->Succeeded)
|
||||
{
|
||||
// Got a token and all our permissions.
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,35 @@ namespace LoginCpp
|
|||
MainPage();
|
||||
|
||||
private:
|
||||
void login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -23,96 +23,225 @@
|
|||
#include "MainPage.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace LoginCpp;
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::Security::Authentication::Web;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
using namespace Windows::UI::Xaml::Controls::Primitives;
|
||||
using namespace Windows::UI::Xaml::Data;
|
||||
using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Facebook;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||
|
||||
#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();
|
||||
|
||||
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
|
||||
OutputDebugString(whatever->Data());
|
||||
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
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();
|
||||
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
FBPermissions^ result = nullptr;
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
if (sess->LoggedIn)
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
result = ref new FBPermissions(v->GetView());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
|
||||
unsigned int grantedCount = 0;
|
||||
|
||||
if (data)
|
||||
{
|
||||
success = !data->DeclinedPermissions->Values->Size;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException) &&
|
||||
(result->ErrorInfo->Subcode == (int)Facebook::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([this]()
|
||||
{
|
||||
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");
|
||||
|
||||
create_task(sess->LoginAsync()).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
f->Navigate(OptionsPage::typeid);
|
||||
}));
|
||||
}
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(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
|
||||
{
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
LogoutAndRetry();
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
else if (result && result->Succeeded)
|
||||
{
|
||||
// Got a token, and all the permissions we wanted - go ahead to the options page
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,36 @@ namespace LoginCpp
|
|||
public:
|
||||
MainPage();
|
||||
|
||||
private:
|
||||
void login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
private:
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<DebuggerFlavor>WindowsPhoneEmulatorDebugger</DebuggerFlavor>
|
||||
<WindowsPhoneEmulatorID>8BDF218D-FDBB-4A97-90F9-3AA33B559A92;Mobile Emulator 10.0.10240.0 WVGA 4 inch 512MB</WindowsPhoneEmulatorID>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -9,7 +9,7 @@
|
|||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
|
||||
<Grid>
|
||||
<Button x:Name ="LoginButton" Content="Login" HorizontalAlignment="Left" Margin="39,48,0,0" VerticalAlignment="Top" Click="LoginButton_Click" Width="315"/>
|
||||
<Button x:Name ="LoginButton" Content="Login" HorizontalAlignment="Left" Margin="39,48,0,0" VerticalAlignment="Top" Click="login_OnClicked" Width="315"/>
|
||||
<TextBlock FontSize="14" HorizontalAlignment="Left" Margin="39,302,0,0" TextWrapping="Wrap" Text="Access Token:" VerticalAlignment="Top" Width="261" Height="18"/>
|
||||
<TextBlock x:Name="ResponseText" FontSize="14" HorizontalAlignment="Left" Margin="39,325,0,0" Text="TextBox" TextWrapping="Wrap" VerticalAlignment="Top" Height="94" Width="261"/>
|
||||
<TextBlock FontSize="14" HorizontalAlignment="Left" Margin="39,445,0,0" TextWrapping="Wrap" Text="Expires" VerticalAlignment="Top" Height="24" Width="261"/>
|
||||
|
|
|
@ -23,13 +23,18 @@
|
|||
#include "MainPage.xaml.h"
|
||||
#include "OptionsPage.xaml.h"
|
||||
|
||||
using namespace LoginCpp;
|
||||
|
||||
using namespace concurrency;
|
||||
using namespace Facebook;
|
||||
using namespace LoginCpp;
|
||||
using namespace Platform;
|
||||
using namespace Platform::Collections;
|
||||
using namespace Windows::ApplicationModel;
|
||||
using namespace Windows::ApplicationModel::Activation;
|
||||
using namespace Windows::ApplicationModel::Core;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Foundation;
|
||||
using namespace Windows::Foundation::Collections;
|
||||
using namespace Windows::Security::Authentication::Web;
|
||||
using namespace Windows::UI::Core;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
|
@ -38,118 +43,204 @@ using namespace Windows::UI::Xaml::Data;
|
|||
using namespace Windows::UI::Xaml::Input;
|
||||
using namespace Windows::UI::Xaml::Media;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Windows::ApplicationModel::Resources;
|
||||
using namespace Windows::Globalization;
|
||||
using namespace Facebook;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
|
||||
|
||||
#define FBAppIDName L"FBApplicationId"
|
||||
#define FBPhoneAppIDName L"FBWinPhoneAppId"
|
||||
#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();
|
||||
InitializeComponent();
|
||||
|
||||
String^ whatever = WebAuthenticationBroker::GetCurrentApplicationCallbackUri()->DisplayUri + L"\n";
|
||||
OutputDebugString(whatever->Data());
|
||||
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
void MainPage::SetSessionAppIds()
|
||||
{
|
||||
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();
|
||||
|
||||
FBSession^ s = FBSession::ActiveSession;
|
||||
|
||||
String^ appId = rl->GetString(FBAppIDName);
|
||||
String^ winAppId = rl->GetString(FBPhoneAppIDName);
|
||||
|
||||
String^ winAppId = rl->GetString(FBStoreAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s->FBAppId = appId;
|
||||
s->WinAppId = winAppId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when this page is about to be displayed in a Frame.
|
||||
/// </summary>
|
||||
/// <param name="e">Event data that describes how this page was reached. The Parameter
|
||||
/// property is typically used to configure the page.</param>
|
||||
void MainPage::OnNavigatedTo(NavigationEventArgs^ e)
|
||||
{
|
||||
(void)e; // Unused parameter
|
||||
|
||||
// TODO: Prepare page for display here.
|
||||
|
||||
// TODO: If your application contains multiple pages, ensure that you are
|
||||
// handling the hardware Back button by registering for the
|
||||
// Windows::Phone::UI::Input::HardwareButtons.BackPressed event.
|
||||
// If you are using the NavigationHelper provided by some templates,
|
||||
// this event is handled for you.
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
Calendar^ cal = ref new Calendar();
|
||||
cal->SetDateTime(sess->AccessTokenData->ExpirationDate);
|
||||
|
||||
ResponseText->Text = sess->AccessTokenData->AccessToken;
|
||||
|
||||
ExpirationDate->Text = cal->DayOfWeekAsString() + "," + cal->YearAsString() + "/" +
|
||||
cal->MonthAsNumericString() + "/" + cal->DayAsString() + ", " +
|
||||
cal->HourAsPaddedString(2) + ":" + cal->MinuteAsPaddedString(2) + ":" +
|
||||
cal->SecondAsPaddedString(2);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginCpp::MainPage::LoginButton_Click(
|
||||
Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
FBPermissions^ MainPage::BuildPermissions(
|
||||
)
|
||||
{
|
||||
// Get the active session, set it up with the parameters it needs, and
|
||||
// start Login process.
|
||||
FBPermissions^ result = nullptr;
|
||||
Vector<String^>^ v = ref new Vector<String^>();
|
||||
|
||||
for (unsigned int i = 0; i < ARRAYSIZE(requested_permissions); i++)
|
||||
{
|
||||
v->Append(ref new String(requested_permissions[i]));
|
||||
}
|
||||
|
||||
result = ref new FBPermissions(v->GetView());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL MainPage::DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
FBAccessTokenData^ data = FBSession::ActiveSession->AccessTokenData;
|
||||
unsigned int grantedCount = 0;
|
||||
|
||||
if (data)
|
||||
{
|
||||
success = !data->DeclinedPermissions->Values->Size;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
(!result->Succeeded) &&
|
||||
((result->ErrorInfo->Code == (int)Facebook::ErrorCode::ErrorCodeOauthException) &&
|
||||
(result->ErrorInfo->Subcode == (int)Facebook::ErrorSubcode::ErrorSubcodeSessionInvalidated)));
|
||||
}
|
||||
|
||||
BOOL MainPage::ShouldRerequest(
|
||||
FBResult^ result
|
||||
)
|
||||
{
|
||||
return (result &&
|
||||
result->Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
void MainPage::NavigateToOptionsPage()
|
||||
{
|
||||
LoginButton->Content = L"Logout";
|
||||
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->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);
|
||||
}));
|
||||
}
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
create_task(FBSession::ActiveSession->LoginAsync(BuildPermissions()))
|
||||
.then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
{
|
||||
if (retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(false);
|
||||
}));
|
||||
}
|
||||
else
|
||||
{
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
)
|
||||
{
|
||||
// It's necessary to logout prior to reattempting login, because it could
|
||||
// be that the session has cached an access token that is no longer valid,
|
||||
// e.g. if the user revoked the app in Settings. FBSession::Logout clears
|
||||
// the session's cached access token, among other things.
|
||||
create_task(FBSession::ActiveSession->Logout())
|
||||
.then([=]()
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
TryRerequest(TRUE);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
void MainPage::login_OnClicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
|
||||
{
|
||||
FBSession^ sess = FBSession::ActiveSession;
|
||||
|
||||
if (sess->LoggedIn)
|
||||
{
|
||||
sess->Logout();
|
||||
LoginButton->Content = L"Login";
|
||||
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");
|
||||
|
||||
create_task(sess->LoginAsync()).then([=](FBResult^ result)
|
||||
create_task(sess->LoginAsync(BuildPermissions())).then([=](FBResult^ result)
|
||||
{
|
||||
if (result->Succeeded)
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
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)
|
||||
LogoutAndRetry();
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
// Login call has to happen on UI thread, so circle back around to it
|
||||
CoreApplication::MainView->CoreWindow->Dispatcher->RunAsync(
|
||||
Windows::UI::Core::CoreDispatcherPriority::Normal,
|
||||
ref new Windows::UI::Core::DispatchedHandler([=]()
|
||||
{
|
||||
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);
|
||||
}));
|
||||
}
|
||||
}
|
||||
TryRerequest(FALSE);
|
||||
}));
|
||||
}
|
||||
else if (result && result->Succeeded)
|
||||
{
|
||||
// Got a token, and all the permissions we wanted - go ahead to the options page
|
||||
NavigateToOptionsPage();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -25,29 +25,45 @@
|
|||
|
||||
namespace LoginCpp
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public ref class MainPage sealed
|
||||
{
|
||||
public:
|
||||
MainPage();
|
||||
|
||||
protected:
|
||||
virtual void OnNavigatedTo(
|
||||
Windows::UI::Xaml::Navigation::NavigationEventArgs^ e
|
||||
) override;
|
||||
/// <summary>
|
||||
/// An empty page that can be used on its own or navigated to within a Frame.
|
||||
/// </summary>
|
||||
public ref class MainPage sealed
|
||||
{
|
||||
public:
|
||||
MainPage();
|
||||
|
||||
private:
|
||||
void StartLogin(
|
||||
Facebook::FBSession^ Session
|
||||
void MainPage::SetSessionAppIds(
|
||||
);
|
||||
|
||||
void LoginButton_Click(
|
||||
Platform::Object^ sender,
|
||||
Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
Facebook::FBPermissions^ BuildPermissions(
|
||||
);
|
||||
|
||||
Windows::Foundation::EventRegistrationToken m_cookie;
|
||||
BOOL DidGetAllRequestedPermissions(
|
||||
);
|
||||
|
||||
BOOL MainPage::WasAppPermissionRemovedByUser(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
BOOL ShouldRerequest(
|
||||
Facebook::FBResult^ result
|
||||
);
|
||||
|
||||
void NavigateToOptionsPage(
|
||||
);
|
||||
|
||||
void MainPage::TryRerequest(
|
||||
BOOL retry
|
||||
);
|
||||
|
||||
void MainPage::LogoutAndRetry(
|
||||
);
|
||||
|
||||
void login_OnClicked(
|
||||
Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e
|
||||
);
|
||||
void LoginButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.22823.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LoginCs", "LoginCs", "{F3A8EFF0-4471-4905-B279-756B1D864AAB}"
|
||||
EndProject
|
||||
|
|
|
@ -75,11 +75,11 @@ namespace LoginCs
|
|||
#else
|
||||
sess.WinAppId = loader.GetString(FBStoreAppIDName);
|
||||
#endif
|
||||
sess.AddPermission("public_profile");
|
||||
sess.AddPermission("user_friends");
|
||||
sess.AddPermission("email");
|
||||
sess.AddPermission("user_likes");
|
||||
sess.AddPermission("user_groups");
|
||||
//sess.AddPermission("public_profile");
|
||||
//sess.AddPermission("user_friends");
|
||||
//sess.AddPermission("email");
|
||||
//sess.AddPermission("user_likes");
|
||||
//sess.AddPermission("user_groups");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -182,4 +182,4 @@ namespace LoginCs
|
|||
deferral.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,9 +33,17 @@
|
|||
<Button x:Name="BackButton" Content="Go Back" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="BackButton_Click"/>
|
||||
<Button x:Name="UserLikesButton" Content="Show Likes..." HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="UserLikesButton_Click"/>
|
||||
</StackPanel>
|
||||
|
||||
|
||||
<StackPanel Grid.Row="2" Margin="19,0,0,0">
|
||||
<Ellipse Width="250" Height="250">
|
||||
<Ellipse.Fill>
|
||||
<ImageBrush x:Name="ProfilePicBrush" ImageSource="" />
|
||||
</Ellipse.Fill>
|
||||
</Ellipse>
|
||||
</StackPanel>
|
||||
|
||||
<!--TODO: Content should be placed within the following grid-->
|
||||
<Grid Grid.Row="2" x:Name="ContentRoot" Margin="19,9.5,19,0">
|
||||
<Grid Grid.Row="3" x:Name="ContentRoot" Margin="19,9.5,19,0">
|
||||
<ScrollViewer VerticalScrollBarVisibility="Auto">
|
||||
<StackPanel Grid.Row="0">
|
||||
<TextBlock Text="ID:" Style="{ThemeResource TitleTextBlockStyle}" Margin="0,12,0,0"/>
|
||||
|
|
|
@ -31,6 +31,7 @@ using Windows.UI.Xaml.Navigation;
|
|||
|
||||
using Facebook;
|
||||
using Facebook.Graph;
|
||||
using Windows.UI.Xaml.Media.Imaging;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
|
@ -64,9 +65,35 @@ namespace LoginCs
|
|||
UserUpdatedTime.Text = user.UpdatedTime;
|
||||
UserVerified.Text = user.Verified.ToString();
|
||||
SquarePicture.UserId = user.Id;
|
||||
LoadRoundProfilePicture(user.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async void LoadRoundProfilePicture(
|
||||
String UserId
|
||||
)
|
||||
{
|
||||
PropertySet parameters = new PropertySet();
|
||||
String path = "/" + UserId + "/picture";
|
||||
|
||||
parameters.Add(new KeyValuePair<String, Object>("redirect", "false"));
|
||||
|
||||
// Just picking a width and height for now
|
||||
parameters.Add(new KeyValuePair<String, Object>("width", "200"));
|
||||
parameters.Add(new KeyValuePair<String, Object>("height", "200"));
|
||||
|
||||
FBSingleValue value = new FBSingleValue(path, parameters,
|
||||
new FBJsonClassFactory(FBProfilePicture.FromJson));
|
||||
|
||||
FBResult result = await value.Get();
|
||||
if (result.Succeeded)
|
||||
{
|
||||
FBProfilePicture pic = (FBProfilePicture)result.Object;
|
||||
ProfilePicBrush.ImageSource = new BitmapImage(pic.URL);
|
||||
}
|
||||
}
|
||||
|
||||
private void UserLikesButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Frame.Navigate(typeof(UserLikes));
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
<SynthesizeLinkMetadata>true</SynthesizeLinkMetadata>
|
||||
<ProjectTypeGuids>{BC8A1FFA-BEE3-4634-8014-F334798102B3};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<PackageCertificateKeyFile>LoginCs.Windows_TemporaryKey.pfx</PackageCertificateKeyFile>
|
||||
<NuGetPackageImportStamp>3faccb8c</NuGetPackageImportStamp>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
|
|
@ -32,6 +32,8 @@ using Windows.UI.Xaml.Navigation;
|
|||
|
||||
using Facebook;
|
||||
using Windows.Globalization;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
|
||||
|
||||
|
@ -45,18 +47,109 @@ namespace LoginCs
|
|||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
private async void LoginToFB()
|
||||
{
|
||||
Uri endURI =
|
||||
WebAuthenticationBroker.GetCurrentApplicationCallbackUri();
|
||||
string uriString = endURI.ToString();
|
||||
private const string FBAppIDName = "FBApplicationId";
|
||||
private const string FBPhoneAppIDName = "FBWinPhoneAppId";
|
||||
private const string PermissionGranted = "granted";
|
||||
|
||||
private readonly string[] requested_permissions =
|
||||
{
|
||||
"public_profile",
|
||||
"email",
|
||||
"user_friends",
|
||||
"publish_actions"
|
||||
};
|
||||
|
||||
void SetSessionAppIds(
|
||||
)
|
||||
{
|
||||
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(FBPhoneAppIDName);
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s.FBAppId = appId;
|
||||
s.WinAppId = winAppId;
|
||||
}
|
||||
|
||||
FBPermissions BuildPermissions(
|
||||
)
|
||||
{
|
||||
FBPermissions result = null;
|
||||
List<string> perms = new List<string>();
|
||||
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
perms.Add(requested_permissions[i]);
|
||||
}
|
||||
|
||||
result = new FBPermissions(perms);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
bool success = false;
|
||||
FBAccessTokenData data = FBSession.ActiveSession.AccessTokenData;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
success = (data.DeclinedPermissions.Values.Count == 0);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool WasAppPermissionRemovedByUser(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
(!Result.Succeeded) &&
|
||||
(Result.ErrorInfo.Code == (int)Facebook.ErrorCode.ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
bool ShouldRerequest(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
Result.Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
async Task TryRerequest(
|
||||
bool Retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(BuildPermissions());
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync();
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Frame.Navigate(typeof(UserInfo));
|
||||
if (Retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,7 +202,27 @@ namespace LoginCs
|
|||
else
|
||||
{
|
||||
LoginButton.Content = "Logout";
|
||||
LoginToFB();
|
||||
FBResult result = await sess.LoginAsync(BuildPermissions());
|
||||
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
await sess.Logout();
|
||||
await TryRerequest(true);
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else if (result.Succeeded)
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="win81" userInstalled="true" />
|
||||
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="win81" userInstalled="true" />
|
||||
</packages>
|
||||
|
|
|
@ -15,9 +15,10 @@
|
|||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{76F1466A-8B6D-4E39-A767-685A06062A39};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<SynthesizeLinkMetadata>true</SynthesizeLinkMetadata>
|
||||
<NuGetPackageImportStamp>f8140d1d</NuGetPackageImportStamp>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -160,4 +161,4 @@
|
|||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -20,6 +20,7 @@ using System.Collections.Generic;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
@ -41,41 +42,116 @@ namespace LoginCs
|
|||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
const string FBAppIDName = "FBApplicationId";
|
||||
const string FBPhoneAppIDName = "FBWinPhoneAppId";
|
||||
const string FBAppIDName = "FBApplicationId";
|
||||
const string FBPhoneAppIDName = "FBWinPhoneAppId";
|
||||
const string PermissionGranted = "granted";
|
||||
|
||||
readonly string[] requested_permissions =
|
||||
{
|
||||
"public_profile",
|
||||
"user_friends",
|
||||
"user_likes",
|
||||
"user_groups",
|
||||
"user_location"
|
||||
};
|
||||
|
||||
public MainPage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
|
||||
this.NavigationCacheMode = NavigationCacheMode.Required;
|
||||
SetSessionAppIds();
|
||||
}
|
||||
|
||||
public async void StartLogin(
|
||||
|
||||
void SetSessionAppIds(
|
||||
)
|
||||
{
|
||||
FBSession s = FBSession.ActiveSession;
|
||||
|
||||
// Assumes the Facebook App ID and Windows Phone Store ID have been
|
||||
// saved in the default resource file.
|
||||
// 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(FBPhoneAppIDName);
|
||||
|
||||
|
||||
// IDs are both sent to FB app, so it can validate us.
|
||||
s.FBAppId = appId;
|
||||
s.WinAppId = winAppId;
|
||||
}
|
||||
|
||||
// These are the default permissions, needed to retrieve user info.
|
||||
s.AddPermission("public_profile");
|
||||
s.AddPermission("user_friends");
|
||||
s.AddPermission("user_likes");
|
||||
FBPermissions BuildPermissions(
|
||||
)
|
||||
{
|
||||
FBPermissions result = null;
|
||||
List<string> perms = new List<string>();
|
||||
|
||||
// Launches a URI to redirect to the FB app, which will log us in
|
||||
// and return the result via our registered protocol.
|
||||
FBResult result = await s.LoginAsync();
|
||||
for (uint i = 0; i < requested_permissions.Length; i++)
|
||||
{
|
||||
perms.Add(requested_permissions[i]);
|
||||
}
|
||||
|
||||
result = new FBPermissions(perms);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool DidGetAllRequestedPermissions(
|
||||
)
|
||||
{
|
||||
bool success = false;
|
||||
FBAccessTokenData data = FBSession.ActiveSession.AccessTokenData;
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
success = (data.DeclinedPermissions.Values.Count == 0);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool WasAppPermissionRemovedByUser(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
(!Result.Succeeded) &&
|
||||
(Result.ErrorInfo.Code == (int)Facebook.ErrorCode.ErrorCodeOauthException));
|
||||
}
|
||||
|
||||
bool ShouldRerequest(
|
||||
FBResult Result
|
||||
)
|
||||
{
|
||||
return ((Result != null) &&
|
||||
Result.Succeeded &&
|
||||
!DidGetAllRequestedPermissions());
|
||||
}
|
||||
|
||||
async Task TryRerequest(
|
||||
bool Retry
|
||||
)
|
||||
{
|
||||
// If we're logged out, the session has cleared the FB and Windows app IDs,
|
||||
// so they need to be set again. We load these IDs via the ResourceLoader
|
||||
// class, which must be accessed on the UI thread, which is why this call
|
||||
// is outside the task context.
|
||||
SetSessionAppIds();
|
||||
|
||||
FBResult result = await FBSession.ActiveSession.LoginAsync(BuildPermissions());
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
if (Retry && (!DidGetAllRequestedPermissions()))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -123,7 +199,27 @@ namespace LoginCs
|
|||
else
|
||||
{
|
||||
LoginButton.Content = "Logout";
|
||||
StartLogin();
|
||||
|
||||
FBResult result = await sess.LoginAsync(BuildPermissions());
|
||||
|
||||
// There may be other cases where an a failed login request should
|
||||
// prompt the app to retry login, but this one is common enough that
|
||||
// it's helpful to demonstrate handling it here. If the predicate
|
||||
// returns TRUE, the user has gone to facebook.com in the browser,
|
||||
// and removed our app from their list off allowed apps in Settings.
|
||||
if (WasAppPermissionRemovedByUser(result))
|
||||
{
|
||||
await sess.Logout();
|
||||
}
|
||||
else if (ShouldRerequest(result))
|
||||
{
|
||||
await TryRerequest(false);
|
||||
}
|
||||
else if (result.Succeeded)
|
||||
{
|
||||
//Navigate back to same page, to clear out logged in info.
|
||||
App.RootFrame.Navigate(typeof(UserInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче