Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add external api #54

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,4 @@ Future<Response> handleTransactionRequest(Request request) async {

return Response.ok('Transaction request received');
}

// TODO: write accesstoken test mode for testing app fexr
22 changes: 19 additions & 3 deletions lib/external_interaction/rubix/rubix_external_rpc.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'package:sky/external_interaction/ext_auth_stream.dart';
import 'package:sky/external_interaction/rubix/rubix_txn_request_stream.dart';
import 'package:sky/native_interaction/rubix/rubix_rpc.dart';
import 'package:sky/native_interaction/rubix/rubix_util.dart';
import 'package:sky/native_interaction/rubix/rubix_util.dart' as util;
import 'package:sky/protogen/google/protobuf/empty.pb.dart';
import 'package:grpc/grpc.dart';
import 'package:sky/protogen/native-interaction/rubix-external.pbgrpc.dart';
import 'package:sky/external_interaction/sky_outgoing_calls.dart';

class RubixExternalService extends RubixExternalServiceBase {
@override
Expand All @@ -15,8 +16,8 @@ class RubixExternalService extends RubixExternalServiceBase {
var peerId = user.getPeerId();
var uuid = request.uuid;

Token tokenObj =
ExternalAccessToken.get(did: did, peerId: peerId, uuid: uuid);
util.Token tokenObj =
util.ExternalAccessToken.get(did: did, peerId: peerId, uuid: uuid);

ExternalAuthStream().add(ExternalAuthState.createRubixToken(
request.uuid, tokenObj.token, tokenObj.expiry));
Expand All @@ -39,4 +40,19 @@ class RubixExternalService extends RubixExternalServiceBase {
..receiver = event.receiver;
});
}

@override
Future<OrgStatus> approveOrgAuthRequest(
ServiceCall call, OrgAuthRequest request) async {
var user = RubixService.getAuthUser(call);
const rubix = 'rubix';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must have been coming from phone,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, no, not need as this is rubix ext rpc. But could have simply passed this to the next function without having to store it in a variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok will make that change.

var did = user.getDid();
var peerId = user.getPeerId();
var orgName = request.orgName;
var callBackUrl = request.callBackUrl;
var sessionId = request.sessionId;
final orgAccessToken = util.OrgAccessToken.get(did: did, peerId: peerId, orgName: orgName);
var response = await fireAuthCallback(did: did, peerId: peerId, callBackUrl: callBackUrl, orgAccessToken: orgAccessToken,sessionId: sessionId,chain: rubix);
return Future.value(OrgStatus(status: response));
}
}
31 changes: 31 additions & 0 deletions lib/external_interaction/sky_outgoing_calls.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'dart:convert';
import 'package:sky/native_interaction/rubix/rubix_util.dart';
import 'package:http/http.dart' as http;


Future<bool> fireAuthCallback({required String did,required String peerId,required String callBackUrl,required Token orgAccessToken,required String sessionId,required String chain })async {
var bodyJsonStr = jsonEncode({
'did': '$did.$peerId',
'session_id': sessionId,
'token': orgAccessToken.token,
'chain': chain,
});
try{
var response = await http.post(
Uri.parse(callBackUrl),
headers: <String, String>{
'Content-Type': 'application/json; charset=UTF-8',
},
body: bodyJsonStr,
);
if (response.statusCode == 200) {
return true;
} else {
return false;
}
}catch(e, s){
print(e);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

print stack trace too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

print(s);
return false;
}
}
61 changes: 60 additions & 1 deletion lib/native_interaction/rubix/rubix_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ final String _secret = Config().jwtAuthSecret;
final String _issuer = 'Fexr Sky';
final String _portMapIndex = 'peer_id_index';

enum _RubixTokenType { challengeToken, accessToken, externalAccessToken }
enum _RubixTokenType { challengeToken, accessToken, externalAccessToken, orgAccessToken }

String _getClaimType(JwtClaim claim) {
return claim.toJson()['type'];
Expand Down Expand Up @@ -263,6 +263,65 @@ class ExternalAccessTokenJWTClaim extends JwtClaim {
}
}

class OrgAccessTokenJWTClaim extends JwtClaim {
OrgAccessTokenJWTClaim({
required String did,
required DateTime expiry,
required String peerId,
required String orgName,
}) : super(
issuer: _issuer,
subject: orgName,
maxAge: Duration(days: 30),
otherClaims: {
'type': _RubixTokenType.orgAccessToken.toString(),
'peerId': peerId,
'did': did,
},
);

factory OrgAccessTokenJWTClaim.fromJWTClaim(JwtClaim claim) {
return OrgAccessTokenJWTClaim(
orgName: claim.subject!,
expiry: claim.expiry!,
peerId: claim.toJson()['peerId'],
did: claim.toJson()['did'],
);
}

factory OrgAccessTokenJWTClaim.fromToken(String token) {
return OrgAccessTokenJWTClaim.fromJWTClaim(
verifyJwtHS256Signature(token, _secret));
}

String getOrgName() {
return subject!;
}

String getPeerId() {
return toJson()['peerId'];
}

String getDID() {
return toJson()['did'];
}
}

class OrgAccessToken {
static final int _accessTokenMaxAge = 30; // days
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

token age might be something we have to worry about but not during a poc. We need to come back on this.

static Token get(
{required String did, required String peerId, required String orgName}) {
final JwtClaim claimSet = OrgAccessTokenJWTClaim(
did: did,
expiry: DateTime.now().add(Duration(days: _accessTokenMaxAge)),
peerId: peerId,
orgName: orgName,
);

return Token(issueJwtHS256(claimSet, _secret), claimSet.expiry!);
}
}

class ExternalAccessToken {
static final int _accessTokenMaxAge = 30; // days
static Token get(
Expand Down
122 changes: 122 additions & 0 deletions lib/protogen/native-interaction/rubix-external.pb.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,128 @@ class AuthRequest extends $pb.GeneratedMessage {
void clearUuid() => clearField(1);
}

class OrgAuthRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OrgAuthRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'protos'), createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'orgName', protoName: 'orgName')
..aOS(2, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'callBackUrl', protoName: 'callBackUrl')
..aOS(3, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'sessionId', protoName: 'sessionId')
..hasRequiredFields = false
;

OrgAuthRequest._() : super();
factory OrgAuthRequest({
$core.String? orgName,
$core.String? callBackUrl,
$core.String? sessionId,
}) {
final _result = create();
if (orgName != null) {
_result.orgName = orgName;
}
if (callBackUrl != null) {
_result.callBackUrl = callBackUrl;
}
if (sessionId != null) {
_result.sessionId = sessionId;
}
return _result;
}
factory OrgAuthRequest.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory OrgAuthRequest.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
OrgAuthRequest clone() => OrgAuthRequest()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
OrgAuthRequest copyWith(void Function(OrgAuthRequest) updates) => super.copyWith((message) => updates(message as OrgAuthRequest)) as OrgAuthRequest; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static OrgAuthRequest create() => OrgAuthRequest._();
OrgAuthRequest createEmptyInstance() => create();
static $pb.PbList<OrgAuthRequest> createRepeated() => $pb.PbList<OrgAuthRequest>();
@$core.pragma('dart2js:noInline')
static OrgAuthRequest getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrgAuthRequest>(create);
static OrgAuthRequest? _defaultInstance;

@$pb.TagNumber(1)
$core.String get orgName => $_getSZ(0);
@$pb.TagNumber(1)
set orgName($core.String v) { $_setString(0, v); }
@$pb.TagNumber(1)
$core.bool hasOrgName() => $_has(0);
@$pb.TagNumber(1)
void clearOrgName() => clearField(1);

@$pb.TagNumber(2)
$core.String get callBackUrl => $_getSZ(1);
@$pb.TagNumber(2)
set callBackUrl($core.String v) { $_setString(1, v); }
@$pb.TagNumber(2)
$core.bool hasCallBackUrl() => $_has(1);
@$pb.TagNumber(2)
void clearCallBackUrl() => clearField(2);

@$pb.TagNumber(3)
$core.String get sessionId => $_getSZ(2);
@$pb.TagNumber(3)
set sessionId($core.String v) { $_setString(2, v); }
@$pb.TagNumber(3)
$core.bool hasSessionId() => $_has(2);
@$pb.TagNumber(3)
void clearSessionId() => clearField(3);
}

class OrgStatus extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'OrgStatus', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'protos'), createEmptyInstance: create)
..aOB(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'status')
..hasRequiredFields = false
;

OrgStatus._() : super();
factory OrgStatus({
$core.bool? status,
}) {
final _result = create();
if (status != null) {
_result.status = status;
}
return _result;
}
factory OrgStatus.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r);
factory OrgStatus.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
'Will be removed in next major version')
OrgStatus clone() => OrgStatus()..mergeFromMessage(this);
@$core.Deprecated(
'Using this can add significant overhead to your binary. '
'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
'Will be removed in next major version')
OrgStatus copyWith(void Function(OrgStatus) updates) => super.copyWith((message) => updates(message as OrgStatus)) as OrgStatus; // ignore: deprecated_member_use
$pb.BuilderInfo get info_ => _i;
@$core.pragma('dart2js:noInline')
static OrgStatus create() => OrgStatus._();
OrgStatus createEmptyInstance() => create();
static $pb.PbList<OrgStatus> createRepeated() => $pb.PbList<OrgStatus>();
@$core.pragma('dart2js:noInline')
static OrgStatus getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<OrgStatus>(create);
static OrgStatus? _defaultInstance;

@$pb.TagNumber(1)
$core.bool get status => $_getBF(0);
@$pb.TagNumber(1)
set status($core.bool v) { $_setBool(0, v); }
@$pb.TagNumber(1)
$core.bool hasStatus() => $_has(0);
@$pb.TagNumber(1)
void clearStatus() => clearField(1);
}

class TxnRequest extends $pb.GeneratedMessage {
static final $pb.BuilderInfo _i = $pb.BuilderInfo(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'TxnRequest', package: const $pb.PackageName(const $core.bool.fromEnvironment('protobuf.omit_message_names') ? '' : 'protos'), createEmptyInstance: create)
..aOS(1, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'receiver')
Expand Down
25 changes: 25 additions & 0 deletions lib/protogen/native-interaction/rubix-external.pbgrpc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ class RubixExternalClient extends $grpc.Client {
'/protos.RubixExternal/ApproveAuthRequest',
($0.AuthRequest value) => value.writeToBuffer(),
($core.List<$core.int> value) => $1.Empty.fromBuffer(value));
static final _$approveOrgAuthRequest =
$grpc.ClientMethod<$0.OrgAuthRequest, $0.OrgStatus>(
'/protos.RubixExternal/ApproveOrgAuthRequest',
($0.OrgAuthRequest value) => value.writeToBuffer(),
($core.List<$core.int> value) => $0.OrgStatus.fromBuffer(value));
static final _$streamTransactionRequest =
$grpc.ClientMethod<$1.Empty, $0.TxnRequest>(
'/protos.RubixExternal/StreamTransactionRequest',
Expand All @@ -36,6 +41,12 @@ class RubixExternalClient extends $grpc.Client {
return $createUnaryCall(_$approveAuthRequest, request, options: options);
}

$grpc.ResponseFuture<$0.OrgStatus> approveOrgAuthRequest(
$0.OrgAuthRequest request,
{$grpc.CallOptions? options}) {
return $createUnaryCall(_$approveOrgAuthRequest, request, options: options);
}

$grpc.ResponseStream<$0.TxnRequest> streamTransactionRequest($1.Empty request,
{$grpc.CallOptions? options}) {
return $createStreamingCall(
Expand All @@ -55,6 +66,13 @@ abstract class RubixExternalServiceBase extends $grpc.Service {
false,
($core.List<$core.int> value) => $0.AuthRequest.fromBuffer(value),
($1.Empty value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$0.OrgAuthRequest, $0.OrgStatus>(
'ApproveOrgAuthRequest',
approveOrgAuthRequest_Pre,
false,
false,
($core.List<$core.int> value) => $0.OrgAuthRequest.fromBuffer(value),
($0.OrgStatus value) => value.writeToBuffer()));
$addMethod($grpc.ServiceMethod<$1.Empty, $0.TxnRequest>(
'StreamTransactionRequest',
streamTransactionRequest_Pre,
Expand All @@ -69,13 +87,20 @@ abstract class RubixExternalServiceBase extends $grpc.Service {
return approveAuthRequest(call, await request);
}

$async.Future<$0.OrgStatus> approveOrgAuthRequest_Pre(
$grpc.ServiceCall call, $async.Future<$0.OrgAuthRequest> request) async {
return approveOrgAuthRequest(call, await request);
}

$async.Stream<$0.TxnRequest> streamTransactionRequest_Pre(
$grpc.ServiceCall call, $async.Future<$1.Empty> request) async* {
yield* streamTransactionRequest(call, await request);
}

$async.Future<$1.Empty> approveAuthRequest(
$grpc.ServiceCall call, $0.AuthRequest request);
$async.Future<$0.OrgStatus> approveOrgAuthRequest(
$grpc.ServiceCall call, $0.OrgAuthRequest request);
$async.Stream<$0.TxnRequest> streamTransactionRequest(
$grpc.ServiceCall call, $1.Empty request);
}
22 changes: 22 additions & 0 deletions lib/protogen/native-interaction/rubix-external.pbjson.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ const AuthRequest$json = const {

/// Descriptor for `AuthRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List authRequestDescriptor = $convert.base64Decode('CgtBdXRoUmVxdWVzdBISCgR1dWlkGAEgASgJUgR1dWlk');
@$core.Deprecated('Use orgAuthRequestDescriptor instead')
const OrgAuthRequest$json = const {
'1': 'OrgAuthRequest',
'2': const [
const {'1': 'orgName', '3': 1, '4': 1, '5': 9, '10': 'orgName'},
const {'1': 'callBackUrl', '3': 2, '4': 1, '5': 9, '10': 'callBackUrl'},
const {'1': 'sessionId', '3': 3, '4': 1, '5': 9, '10': 'sessionId'},
],
};

/// Descriptor for `OrgAuthRequest`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List orgAuthRequestDescriptor = $convert.base64Decode('Cg5PcmdBdXRoUmVxdWVzdBIYCgdvcmdOYW1lGAEgASgJUgdvcmdOYW1lEiAKC2NhbGxCYWNrVXJsGAIgASgJUgtjYWxsQmFja1VybBIcCglzZXNzaW9uSWQYAyABKAlSCXNlc3Npb25JZA==');
@$core.Deprecated('Use orgStatusDescriptor instead')
const OrgStatus$json = const {
'1': 'OrgStatus',
'2': const [
const {'1': 'status', '3': 1, '4': 1, '5': 8, '10': 'status'},
],
};

/// Descriptor for `OrgStatus`. Decode as a `google.protobuf.DescriptorProto`.
final $typed_data.Uint8List orgStatusDescriptor = $convert.base64Decode('CglPcmdTdGF0dXMSFgoGc3RhdHVzGAEgASgIUgZzdGF0dXM=');
@$core.Deprecated('Use txnRequestDescriptor instead')
const TxnRequest$json = const {
'1': 'TxnRequest',
Expand Down
2 changes: 1 addition & 1 deletion protos