Skip to content

Commit

Permalink
Add more complete examples, remove logging of credentials, document h…
Browse files Browse the repository at this point in the history
…ow to publish new plugin versions.
  • Loading branch information
Levi Sky committed Mar 8, 2021
1 parent f38c4ec commit cc6e099
Show file tree
Hide file tree
Showing 8 changed files with 188 additions and 74 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ Add write file and baseline identity features login and register
## 0.0.3

Upgrade json_serializable to core dependency

## 0.0.4

* Add documentation and complete example for use case of creating a TozId Identity for writing file data to TozStore
* Remove logging of sensitive credentials
* Add documentation for how to publish new versions
11 changes: 11 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ the generated files are created by running `flutter pub run build_runner build`.

When developing native portions of the plugin a full re-compile is needed, hot
restarts don't reflect current state.

## Publishing

* Checkout code from branch
* Write code, test code
* Update plugin version in `pubspec.yaml` file, `CHANGELOG.md` and `README.md` as needed
* Before committing changes for review, run `flutter pub publish --dry-run`
* Commit & PR changes
* Once PR is approved, merge into trunk
* Check out trunk, push a git tag matching the version tag in `pubspec.yaml`
* Run `flutter pub publish`
102 changes: 101 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,105 @@
# plugin_tozny

A flutter plugin for Tozny's products.
A work in progress flutter plugin for using [Tozny's](https://www.tozny.com) products such as TozStore and TozId to encrypt and secure data,
applications, and identities.

## Using

Use in your Dart or Flutter project by adding `plugin_tozny` as a dependency in your pubspec file:

```yaml
plugin_tozny:
git:
url: git://github.com/tozny/flutter-plugin
ref: 0.0.5
```

### End-to-end TozId Identity Registration, Login, & TozStore encrypted filed storage example

```dart
import 'package:plugin_tozny/plugin_tozny.dart';
import 'package:plugin_tozny/plugin_identity.dart';
import 'package:plugin_tozny/plugin_realm.dart';
import 'package:plugin_tozny/tozny_model.dart';
void registerLoginStoreFileExample() async {
RealmConfig realmConfig = new RealmConfig.fromJson({
"realm_name": "example",
"app_name": "account", // Only supported value at the moment
"broker_target_url": "https://id.tozny.com/example/recover", // Default value in the form of https://<TozIdBaseURL>/<YourRealmName>/recover will use a Tozny Hosted broker compute function for password recovery flows
"api_url": "https://api.e3db.com" // Default value for SaaS customers
});
var realmClient = PluginRealm(realmConfig);
try {
var username = 'example';
var email = 'example@example.com'; // Note that username and password can be the same if the username is a valid email
var password = 'StrongpassW0rd1!';
var realmIdentity = await realmClient.register(
username,
password,
'10a0cd84416e0950e345EXAMPLE813ec34a32ce1e9f76e3c192c932d2add',
email,
'FirstName',
'LastName',
60);
print("Registered Realm Identity ${realmIdentity.toJson().toString()}");
try {
var loggedInIdentity = await realmClient.login(username, password);
print(
"Logged into Realm as Identity ${loggedInIdentity.config.toJson().toString()}");
try {
var absoluteFilePath = writeExampleFile();
var recordType = "android-gyroscope-sensor-data";
var searchableRecordMetadata = {
"sensor-category": "movement",
"collection-timestamp": "1615146901",
"anonymous-participant-id": "u-u-i-d",
};
var storedRecordDetails = await loggedInIdentity.client.writeFile(
recordType, absoluteFilePath, searchableRecordMetadata);
print("Wrote file Record ${storedRecordDetails.toJson().toString()}");
} catch (e, s) {
print(e);
print(s);
}
} catch (e, s) {
print(e);
print(s);
}
} catch (e, s) {
print(e);
print(s);
}
}
Future<String> writeExampleFile() async {
final directory = await getApplicationDocumentsDirectory();
var filename = "example.txt";
final path = '${directory.path}/$filename';
var file = new File(path);
var sink = file.openWrite();
sink.write('example');
await sink.close();
return file.absolute.path;
}
```

Running the example above after replacing the example values (realm name, registration token, username and email)
will output text similar to the below to the emulator or device console:

```text
I/flutter ( 6719): Registered Realm Identity {client_credentials: {api_key_id: fbd4b8EXAMPLE8b180a88435eec7c4e7e60e6873e820a9d, api_secret: b43de1815737df6c4EXAMPLE83ccf45991a0118c415ba3d0cd86735f, client_id: fa7da2d4-1486-41ab-8d68-accf01c27a3e, client_email: , public_key: xCNRuxVh-83qYV7WQ1EXAMPLLUygwN_-GbijgQ, private_key: yi_UZqiQ1BpYxF2X3i0kGjUmP3AmvkEXAMPL, public_signing_key: QI8-D-dl5y3bgl2CFUFIykfPJ0KaXdz505YPGpYRYeg, private_signing_key: kradKCZbLCVu0m61-rZILQtgEjqhVBRsW3MhilYLnG1Ajz4P52XnLduCXYIVQUjKR88nQppdEXAMPL, api_url: https://api.e3db.com}, identity_config: {api_url: , appName: null, broker_target_url: https://id.tozny.com/flutter/recover, realm_name: flutter, user_id: 1786, username: example2}}
I/flutter ( 6719): Logged into Realm as Identity {client_credentials: {api_key_id: fbd4b81604971a8fa5977958c646EXAMPL7c4e7e60e6873e820a9d, api_secret: b43de1815737df6EXAMPELcf45991a0118c415ba3d0cd86735f, client_id: fa7da2d4-1486-41ab-8d68-accf01c27a3e, client_email: , public_key: xCNRuxVh-83EXAMPLCkLoLUygwN_-GbijgQ, private_key: yi_UZqiQ1BpYxF2X3i0kGjUmP3AmEXAMPL, public_signing_key: QI8-D-dl5y3bgl2CFUFIykfPJ0KaXdz505YPGpYRYeg, private_signing_key: kradKCZbLCVu0m61-rZILQtgEjqhVBRsW3MhilYLnG1Ajz4P52XnLduCXYIVQUjKR88nEXAMPL, api_url: https://api.e3db.com}, identity_config: {api_url: , appName: null, broker_target_url: https://id.tozny.com/flutter/recover, realm_name: flutter, user_id: 1786, username: example2}, user_agent_token: {access_token: eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJnTWlGYWVxMFZVRjFzN1NXTW90UzJEWU9nT0s1UC1zQ2N2UkZhcVV1N2EwIn0.eyJleHAiOjE2MTUxNjQ1NzIsImlhdCI6MTYxNTE2MDk3MiwiYXV0aF90aW1lIjoxNjE1MTYwOTcyLCJqdGkiOiI0NDI3MWRiMC00ZmFmLTQ0NzQtEXAMPL
I/flutter ( 6719): Wrote file Record {record_id: 0901582a-1ae2-4e42-8435-f74212ea86f8, writer_id: fa7da2d4-1486-41ab-8d68-accf01c27a3e, user_id: fa7da2d4-1486-41ab-8d68-accf01c27a3e, created: 2021-03-08T07:49:33.000Z, last_modified: 2021-03-08T07:49:33.000Z, version: 91af53ee-0575-4a73-bbc2-ee0803038f25, type: android-gyroscope-sensor-data, plain: {sensor-category: movement, anonymous-participant-id: u-u-i-d, collection-timestamp: 1615146901}, file: {file_url: null, file_name: 91b18cc7-cb08-4372-ac94-baab6cae31b4-1615160973, checksum: vwItq0yNXV2q/QzrhLd6Fw==, compression: RAW, size: null}}
```

## Current Limitations

* Plugin only works for Flutter apps running on Android.
* Plugin implements a partial set of all the methods and classes provided by the native SDK ([e3db-java](https://github.com/tozny/e3db-java)).
* Plugin only works with TozId Realms where the realm name is all lowercase.
* Plugin only works with TozId Identities creating using this plugin / is incompatible with those created via the TozId UI.
56 changes: 27 additions & 29 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:developer' as developer;
import 'dart:io';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:plugin_tozny/plugin_tozny.dart';
import 'package:plugin_tozny/plugin_identity.dart';
import 'package:plugin_tozny/plugin_realm.dart';
import 'package:plugin_tozny/tozny_model.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'dart:isolate';
import 'dart:developer' as developer;
import 'package:plugin_tozny/plugin_realm.dart';
import 'package:plugin_tozny/plugin_tozny.dart';
import 'package:plugin_tozny/tozny_model.dart';

void main() {
runApp(MyApp());
Expand Down Expand Up @@ -38,7 +37,7 @@ class _MyAppState extends State<MyApp> {
platformVersion = await PluginTozny.platformVersion;
} on PlatformException {
platformVersion = 'Failed to get platform version.';
} catch(e) {
} catch (e) {
platformVersion = e.toString();
}

Expand All @@ -62,9 +61,10 @@ class _MyAppState extends State<MyApp> {
await Permission.storage.request();
}
Record writtenRecord = await writeRecord(client);
Record tozstoreRecord = await readRecord(writtenRecord.metaData.recordID, client);
Record tozstoreRecord =
await readRecord(writtenRecord.metaData.recordID, client);
developer.log(tozstoreRecord.toJson().toString());
} catch(e) {
} catch (e) {
developer.log("example flow failed because $e");
}
}
Expand All @@ -75,8 +75,8 @@ class _MyAppState extends State<MyApp> {
var username = random.nextInt(10000).toString();
try {
print("before register");
await realmClient.register(username, "pass", regToken,
"test@example.com", "test", "user", 60);
await realmClient.register(
username, "pass", regToken, "test@example.com", "test", "user", 60);
print("logging in");
var loggedInIdentity = await realmClient.login(username, "pass");
print("writing record with identity");
Expand All @@ -96,28 +96,29 @@ class _MyAppState extends State<MyApp> {
var sink = file.openWrite();
sink.write('some encrypted content');
await sink.close();
var plain = {"plain":"file"};
var plain = {"plain": "file"};
developer.log(file.absolute.path);
var recordMeta = await client.writeFile("testFileType1", file.absolute.path, plain);
var recordMeta =
await client.writeFile("testFileType1", file.absolute.path, plain);
setState(() {
_platformVersion = "written file record: " + recordMeta.recordID;
});
return recordMeta;
} catch(e) {
} catch (e) {
developer.log("sdkfjlaskjdf" + e.toString());
}
}

Future<Record> writeRecord(PluginTozny client) async {
try {
var data = {"test": "example", "another": "encrypted"};
var plain = {"plain":"hello", "search":"world"};
var plain = {"plain": "hello", "search": "world"};
var record = await client.writeRecord("testType1", data, plain);
setState(() {
_platformVersion = "written record: " + record.metaData.recordID;
});
return record;
} catch(e) {
} catch (e) {
developer.log(e.toString());
}
}
Expand All @@ -129,7 +130,7 @@ class _MyAppState extends State<MyApp> {
_platformVersion = "read record";
});
return record;
} catch(e) {
} catch (e) {
developer.log("found error");
developer.log(e.toString());
}
Expand All @@ -143,25 +144,22 @@ class _MyAppState extends State<MyApp> {
return client;
}


@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Plugin example app'),
),
body: Stack(
children: <Widget>[
Center(
child: RaisedButton(
child: Text('Tozny Test'),
onPressed: onButtonPress,
),
body: Stack(children: <Widget>[
Center(
child: RaisedButton(
child: Text('Tozny Test'),
onPressed: onButtonPress,
),
Text('Running on: $_platformVersion\n'),
]
),
),
Text('Running on: $_platformVersion\n'),
]),
),
);
}
Expand Down
Loading

0 comments on commit cc6e099

Please sign in to comment.