mirror of
https://github.com/mitchell/selfpass.git
synced 2025-12-14 21:27:22 +00:00
Add 'client/' from commit '92f38b5810'
git-subtree-dir: client git-subtree-mainline:024017338egit-subtree-split:92f38b5810
This commit is contained in:
commit
66ec035ee0
90 changed files with 3817 additions and 0 deletions
83
client/lib/repositories/grpc_credentials_client.dart
Normal file
83
client/lib/repositories/grpc_credentials_client.dart
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:grpc/grpc.dart';
|
||||
|
||||
import '../protobuf/service.pbgrpc.dart' as grpc;
|
||||
import '../protobuf/service.pb.dart' as protobuf;
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
import '../types/connection_config.dart';
|
||||
import '../types/credential.dart';
|
||||
|
||||
class GRPCCredentialsClient implements CredentialsRepo {
|
||||
static GRPCCredentialsClient _cached;
|
||||
grpc.CredentialServiceClient _client;
|
||||
|
||||
GRPCCredentialsClient(ConnectionConfig config) {
|
||||
final caCert = utf8.encode(config.caCertificate);
|
||||
final cert = utf8.encode(config.certificate);
|
||||
final privateCert = utf8.encode(config.privateCertificate);
|
||||
|
||||
final splitHost = config.host.split(':');
|
||||
final hostname = splitHost[0];
|
||||
final port = int.parse(splitHost[1]);
|
||||
|
||||
_client = grpc.CredentialServiceClient(ClientChannel(
|
||||
hostname,
|
||||
port: port,
|
||||
options: ChannelOptions(
|
||||
credentials: _ChannelCredentials(caCert, cert, privateCert),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
factory GRPCCredentialsClient.cached({ConnectionConfig config}) =>
|
||||
config == null ? _cached : _cached = GRPCCredentialsClient(config);
|
||||
|
||||
Stream<Metadata> getAllMetadata(String sourceHost) {
|
||||
final request = grpc.GetAllMetadataRequest();
|
||||
request.sourceHost = sourceHost;
|
||||
|
||||
return _client.getAllMetadata(request).map<Metadata>(
|
||||
(protobuf.Metadata pbMetadata) => Metadata.fromProtobuf(pbMetadata));
|
||||
}
|
||||
|
||||
Future<Credential> get(String id) async {
|
||||
final request = grpc.IdRequest();
|
||||
request.id = id;
|
||||
|
||||
return Credential.fromProtobuf(await _client.get(request));
|
||||
}
|
||||
|
||||
Future<Credential> create(CredentialInput input) async {
|
||||
return Credential();
|
||||
}
|
||||
|
||||
Future<Credential> update(String id, CredentialInput input) async {
|
||||
return Credential();
|
||||
}
|
||||
|
||||
Future<void> delete(String id) {
|
||||
final request = grpc.IdRequest();
|
||||
request.id = id;
|
||||
|
||||
return _client.delete(request);
|
||||
}
|
||||
}
|
||||
|
||||
class _ChannelCredentials extends ChannelCredentials {
|
||||
final List<int> _key;
|
||||
final List<int> _cert;
|
||||
|
||||
const _ChannelCredentials(List<int> caCert, this._cert, this._key)
|
||||
: super.secure(certificates: caCert);
|
||||
|
||||
@override
|
||||
SecurityContext get securityContext {
|
||||
return super.securityContext
|
||||
..usePrivateKeyBytes(_key)
|
||||
..useCertificateChainBytes(_cert);
|
||||
}
|
||||
}
|
||||
91
client/lib/repositories/secure_storage_config.dart
Normal file
91
client/lib/repositories/secure_storage_config.dart
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
import '../types/abstracts.dart';
|
||||
import '../types/connection_config.dart';
|
||||
|
||||
import '../utils/crypto.dart' as crypto;
|
||||
|
||||
class SecureStorageConfig implements ConfigRepo {
|
||||
static const _keyPrivateKey = "private_key";
|
||||
static const _keyConnectionConfig = "connection_config";
|
||||
static const _keyPassword = "password";
|
||||
|
||||
final _storage = FlutterSecureStorage();
|
||||
|
||||
bool _passwordMatched = false;
|
||||
String _password;
|
||||
|
||||
String get password {
|
||||
_checkIfPasswordMatched();
|
||||
return _password;
|
||||
}
|
||||
|
||||
Future<void> setPrivateKey(String key) {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.write(key: _keyPrivateKey, value: key.replaceAll('-', ''));
|
||||
}
|
||||
|
||||
Future<String> get privateKey {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.read(key: _keyPrivateKey);
|
||||
}
|
||||
|
||||
Future<void> setPassword(String password) {
|
||||
_checkIfPasswordMatched();
|
||||
|
||||
_password = password;
|
||||
|
||||
return _storage.write(
|
||||
key: _keyPassword, value: crypto.hashPassword(password));
|
||||
}
|
||||
|
||||
Future<bool> get passwordIsSet async {
|
||||
final passHash = await _storage.read(key: _keyPassword);
|
||||
|
||||
if (passHash != null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
_passwordMatched = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Future<bool> matchesPasswordHash(String password) async {
|
||||
_passwordMatched = crypto.matchHashedPassword(
|
||||
await _storage.read(key: _keyPassword), password);
|
||||
|
||||
if (_passwordMatched) _password = password;
|
||||
|
||||
return _passwordMatched;
|
||||
}
|
||||
|
||||
Future<void> setConnectionConfig(ConnectionConfig config) {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.write(
|
||||
key: _keyConnectionConfig, value: json.encode(config));
|
||||
}
|
||||
|
||||
Future<ConnectionConfig> get connectionConfig async {
|
||||
_checkIfPasswordMatched();
|
||||
final connConfig = await _storage.read(key: _keyConnectionConfig);
|
||||
|
||||
if (connConfig == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ConnectionConfig.fromJson(json.decode(connConfig));
|
||||
}
|
||||
|
||||
Future<void> deleteAll() {
|
||||
_checkIfPasswordMatched();
|
||||
return _storage.deleteAll();
|
||||
}
|
||||
|
||||
void _checkIfPasswordMatched() {
|
||||
if (_passwordMatched) return;
|
||||
throw Exception('password not matched yet');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue