1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/common/manifest_handlers/oauth2_manifest_handler.h"
7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/values.h"
11 #include "extensions/common/error_utils.h"
12 #include "extensions/common/manifest_constants.h"
17 const char kClientId
[] = "client_id";
18 const char kScopes
[] = "scopes";
19 const char kAutoApprove
[] = "auto_approve";
23 namespace extensions
{
25 namespace keys
= manifest_keys
;
26 namespace errors
= manifest_errors
;
28 OAuth2Info::OAuth2Info() : auto_approve(false) {}
29 OAuth2Info::~OAuth2Info() {}
31 static base::LazyInstance
<OAuth2Info
> g_empty_oauth2_info
=
32 LAZY_INSTANCE_INITIALIZER
;
35 const OAuth2Info
& OAuth2Info::GetOAuth2Info(const Extension
* extension
) {
36 OAuth2Info
* info
= static_cast<OAuth2Info
*>(
37 extension
->GetManifestData(keys::kOAuth2
));
38 return info
? *info
: g_empty_oauth2_info
.Get();
41 OAuth2ManifestHandler::OAuth2ManifestHandler() {
44 OAuth2ManifestHandler::~OAuth2ManifestHandler() {
47 bool OAuth2ManifestHandler::Parse(Extension
* extension
,
48 base::string16
* error
) {
49 scoped_ptr
<OAuth2Info
> info(new OAuth2Info
);
50 const base::DictionaryValue
* dict
= NULL
;
51 if (!extension
->manifest()->GetDictionary(keys::kOAuth2
, &dict
)) {
52 *error
= base::ASCIIToUTF16(errors::kInvalidOAuth2ClientId
);
56 // This should not be possible, but it looks like the source of the crash in
57 // http://crbug.com/445683. Perhaps something is overwriting the stack.
60 // HasPath checks for whether the manifest is allowed to have
61 // oauth2.auto_approve based on whitelist, and if it is present.
62 // GetBoolean reads the value of auto_approve directly from dict to prevent
63 // duplicate checking.
64 if (extension
->manifest()->HasPath(keys::kOAuth2AutoApprove
) &&
65 !dict
->GetBoolean(kAutoApprove
, &info
->auto_approve
)) {
66 *error
= base::ASCIIToUTF16(errors::kInvalidOAuth2AutoApprove
);
70 // Component apps using auto_approve may use Chrome's client ID by
71 // omitting the field.
72 if ((!dict
->GetString(kClientId
, &info
->client_id
) ||
73 info
->client_id
.empty()) &&
74 (extension
->location() != Manifest::COMPONENT
|| !info
->auto_approve
)) {
75 *error
= base::ASCIIToUTF16(errors::kInvalidOAuth2ClientId
);
79 const base::ListValue
* list
= NULL
;
80 if (!dict
->GetList(kScopes
, &list
)) {
81 *error
= base::ASCIIToUTF16(errors::kInvalidOAuth2Scopes
);
85 for (size_t i
= 0; i
< list
->GetSize(); ++i
) {
87 if (!list
->GetString(i
, &scope
)) {
88 *error
= base::ASCIIToUTF16(errors::kInvalidOAuth2Scopes
);
91 info
->scopes
.push_back(scope
);
94 extension
->SetManifestData(keys::kOAuth2
, info
.release());
98 const std::vector
<std::string
> OAuth2ManifestHandler::Keys() const {
99 return SingleKey(keys::kOAuth2
);
102 } // namespace extensions