Skip to content

Commit 964569e

Browse files
polothysamchaffee
authored andcommitted
INT-12420: Allow the key/secret to be optional for S3 file system
1 parent fded1f9 commit 964569e

File tree

5 files changed

+382
-7
lines changed

5 files changed

+382
-7
lines changed

classes/aws_apcu_cache.php

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* An APCu cache for AWS.
19+
*
20+
* @package local_aws_sdk
21+
* @copyright Copyright (c) 2017 Blackboard Inc. (http://www.blackboard.com)
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
namespace local_aws_sdk;
26+
27+
use Aws\CacheInterface;
28+
29+
defined('MOODLE_INTERNAL') || die();
30+
31+
/**
32+
* An APCu cache for AWS.
33+
*
34+
* @package local_aws_sdk
35+
* @copyright Copyright (c) 2017 Blackboard Inc. (http://www.blackboard.com)
36+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37+
*/
38+
class aws_apcu_cache implements CacheInterface {
39+
/**
40+
* Determine if this cache is usable.
41+
*
42+
* @return bool
43+
*/
44+
public static function are_requirements_met() {
45+
// APCu on the CLI does not persist cached values between CLI runs.
46+
// So, rather pointless to use on the CLI.
47+
if (CLI_SCRIPT && !PHPUNIT_TEST) {
48+
return false;
49+
}
50+
if (!extension_loaded('apcu') || !ini_get('apc.enabled')) {
51+
return false;
52+
}
53+
54+
return true;
55+
}
56+
57+
/**
58+
* Get a cache item by key.
59+
*
60+
* @param string $key Key to retrieve.
61+
*
62+
* @return mixed|null Returns the value or null if not found.
63+
*/
64+
public function get($key) {
65+
$success = false;
66+
$value = apcu_fetch($key, $success);
67+
68+
return $success ? $value : null;
69+
}
70+
71+
/**
72+
* Set a cache key value.
73+
*
74+
* @param string $key Key to set
75+
* @param mixed $value Value to set.
76+
* @param int $ttl Number of seconds the item is allowed to live. Set
77+
* to 0 to allow an unlimited lifetime.
78+
*/
79+
public function set($key, $value, $ttl = 0) {
80+
$success = apcu_store($key, $value, $ttl);
81+
82+
if (!$success) {
83+
debugging('Failed to store cached value in APCu');
84+
}
85+
}
86+
87+
/**
88+
* Remove a cache key.
89+
*
90+
* @param string $key Key to remove.
91+
*/
92+
public function remove($key) {
93+
apcu_delete($key);
94+
}
95+
}

classes/aws_sdk.php

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class aws_sdk {
3737
/**
3838
* Required AWS config names.
3939
*/
40-
const REQUIRED_CONFIGS = ['key', 'secret', 'region'];
40+
const REQUIRED_CONFIGS = ['region'];
4141

4242
/**
4343
* Autoload the AWS SDK classes.
@@ -69,12 +69,51 @@ public static function config_from_cfg($name) {
6969
}
7070
}
7171

72-
return [
73-
'region' => $cfg['region'],
74-
'credentials' => [
72+
$config = ['region' => $cfg['region']];
73+
74+
$credentials = self::resolve_credentials($name, $cfg);
75+
if (!empty($credentials)) {
76+
$config['credentials'] = $credentials;
77+
}
78+
79+
return $config;
80+
}
81+
82+
/**
83+
* Extract AWS credentials from CFG value.
84+
*
85+
* @param string $name The CFG name.
86+
* @param array $cfg The Moodle config value.
87+
* @return mixed
88+
*/
89+
private static function resolve_credentials($name, array $cfg) {
90+
// First check for key/secret credentials.
91+
if (array_key_exists('key', $cfg) && array_key_exists('secret', $cfg)) {
92+
return [
7593
'key' => $cfg['key'],
7694
'secret' => $cfg['secret']
77-
],
78-
];
95+
];
96+
}
97+
98+
// With no credentials set, then the AWS SDK will fallback to various means for acquiring credentials.
99+
// See http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/configuration.html#credentials for details.
100+
101+
// When using IAM roles, we can set credentials to a cache so the SDK doesn't have to ping the metadata service every time.
102+
// See http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#instance-profile-credentials for details.
103+
if (array_key_exists('credentials_cache', $cfg)) {
104+
// Ensure we are loading as caches require this.
105+
self::autoload();
106+
107+
$type = $cfg['credentials_cache'];
108+
if ($type === 'apcu') {
109+
if (aws_apcu_cache::are_requirements_met()) {
110+
return new aws_apcu_cache();
111+
}
112+
} else {
113+
throw new \coding_exception('The $CFG->'.$name.'[\'credentials_cache\'] value is unknown: '.$type);
114+
}
115+
}
116+
117+
return [];
79118
}
80119
}

tests/aws_apcu_cache_test.php

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
// This file is part of Moodle - http://moodle.org/
3+
//
4+
// Moodle is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// Moodle is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16+
17+
/**
18+
* Tests for APCu cache.
19+
*
20+
* @package local_aws_sdk
21+
* @copyright Copyright (c) 2017 Blackboard Inc. (http://www.blackboard.com)
22+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23+
*/
24+
25+
use Aws\Credentials\Credentials;
26+
use local_aws_sdk\aws_apcu_cache;
27+
use local_aws_sdk\aws_sdk;
28+
29+
defined('MOODLE_INTERNAL') || die();
30+
31+
/**
32+
* Tests for APCu cache.
33+
*
34+
* @package local_aws_sdk
35+
* @copyright Copyright (c) 2017 Blackboard Inc. (http://www.blackboard.com)
36+
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
37+
*/
38+
class local_aws_sdk_aws_apcu_cache_testcase extends advanced_testcase {
39+
40+
const TEST_KEY = 'phpunit_local_aws_sdk_test';
41+
42+
protected function setUp() {
43+
if (!extension_loaded('apcu')) {
44+
$this->markTestSkipped('The APCu extension is not loaded');
45+
}
46+
if (!ini_get('apc.enabled')) {
47+
$this->markTestSkipped('The APCu extension is not enabled');
48+
}
49+
if (!ini_get('apc.enable_cli')) {
50+
$this->markTestSkipped('The APCu extension is not enabled for CLI');
51+
}
52+
}
53+
54+
protected function tearDown() {
55+
apcu_delete(self::TEST_KEY);
56+
}
57+
58+
/**
59+
* @param mixed $value
60+
* @dataProvider value_provider
61+
*/
62+
public function test_cache($value) {
63+
$cache = new aws_apcu_cache();
64+
$cache->set(self::TEST_KEY, $value);
65+
$this->assertDebuggingNotCalled();
66+
67+
$result = $cache->get(self::TEST_KEY);
68+
$this->assertNotNull($result);
69+
70+
if ($value instanceof Credentials) {
71+
$this->assertInstanceOf(Credentials::class, $result);
72+
$this->assertSame($value->toArray(), $result->toArray());
73+
} else {
74+
$this->assertSame($value, $result);
75+
}
76+
77+
$cache->remove(self::TEST_KEY);
78+
$this->assertNull($cache->get(self::TEST_KEY));
79+
}
80+
81+
public function value_provider() {
82+
aws_sdk::autoload();
83+
84+
return [
85+
['Hodor value'],
86+
[100],
87+
[['Foo', 'Bar', 100]],
88+
[100.01],
89+
[new Credentials('key', 'secret', 'token', 100)],
90+
];
91+
}
92+
}

0 commit comments

Comments
 (0)