Merge pull request #44 from Microsoft/3_rerequest_permissions

3 rerequest permissions
This commit is contained in:
Gilles Khouzam 2015-08-19 16:13:50 -07:00
Родитель a006a50eb4 b69edec68b
Коммит c76878059b
35 изменённых файлов: 1672 добавлений и 957 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -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));
}
}
}
}