Skip to content

Commit 10126b9

Browse files
committed
Update/add modules standard files, update documentation to support vendor change
1 parent fa5a0e7 commit 10126b9

33 files changed

+322
-142
lines changed

.editorconfig

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
[*]
2+
charset = utf-8
3+
end_of_line = lf
4+
indent_size = 4
5+
indent_style = space
6+
insert_final_newline = true
7+
trim_trailing_whitespace = true
8+
9+
[*.md]
10+
trim_trailing_whitespace = false
11+
12+
[*.{yml,js,json,css,scss,eslintrc,feature}]
13+
indent_size = 2
14+
indent_style = space
15+
16+
[package.json]
17+
indent_size = 2
18+
19+
[composer.json]
20+
indent_size = 4

.gitattributes

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/tests export-ignore
2+
/docs export-ignore
3+
/client/src export-ignore
4+
/.gitattributes export-ignore
5+
/.gitignore export-ignore
6+
/.php_cs.dist
7+
/phpstan.neon.dist
8+
/phpunit.xml.dist

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
11
/.php_cs.cache
2+
/vendor/
3+
/resources/
4+
/composer.lock
5+
/.php_cs.cache
6+
/app/
7+
/assets/

.php_cs.dist

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
/**
3+
* Configuration file for https://github.com/FriendsOfPHP/PHP-CS-Fixer
4+
* Install with composer: $ composer global require friendsofphp/php-cs-fixer
5+
* Usage (in this directory) : ~/.composer/vendor/bin/php-cs-fixer fix .
6+
*/
7+
$finder = PhpCsFixer\Finder::create()
8+
->in(__DIR__);
9+
10+
return PhpCsFixer\Config::create()
11+
->setRules([
12+
'@PSR2' => true,
13+
'array_indentation' => true,
14+
'array_syntax' => ['syntax' => 'short'],
15+
'blank_line_after_namespace' => true,
16+
'blank_line_after_opening_tag' => true,
17+
'full_opening_tag' => true,
18+
'no_closing_tag' => true,
19+
])
20+
->setIndent(" ")
21+
->setFinder($finder);

LICENCE renamed to LICENSE.md

File renamed without changes.

README.md

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
# One-time field value saving for Silverstripe
2+
3+
A Silverstripe module for storing private string values, optionally encrypted.
4+
5+
To update the value, add the plain text secret to the relevant field and save the record, the old value will be overwritten.
6+
7+
The stored value can be cleared using the supplied checkbox.
8+
9+
## Installing
10+
11+
The only supported method of installing this module is via composer:
12+
13+
```shell
14+
composer require codem/silverstripe-onetime
15+
```
16+
17+
## Requirements
18+
19+
[Per composer.json](./composer.json)
20+
21+
## Configuration
22+
23+
## Partial field value display
24+
25+
Use the following configuration values with your project config to manage partial value display in supporting fields
26+
27+
```yaml
28+
---
29+
Name: app-onetime
30+
After:
31+
- '#onetime'
32+
---
33+
Codem\OneTime\PartialValue:
34+
min_characters_replaced : 6
35+
max_characters_replaced : 18
36+
percent_cleared : 80
37+
replacement_character: '*'
38+
```
39+
40+
## Extension
41+
42+
In your site/module .yml configuration, assign the `HasSecrets` extension to the relevant DataObjects. Once applied and flushed, these dataobjects will be able to access the methods for encryption/decryption provided by the extension.
43+
44+
```yaml
45+
MyOrg\MyDataObject:
46+
extensions:
47+
- 'Codem\OneTime\HasSecrets'
48+
MyOrg\AnotherDataObject:
49+
extensions:
50+
- 'Codem\OneTime\HasSecrets'
51+
```
52+
53+
In the relevant DataObjects, set up a configuration schema to mark certain fields as being handled by the module:
54+
55+
```php
56+
<?php
57+
58+
namespace MyOrg;
59+
60+
use Codem\OneTime\PartialValue;
61+
use SilverStripe\ORM\DataObject;
62+
//...
63+
64+
class MyDataObject extends DataObject {
65+
66+
private static $onetime_field_schema = [
67+
68+
// store a value locally
69+
'TextFieldEmpty' => [
70+
'provider' => 'Local',// this field isn't encrypted
71+
'partial' => false
72+
],
73+
74+
// store the value encrypted with your KMS configuration
75+
'TextFieldPartial' => [
76+
'provider' => 'AmazonKMS',// the stored value is encrypted using AWS KMS
77+
'partial' => true,
78+
'partial_filter' => PartialValue::FILTER_HIDE_MIDDLE // with a specific partial filter
79+
],
80+
'TextFieldPartialDefault' => [
81+
'provider' => 'Local',
82+
'partial' => true // default partial value view
83+
],
84+
'TextareaFieldEmpty' => [
85+
'provider' => 'AmazonKMS',
86+
'partial' => false // no partial value view
87+
]
88+
89+
];
90+
91+
// etc
92+
}
93+
94+
```
95+
96+
## Providers
97+
98+
There are two providers currently supported
99+
100+
### Local
101+
102+
The values are stored in the local database in plain text but are not displayed in the relevant fields.
103+
104+
> :warning: This provider *only* helps to avoid users with certain CMS/Admin seeing secret values.
105+
106+
### AmazonKMS
107+
The values are stored encrypted in the local database and are not shown in the relevant fields. Encryption and decryption is handled via the AWS client.
108+
109+
You can use the decrypted values in your application, for instance submitting a consumer secret to an API.
110+
111+
#### Configuration
112+
113+
AmazonKMS requires an AWS Key, Secret Key, Key ID and AWS Region value to be available, add them to your site's configuration YML like so:
114+
115+
```yaml
116+
Codem\OneTime\Provider\AmazonKMS:
117+
access_key: 'access_key'
118+
secret: 'secret'
119+
aws_region: 'an-aws-region'
120+
key_id: 'a-kms-keyid'
121+
```
122+
123+
**OR**
124+
125+
You may also not provide the access_key & secret and instead rely on other authentication methods provided by AWS (e.g ~/.aws/credentials)
126+
127+
The IAM user with the relevant access_key and secret must have encrypt/decrypt privileges set up. You should not use your AWS root/admin user for this.
128+
129+
#### Encryption Context
130+
131+
Encryption Context is optional and assists with logging of encrypt/decrypt requests.
132+
133+
If you want to use this option, add it to the above configuration like so or in your environment:
134+
135+
```yaml
136+
Codem\OneTime\Provider\AmazonKMS:
137+
access_key: 'access_key'
138+
secret: 'secret'
139+
aws_region: 'an-aws-region'
140+
key_id: 'a-kms-keyid'
141+
encryption_context:
142+
AContextKey: 'some_context_value'
143+
```
144+
145+
Read [Encryption Context documentation](https://docs.aws.amazon.com/kms/latest/developerguide/encryption-context.html) at AWS for more information.
146+
147+
## Decrypting
148+
When you wish to get the field value back, simply call `decrypt()` on your DataObject. The argument is the field name.
149+
150+
```php
151+
$instance = MyDataObject::get()->byId(1);
152+
$plaintext = $instance->decrypt('SomeFieldNameWithEncryptedValue');
153+
```
154+
You can then use that value in your application, e.g by passing it to an API.
155+
156+
### Good-to-know
157+
158+
### Visibility of secrets on entry
159+
160+
+ Values you enter will be visible when entered into the field
161+
+ If your admin/website is not hosted over an HTTPS connection (!) data will be visible in transit
162+
163+
### Field value truncation
164+
165+
Encrypted values will be longer than the plain text version entered into the field.
166+
167+
If your field is set as a Varchar field, you may experience truncation of the encrypted value when the database insert occurs. Rather than this module automatically changing your field types, it's highly recommended that you specify "Text" as the field type for the relevant fields.
168+
169+
You can then use a ```TextField``` instead of a ```TextareaField``` in your DataObject's getCmsFields, if required.
170+
171+
## LICENSE
172+
173+
BSD-3-Clause
174+
175+
## Maintainers
176+
177+
Codem

code-of-conduct.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
When having discussions about this module in issues or pull request please adhere to the [SilverStripe Community Code of Conduct](https://docs.silverstripe.org/en/contributing/code_of_conduct).

docs/en/099_deprecated_schema.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Deprecated schema
2+
3+
This older schema is deprecated and will be removed in future versions
4+
5+
Use the current schema to have finer per-field controls.
6+
7+
```php
8+
<?php
9+
10+
namespace MyOrg;
11+
12+
use SilverStripe\ORM\DataObject;
13+
14+
class MyDataObject extends DataObject {
15+
16+
private static $secret_fields = [
17+
'SomeSecret', // a field called 'SomeSecret'
18+
'AnAPIPassword'// nother field called 'AnAPIPassword'
19+
];
20+
21+
22+
private static $secrets_provider = "AmazonKMS";// this record uses the AmazonKMS provider
23+
24+
// etc
25+
}
26+
```

phpstan.neon.dist

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
parameters:
2+
autoload_directories:
3+
- src
4+
- tests
5+
includes:
6+
- vendor/symbiote/silverstripe-phpstan/phpstan.neon

phpunit.xml.dist

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<phpunit
2+
bootstrap="vendor/silverstripe/framework/tests/bootstrap.php"
3+
colors="true"
4+
backupGlobals="false"
5+
backupStaticAttributes="false"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnError="false"
11+
stopOnFailure="false"
12+
stopOnIncomplete="false"
13+
stopOnSkipped="false"
14+
syntaxCheck="false"
15+
verbose="true"
16+
strict="false">
17+
18+
<testsuite name="codem/silverstripe-onetime">
19+
<directory>tests/</directory>
20+
</testsuite>
21+
22+
<groups>
23+
<exclude>
24+
<group>sanitychecks</group>
25+
</exclude>
26+
</groups>
27+
28+
<filter>
29+
<whitelist addUncoveredFilesFromWhitelist="true">
30+
<directory suffix=".php">src/</directory>
31+
<exclude>
32+
<directory suffix=".php">tests/</directory>
33+
</exclude>
34+
</whitelist>
35+
</filter>
36+
37+
<php>
38+
<!-- use envvarset in your YML files -->
39+
<env name="SS_TEST" value="1"/>
40+
<var name="runningtests" value="true"/>
41+
<!-- sqlite3 for testing module -->
42+
<env name="SS_DATABASE_CLASS" value="SQLite3Database"/>
43+
<env name="SS_DATABASE_NAME" value="SS_ontime_testdb"/>
44+
<env name="SS_DATABASE_SERVER" value="none"/>
45+
<env name="SS_DATABASE_USERNAME" value="none"/>
46+
<env name="SS_DATABASE_PASSWORD" value="none"/>
47+
<env name="SS_SQLITE_DATABASE_PATH" value=":memory:"/>
48+
</php>
49+
50+
</phpunit>

0 commit comments

Comments
 (0)