Skip to content
This repository was archived by the owner on Jul 25, 2022. It is now read-only.

Commit 5a888f9

Browse files
authored
Merge pull request #2 from LukasPoque/add_policy_feature
Add policy feature
2 parents 36bfd22 + 8686ede commit 5a888f9

15 files changed

+713
-16
lines changed

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 0.2.0
2+
3+
Add Policy classes.
4+
- add policies: `PolicyEntry` as class for all policies in the directory or repository, using `PolicyGroup`, `PolicyResource`, `PolicySubject` for
5+
a better data encapsulation
6+
- add `InvalidArgumentException` for arguments which are not matching the expectations
7+
18
## 0.1.0
29

310
First release of the S3I Flutter package. Currently supported:

README.md

+54-12
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@
2727
</p>
2828

2929

30+
## About S³I and KWH4.0
31+
32+
If you are not familiar with the S³I concepts, please read the
33+
[KWH4.0-Standpunkt](https://www.kwh40.de/wp-content/uploads/2020/04/KWH40-Standpunkt-S3I-v2.0.pdf).
34+
35+
For further information see the [KWH Glossar](https://www.kwh40.de/glossar/) and the other [Standpunkte](https://www.kwh40.de/veroffentlichungen/).
36+
3037
## Installing
3138

3239
Add it to your `pubspec.yaml` file:
@@ -42,20 +49,13 @@ flutter packages get
4249
If you like this package, consider supporting it by giving a star on [GitHub](https://github.com/LukasPoque/s3i_flutter) and
4350
a like on [pub.dev](https://pub.dev/packages/s3i_flutter) :heart:
4451

45-
## About S³I and KWH4.0
46-
47-
If you are not familiar with the S³I concepts, please consider reading the
48-
[KWH4.0-Standpunkt](https://www.kwh40.de/wp-content/uploads/2020/04/KWH40-Standpunkt-S3I-v2.0.pdf).
49-
50-
For further information see the [KWH Glossar](https://www.kwh40.de/glossar/) and the other [Standpunkte](https://www.kwh40.de/veroffentlichungen/).
51-
5252
## Usage
5353

5454
For a basic example application see the [example](https://github.com/LukasPoque/s3i_flutter/tree/master/example).
5555

56-
### Setup Auth
56+
### Setup authentication
5757

58-
Create a `ClientIdentity` used by your app. Please contact the [KWH4.0](https://www.kwh40.de/kontakt/) to get an app specific client.
58+
First you need to create a `ClientIdentity` used by your app. Please contact the [KWH4.0](https://www.kwh40.de/kontakt/) to get an app specific client.
5959
```dart
6060
final clientIdentity = ClientIdentity(<CLIENT-ID>, <CLIENT-SECRET>);
6161
```
@@ -70,7 +70,7 @@ final authManager = OAuthProxyFlow(clientIdentity,
7070
scopes: ["group", "offline_access"]);
7171
```
7272

73-
Last but not least you should use this `AuthenticationManager`-Instance to create a `S3ICore`-Instance. Now you could work with the `S3I`.
73+
Last but not least you should use this `AuthenticationManager`-Instance to create a `S3ICore`-Instance.
7474
```dart
7575
final s3i = S3ICore(authManager);
7676
```
@@ -85,9 +85,11 @@ try {
8585
}
8686
````
8787

88-
### Send Requests to the directory
88+
If the `S3ICore`-Instance is ready to use you can now receive and update information from the S3I-Services.
8989

90-
If the `S3ICore`-Instance is ready to use you can receive information about a specific thing by calling `getThing()`.
90+
### Get data from the directory
91+
92+
To get data about a specific thing you can simply call `getThing()` on your `S3ICore`-Instance.
9193
If you don't need the whole thing it's recommended to use a `FieldQuery` so you only receive a part of the entry
9294
which is faster and safes network data.
9395
```dart
@@ -98,6 +100,36 @@ try {
98100
}
99101
```
100102

103+
Similar to this you can request a specific policy from the directory:
104+
```dart
105+
try {
106+
var policy = await s3i.getPolicy(<POLICY_ID>));
107+
} on S3IException catch (e) {
108+
debugPrint("Request Policy failed: " + e.toString());
109+
}
110+
```
111+
112+
TODO: add search example
113+
114+
### Update data in the directory
115+
116+
To update data in the directory it's recommended to request the target before changing it.
117+
This is not needed, because all data classes cloud be created without a version from the cloud but since this package doesn't support `PATCH` requests
118+
using only local data could lead to unintentionally overwriting much more likely.
119+
120+
To update an entry in the directory simply use the `putThing()` or `putPolicy()` method with the locally modified object:
121+
```dart
122+
policyEntry.insertObserver(PolicySubject("nginx:test_observer"));
123+
try {
124+
await s3i.putPolicy(policyEntry);
125+
} on S3IException catch (e) {
126+
debugPrint("Update Policy failed: " + e.toString());
127+
}
128+
```
129+
130+
### Send and receive messages via S3I-Broker
131+
132+
TODO: ...
101133

102134
## Project Structure
103135

@@ -116,6 +148,16 @@ But it doesn't refreshes the tokens automatically, only only if `getAccessToken`
116148

117149
### policy
118150

151+
The `policy` folder includes data classes to store and manipulate the policy entries of a thing from the directory OR repository.
152+
153+
A `PolicyEntry` consists of `PolicyGroup`s and manages the access control to one specific `Entry`.
154+
Each one has it's own policy entry which is only valid for the the service where it's stored (directory/repository).
155+
For more background information see: https://www.eclipse.org/ditto/basic-policy.html
156+
157+
In the S3I-Concept there are two special `PolicyGroup`s which have a specific meaning:
158+
- owner: An owner has READ and WRITE permission to everything (thing:/, policy:/, message:/)
159+
- observer: An observer has only READ permission to the thing part (thing:/)
160+
119161
### broker
120162

121163
### exceptions

example/lib/main.dart

+50-2
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,12 @@ class MyHomePage extends StatefulWidget {
5151

5252
class _MyHomePageState extends State<MyHomePage> {
5353
final thingIdInputController = TextEditingController();
54+
final policyIdInputController = TextEditingController();
5455

5556
// s3i values
5657
AccessToken? accessToken;
5758
Thing? requestedThing;
59+
PolicyEntry? requestedPolicy;
5860

5961
@override
6062
Widget build(BuildContext context) {
@@ -70,7 +72,9 @@ class _MyHomePageState extends State<MyHomePage> {
7072
Divider(height: 5, thickness: 5),
7173
_buildThingRequestArea(),
7274
Divider(height: 5, thickness: 5),
73-
_buildEditThingArea()
75+
_buildEditThingArea(),
76+
Divider(height: 5, thickness: 5),
77+
_buildPolicyRequestArea()
7478
],
7579
),
7680
));
@@ -135,9 +139,12 @@ class _MyHomePageState extends State<MyHomePage> {
135139
} on S3IException catch (e) {
136140
debugPrint("Request Thing failed");
137141
debugPrint(e.toString());
142+
setState(() {
143+
requestedThing = null;
144+
});
138145
}
139146
},
140-
child: Text("Request"))
147+
child: Text("Request Thing"))
141148
],
142149
),
143150
SizedBox(height: 8),
@@ -172,6 +179,47 @@ class _MyHomePageState extends State<MyHomePage> {
172179
: Container();
173180
}
174181

182+
Widget _buildPolicyRequestArea() {
183+
return Padding(
184+
padding: const EdgeInsets.all(16.0),
185+
child: Column(
186+
children: [
187+
Row(
188+
children: [
189+
Expanded(
190+
child: TextField(
191+
controller: policyIdInputController,
192+
),
193+
),
194+
SizedBox(width: 8),
195+
OutlinedButton(
196+
onPressed: () async {
197+
try {
198+
// requests the given policy
199+
// you need read access to the policy
200+
var policy = await MyHomePage.s3i
201+
.getPolicy(policyIdInputController.text);
202+
setState(() {
203+
requestedPolicy = policy;
204+
});
205+
} on S3IException catch (e) {
206+
debugPrint("Request Policy failed");
207+
debugPrint(e.toString());
208+
setState(() {
209+
requestedPolicy = null;
210+
});
211+
}
212+
},
213+
child: Text("Request Policy"))
214+
],
215+
),
216+
SizedBox(height: 8),
217+
if (requestedPolicy != null) Text(requestedPolicy.toString())
218+
],
219+
),
220+
);
221+
}
222+
175223
@override
176224
void dispose() {
177225
thingIdInputController.dispose();

example/pubspec.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ packages:
134134
path: ".."
135135
relative: true
136136
source: path
137-
version: "0.0.1"
137+
version: "0.2.0"
138138
sky_engine:
139139
dependency: transitive
140140
description: flutter

lib/s3i_flutter.dart

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ export 'src/exceptions/parse_exception.dart';
1818
export 'src/exceptions/max_retry_exception.dart';
1919
export 'src/exceptions/network_response_exception.dart';
2020

21+
//policy
22+
export 'src/policy/policy_entry.dart';
23+
export 'src/policy/policy_group.dart';
24+
export 'src/policy/policy_resource.dart';
25+
export 'src/policy/policy_subject.dart';
26+
2127
//query
2228
export 'src/query/query_assembler.dart';
2329
export 'src/query/field_query.dart';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import 'package:s3i_flutter/src/exceptions/s3i_exception.dart';
2+
3+
/// Exception thrown when an argument is not matching the expectations.
4+
class InvalidArgumentException extends S3IException {
5+
InvalidArgumentException(String message) : super(message);
6+
7+
@override
8+
String toString() {
9+
return "InvalidArgumentException: $errorMessage";
10+
}
11+
}

0 commit comments

Comments
 (0)