File: Facebook.cpp

package info (click to toggle)
cpprest 2.10.19-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,916 kB
  • sloc: cpp: 71,086; sh: 275; makefile: 170; javascript: 147
file content (138 lines) | stat: -rw-r--r-- 5,232 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/***
 * Copyright (C) Microsoft. All rights reserved.
 * Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 *
 * =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
 *
 * Facebook.cpp - Implementation file for simple facebook client.
 * Note: this implementation will not work until you replace the placeholder
 * strings below with tokens obtained from facebook.
 * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
 ****/

#include "pch.h"

#include "facebook.h"

using namespace pplx;
using namespace web;
using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Security::Authentication::Web;
using namespace Windows::Storage;

// Placeholder strings for app tokens
// see blog post at http://aka.ms/FacebookCppRest
// for information on obtaining these values
const std::wstring application_id(L"insert your application ID");
const std::wstring application_token(L"insert your application token");

facebook_client& facebook_client::instance()
{
    static facebook_client c;
    return c;
}

pplx::task<void> facebook_client::login(std::wstring scopes)
{
    // Look in the Local Settings for previously-stored login credentials
    auto ls = ApplicationData::Current->LocalSettings->CreateContainer("LoginDetailsCache",
                                                                       ApplicationDataCreateDisposition::Always);

    if (ls->Values->HasKey("facebookToken"))
    {
        token_ = dynamic_cast<String ^>(ls->Values->Lookup("facebookToken"))->Data();
    }

    if (!token_.empty())
    {
        // Check if the token is still valid
        using namespace http;

        uri_builder tokendbg_uri(L"/debug_token");
        tokendbg_uri.append_query(L"input_token", token_);
        tokendbg_uri.append_query(L"access_token", application_token);

        http_request request(methods::GET);
        request.set_request_uri(tokendbg_uri.to_string());
        request.headers().add(header_names::accept, L"application/json");

        return raw_client.request(request)
            .then([](http_response response) { return response.extract_json(); })
            .then(
                [=](json::value v) -> task<void> {
                    auto obj = v[L"data"];

                    if (obj[L"is_valid"].as_bool())
                    {
                        // Currently cached access token is valid
                        signed_in = true;
                        return create_task([]() {}); // Return an empty task to match the function's return value
                    }

                    // If the token was invalid, go through full login
                    return full_login(scopes);
                },
                task_continuation_context::use_current());
    }

    // If no token was found, go through full login
    return full_login(scopes);
}

pplx::task<void> facebook_client::full_login(std::wstring scopes)
{
    // Create uri for OAuth login on Facebook
    http::uri_builder login_uri(L"https://www.facebook.com/dialog/oauth");
    login_uri.append_query(L"client_id", application_id); // App id
    login_uri.append_query(L"redirect_uri", L"https://www.facebook.com/connect/login_success.html");
    login_uri.append_query(L"scope", scopes);
    login_uri.append_query(L"display", L"popup");
    login_uri.append_query(L"response_type", L"token");

    return create_task(WebAuthenticationBroker::AuthenticateAsync(
                           WebAuthenticationOptions::None,
                           ref new Uri(ref new String(login_uri.to_string().c_str())),
                           ref new Uri("https://www.facebook.com/connect/login_success.html")))
        .then([=](WebAuthenticationResult ^ result) {
            if (result->ResponseStatus == WebAuthenticationStatus::Success)
            {
                signed_in = true;

                std::wstring response(result->ResponseData->Data()); // Save authentication token
                auto start = response.find(L"access_token=");
                start += 13;
                auto end = response.find('&');

                token_ = response.substr(start, end - start);

                // Add token to Local Settings for future login attempts
                auto ls = ApplicationData::Current->LocalSettings->CreateContainer(
                    "LoginDetailsCache", ApplicationDataCreateDisposition::Always);

                ls->Values->Insert("facebookToken", ref new String(token_.c_str()));
            }
        });
}

task<json::value> facebook_client::get(std::wstring path)
{
    using namespace http;

    http_request request(methods::GET);

    request.set_request_uri(base_uri().append_path(path).to_uri());
    request.headers().add(header_names::accept, L"application/json");

    return raw_client.request(request).then([](http_response response) { return response.extract_json(); });
}

http::uri_builder facebook_client::base_uri(bool absolute)
{
    http::uri_builder ret;

    if (absolute) ret.set_path(L"https://graph.facebook.com");

    ret.append_query(L"access_token", token_);
    return ret;
}