diff --git a/app/src/types/generated/lit-sessions_pb.d.ts b/app/src/types/generated/lit-sessions_pb.d.ts index 5c91bafa..4212c66e 100644 --- a/app/src/types/generated/lit-sessions_pb.d.ts +++ b/app/src/types/generated/lit-sessions_pb.d.ts @@ -24,6 +24,9 @@ export class AddSessionRequest extends jspb.Message { setMacaroonCustomPermissionsList(value: Array): void; addMacaroonCustomPermissions(value?: MacaroonPermission, index?: number): MacaroonPermission; + getAccountId(): string; + setAccountId(value: string): void; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): AddSessionRequest.AsObject; static toObject(includeInstance: boolean, msg: AddSessionRequest): AddSessionRequest.AsObject; @@ -42,6 +45,7 @@ export namespace AddSessionRequest { mailboxServerAddr: string, devServer: boolean, macaroonCustomPermissionsList: Array, + accountId: string, } } @@ -136,6 +140,9 @@ export class Session extends jspb.Message { getMacaroonRecipe(): MacaroonRecipe | undefined; setMacaroonRecipe(value?: MacaroonRecipe): void; + getAccountId(): string; + setAccountId(value: string): void; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): Session.AsObject; static toObject(includeInstance: boolean, msg: Session): Session.AsObject; @@ -160,6 +167,7 @@ export namespace Session { remotePublicKey: Uint8Array | string, createdAt: string, macaroonRecipe?: MacaroonRecipe.AsObject, + accountId: string, } } @@ -272,6 +280,7 @@ export interface SessionTypeMap { TYPE_MACAROON_ADMIN: 1; TYPE_MACAROON_CUSTOM: 2; TYPE_UI_PASSWORD: 3; + TYPE_MACAROON_ACCOUNT: 4; } export const SessionType: SessionTypeMap; diff --git a/app/src/types/generated/lit-sessions_pb.js b/app/src/types/generated/lit-sessions_pb.js index 230c5214..dcd5c061 100644 --- a/app/src/types/generated/lit-sessions_pb.js +++ b/app/src/types/generated/lit-sessions_pb.js @@ -85,7 +85,8 @@ proto.litrpc.AddSessionRequest.toObject = function(includeInstance, msg) { mailboxServerAddr: jspb.Message.getFieldWithDefault(msg, 4, ""), devServer: jspb.Message.getFieldWithDefault(msg, 5, false), macaroonCustomPermissionsList: jspb.Message.toObjectList(msg.getMacaroonCustomPermissionsList(), - proto.litrpc.MacaroonPermission.toObject, includeInstance) + proto.litrpc.MacaroonPermission.toObject, includeInstance), + accountId: jspb.Message.getFieldWithDefault(msg, 7, "") }; if (includeInstance) { @@ -147,6 +148,10 @@ proto.litrpc.AddSessionRequest.deserializeBinaryFromReader = function(msg, reade reader.readMessage(value,proto.litrpc.MacaroonPermission.deserializeBinaryFromReader); msg.addMacaroonCustomPermissions(value); break; + case 7: + var value = /** @type {string} */ (reader.readString()); + msg.setAccountId(value); + break; default: reader.skipField(); break; @@ -219,6 +224,13 @@ proto.litrpc.AddSessionRequest.serializeBinaryToWriter = function(message, write proto.litrpc.MacaroonPermission.serializeBinaryToWriter ); } + f = message.getAccountId(); + if (f.length > 0) { + writer.writeString( + 7, + f + ); + } }; @@ -330,6 +342,21 @@ proto.litrpc.AddSessionRequest.prototype.clearMacaroonCustomPermissionsList = fu }; +/** + * optional string account_id = 7; + * @return {string} + */ +proto.litrpc.AddSessionRequest.prototype.getAccountId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +}; + + +/** @param {string} value */ +proto.litrpc.AddSessionRequest.prototype.setAccountId = function(value) { + jspb.Message.setProto3StringField(this, 7, value); +}; + + /** * Generated by JsPbCodeGenerator. @@ -716,7 +743,8 @@ proto.litrpc.Session.toObject = function(includeInstance, msg) { localPublicKey: msg.getLocalPublicKey_asB64(), remotePublicKey: msg.getRemotePublicKey_asB64(), createdAt: jspb.Message.getFieldWithDefault(msg, 11, "0"), - macaroonRecipe: (f = msg.getMacaroonRecipe()) && proto.litrpc.MacaroonRecipe.toObject(includeInstance, f) + macaroonRecipe: (f = msg.getMacaroonRecipe()) && proto.litrpc.MacaroonRecipe.toObject(includeInstance, f), + accountId: jspb.Message.getFieldWithDefault(msg, 13, "") }; if (includeInstance) { @@ -802,6 +830,10 @@ proto.litrpc.Session.deserializeBinaryFromReader = function(msg, reader) { reader.readMessage(value,proto.litrpc.MacaroonRecipe.deserializeBinaryFromReader); msg.setMacaroonRecipe(value); break; + case 13: + var value = /** @type {string} */ (reader.readString()); + msg.setAccountId(value); + break; default: reader.skipField(); break; @@ -916,6 +948,13 @@ proto.litrpc.Session.serializeBinaryToWriter = function(message, writer) { proto.litrpc.MacaroonRecipe.serializeBinaryToWriter ); } + f = message.getAccountId(); + if (f.length > 0) { + writer.writeString( + 13, + f + ); + } }; @@ -1188,6 +1227,21 @@ proto.litrpc.Session.prototype.hasMacaroonRecipe = function() { }; +/** + * optional string account_id = 13; + * @return {string} + */ +proto.litrpc.Session.prototype.getAccountId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 13, "")); +}; + + +/** @param {string} value */ +proto.litrpc.Session.prototype.setAccountId = function(value) { + jspb.Message.setProto3StringField(this, 13, value); +}; + + /** * Generated by JsPbCodeGenerator. @@ -1970,7 +2024,8 @@ proto.litrpc.SessionType = { TYPE_MACAROON_READONLY: 0, TYPE_MACAROON_ADMIN: 1, TYPE_MACAROON_CUSTOM: 2, - TYPE_UI_PASSWORD: 3 + TYPE_UI_PASSWORD: 3, + TYPE_MACAROON_ACCOUNT: 4 }; /** diff --git a/app/src/util/tests/sampleData.ts b/app/src/util/tests/sampleData.ts index 98137ea4..8555ecad 100644 --- a/app/src/util/tests/sampleData.ts +++ b/app/src/util/tests/sampleData.ts @@ -874,6 +874,7 @@ export const litListSessions: LIT.ListSessionsResponse.AsObject = { sessionState: LIT.SessionState.STATE_CREATED, sessionType: LIT.SessionType.TYPE_UI_PASSWORD, createdAt: '253300000000', + accountId: '', }, { devServer: true, @@ -887,6 +888,7 @@ export const litListSessions: LIT.ListSessionsResponse.AsObject = { sessionState: LIT.SessionState.STATE_EXPIRED, sessionType: LIT.SessionType.TYPE_UI_PASSWORD, createdAt: '253300000000', + accountId: '', }, ], }; diff --git a/itest/litd_accounts_test.go b/itest/litd_accounts_test.go index 0b529473..e0455c5d 100644 --- a/itest/litd_accounts_test.go +++ b/itest/litd_accounts_test.go @@ -3,7 +3,9 @@ package itest import ( "context" "io/ioutil" + "strings" "testing" + "time" "github.com/btcsuite/btcd/btcutil" "github.com/lightninglabs/lightning-terminal/litrpc" @@ -138,7 +140,15 @@ func runAccountSystemTest(t *harnessTest, node *HarnessNode, hostPort, // Run the actual account restriction tests against the connection with // the account macaroon. - testAccountRestrictions(ctxa, t, net, rawConn, charlie, acctBalance) + newAcctBalance := testAccountRestrictions( + ctxa, t, rawConn, charlie, acctBalance, + ) + + // Test the same account restrictions with an LNC session that is bound + // to the account. + testAccountRestrictionsLNC( + ctxm, t, rawConn, newAcctBalance, acctResp.Account.Id, + ) // Clean up our channel and payments, so we can start the next test // iteration with a clean slate. @@ -151,11 +161,68 @@ func runAccountSystemTest(t *harnessTest, node *HarnessNode, hostPort, require.NoError(t.t, err) } +// testAccountRestrictionsLNC tests that an account restricted session can also +// be created through LNC. +func testAccountRestrictionsLNC(ctxm context.Context, t *harnessTest, + rawConn grpc.ClientConnInterface, currentAccountBalance uint64, + accountID string) { + + // We first need to create an LNC session that we can use to connect. + // We use the UI password to create the session. + litClient := litrpc.NewSessionsClient(rawConn) + sessResp, err := litClient.AddSession(ctxm, &litrpc.AddSessionRequest{ + Label: "integration-test", + SessionType: litrpc.SessionType_TYPE_MACAROON_ACCOUNT, + ExpiryTimestampSeconds: uint64( + time.Now().Add(5 * time.Minute).Unix(), + ), + MailboxServerAddr: mailboxServerAddr, + AccountId: accountID, + }) + require.NoError(t.t, err) + + // Try the LNC connection now. + connectPhrase := strings.Split( + sessResp.Session.PairingSecretMnemonic, " ", + ) + + ctxb := context.Background() + ctxt, cancel := context.WithTimeout(ctxb, defaultTimeout) + defer cancel() + + rawLNCConn, err := connectMailbox(ctxt, connectPhrase) + require.NoError(t.t, err) + + lightningClient := lnrpc.NewLightningClient(rawLNCConn) + + // The channel balance should always reflect our account balance. + assertChannelBalance( + ctxt, t.t, lightningClient, currentAccountBalance, 0, + ) + + // The on-chain balance should always be zero, no on-chain transactions + // should show up and nothing channel or peer related should be shown. + assertWalletBalance(ctxt, t.t, lightningClient, 0, 0, 0, 0) + assertNumChannels(ctxt, t.t, lightningClient, 0, 0, 0, 0) + assertNumPeers(ctxt, t.t, lightningClient, 0) + + txnsResp, err := lightningClient.GetTransactions( + ctxt, &lnrpc.GetTransactionsRequest{}, + ) + require.NoError(t.t, err) + require.Len(t.t, txnsResp.Transactions, 0) + + // There should be invoices and payments from the previous test over RPC + // directly. + assertNumInvoices(ctxt, t.t, lightningClient, 1) + assertNumPayments(ctxt, t.t, lightningClient, 1) +} + // testAccountRestrictions tests the different scenarios in which the account // restricted RPC responses differ from the normal responses. func testAccountRestrictions(ctxa context.Context, t *harnessTest, - net *NetworkHarness, rawConn *grpc.ClientConn, charlie *HarnessNode, - initialAccountBalance uint64) { + rawConn grpc.ClientConnInterface, charlie *HarnessNode, + initialAccountBalance uint64) uint64 { // The ctxa variable is the context with the restricted account macaroon // applied to it. But we also need a timeout context for things we do @@ -217,6 +284,8 @@ func testAccountRestrictions(ctxa context.Context, t *harnessTest, ctxa, t.t, lightningClient, initialAccountBalance+inboundPaymentAmt-outboundPaymentAmt, 0, ) + + return initialAccountBalance + inboundPaymentAmt - outboundPaymentAmt } func assertChannelBalance(ctx context.Context, t *testing.T, diff --git a/litrpc/lit-sessions.pb.go b/litrpc/lit-sessions.pb.go index c6cdf77d..147b05bd 100644 --- a/litrpc/lit-sessions.pb.go +++ b/litrpc/lit-sessions.pb.go @@ -27,6 +27,7 @@ const ( SessionType_TYPE_MACAROON_ADMIN SessionType = 1 SessionType_TYPE_MACAROON_CUSTOM SessionType = 2 SessionType_TYPE_UI_PASSWORD SessionType = 3 + SessionType_TYPE_MACAROON_ACCOUNT SessionType = 4 ) // Enum value maps for SessionType. @@ -36,12 +37,14 @@ var ( 1: "TYPE_MACAROON_ADMIN", 2: "TYPE_MACAROON_CUSTOM", 3: "TYPE_UI_PASSWORD", + 4: "TYPE_MACAROON_ACCOUNT", } SessionType_value = map[string]int32{ "TYPE_MACAROON_READONLY": 0, "TYPE_MACAROON_ADMIN": 1, "TYPE_MACAROON_CUSTOM": 2, "TYPE_UI_PASSWORD": 3, + "TYPE_MACAROON_ACCOUNT": 4, } ) @@ -135,6 +138,7 @@ type AddSessionRequest struct { MailboxServerAddr string `protobuf:"bytes,4,opt,name=mailbox_server_addr,json=mailboxServerAddr,proto3" json:"mailbox_server_addr,omitempty"` DevServer bool `protobuf:"varint,5,opt,name=dev_server,json=devServer,proto3" json:"dev_server,omitempty"` MacaroonCustomPermissions []*MacaroonPermission `protobuf:"bytes,6,rep,name=macaroon_custom_permissions,json=macaroonCustomPermissions,proto3" json:"macaroon_custom_permissions,omitempty"` + AccountId string `protobuf:"bytes,7,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` } func (x *AddSessionRequest) Reset() { @@ -211,6 +215,13 @@ func (x *AddSessionRequest) GetMacaroonCustomPermissions() []*MacaroonPermission return nil } +func (x *AddSessionRequest) GetAccountId() string { + if x != nil { + return x.AccountId + } + return "" +} + type MacaroonPermission struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -340,6 +351,7 @@ type Session struct { RemotePublicKey []byte `protobuf:"bytes,10,opt,name=remote_public_key,json=remotePublicKey,proto3" json:"remote_public_key,omitempty"` CreatedAt uint64 `protobuf:"varint,11,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` MacaroonRecipe *MacaroonRecipe `protobuf:"bytes,12,opt,name=macaroon_recipe,json=macaroonRecipe,proto3" json:"macaroon_recipe,omitempty"` + AccountId string `protobuf:"bytes,13,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` } func (x *Session) Reset() { @@ -458,6 +470,13 @@ func (x *Session) GetMacaroonRecipe() *MacaroonRecipe { return nil } +func (x *Session) GetAccountId() string { + if x != nil { + return x.AccountId + } + return "" +} + type MacaroonRecipe struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -687,7 +706,7 @@ var File_lit_sessions_proto protoreflect.FileDescriptor var file_lit_sessions_proto_rawDesc = []byte{ 0x0a, 0x12, 0x6c, 0x69, 0x74, 0x2d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x22, 0xca, 0x02, 0x0a, + 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x22, 0xe9, 0x02, 0x0a, 0x11, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x12, 0x36, 0x0a, 0x0c, 0x73, 0x65, 0x73, 0x73, @@ -708,101 +727,106 @@ var file_lit_sessions_proto_rawDesc = []byte{ 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x19, 0x6d, 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x50, 0x65, - 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x44, 0x0a, 0x12, 0x4d, 0x61, 0x63, - 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, - 0x16, 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, - 0x3f, 0x0a, 0x12, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x22, 0xb8, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, - 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, - 0x65, 0x6c, 0x12, 0x39, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x6c, 0x69, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, - 0x0c, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, 0x16, 0x65, 0x78, 0x70, - 0x69, 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x53, 0x65, 0x63, 0x6f, - 0x6e, 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x5f, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x11, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x65, 0x76, 0x53, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, - 0x63, 0x72, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x70, 0x61, 0x69, 0x72, - 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x69, - 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6d, 0x6e, 0x65, 0x6d, - 0x6f, 0x6e, 0x69, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x69, 0x72, - 0x69, 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, - 0x63, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x75, - 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, - 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x6d, 0x61, - 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x65, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, - 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x52, 0x0e, 0x6d, 0x61, 0x63, - 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x22, 0x68, 0x0a, 0x0e, 0x4d, - 0x61, 0x63, 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x12, 0x3c, 0x0a, - 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, 0x61, - 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, - 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, - 0x61, 0x76, 0x65, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, - 0x76, 0x65, 0x61, 0x74, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x14, - 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x73, 0x22, 0x40, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63, - 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x4b, 0x65, 0x79, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x72, 0x0a, 0x0b, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, - 0x44, 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, - 0x12, 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, - 0x4e, 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x55, 0x49, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x03, - 0x2a, 0x59, 0x0a, 0x0c, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, - 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, - 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, - 0x55, 0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, - 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, - 0x45, 0x5f, 0x45, 0x58, 0x50, 0x49, 0x52, 0x45, 0x44, 0x10, 0x03, 0x32, 0xe8, 0x01, 0x0a, 0x08, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, - 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, - 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, - 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x74, - 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, - 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, - 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, - 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, - 0x62, 0x73, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x44, 0x0a, 0x12, 0x4d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, + 0x0a, 0x06, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x3f, + 0x0a, 0x12, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x29, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x22, + 0xd7, 0x04, 0x0a, 0x07, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x6c, + 0x61, 0x62, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x62, 0x65, + 0x6c, 0x12, 0x39, 0x0a, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, + 0x63, 0x2e, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x0c, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x36, 0x0a, 0x0c, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x13, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x0b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x18, 0x65, 0x78, 0x70, 0x69, 0x72, 0x79, 0x5f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, 0x16, 0x65, 0x78, 0x70, 0x69, + 0x72, 0x79, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x53, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x5f, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x11, 0x6d, 0x61, 0x69, 0x6c, 0x62, 0x6f, 0x78, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, + 0x64, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x64, 0x65, 0x76, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x64, 0x65, 0x76, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x70, 0x61, 0x69, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x63, + 0x72, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x70, 0x61, 0x69, 0x72, 0x69, + 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x36, 0x0a, 0x17, 0x70, 0x61, 0x69, 0x72, + 0x69, 0x6e, 0x67, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x5f, 0x6d, 0x6e, 0x65, 0x6d, 0x6f, + 0x6e, 0x69, 0x63, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x15, 0x70, 0x61, 0x69, 0x72, 0x69, + 0x6e, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4d, 0x6e, 0x65, 0x6d, 0x6f, 0x6e, 0x69, 0x63, + 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x72, 0x65, + 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x21, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x30, 0x01, 0x52, 0x09, + 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x3f, 0x0a, 0x0f, 0x6d, 0x61, 0x63, + 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x5f, 0x72, 0x65, 0x63, 0x69, 0x70, 0x65, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x52, 0x0e, 0x6d, 0x61, 0x63, 0x61, + 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x61, 0x63, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x49, 0x64, 0x22, 0x68, 0x0a, 0x0e, 0x4d, 0x61, 0x63, + 0x61, 0x72, 0x6f, 0x6f, 0x6e, 0x52, 0x65, 0x63, 0x69, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0b, 0x70, + 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4d, 0x61, 0x63, 0x61, 0x72, 0x6f, + 0x6f, 0x6e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, + 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x61, 0x76, + 0x65, 0x61, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x63, 0x61, 0x76, 0x65, + 0x61, 0x74, 0x73, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x43, 0x0a, 0x14, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x22, + 0x40, 0x0a, 0x14, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x6f, 0x63, 0x61, 0x6c, + 0x5f, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, + 0x79, 0x22, 0x17, 0x0a, 0x15, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x8d, 0x01, 0x0a, 0x0b, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x16, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, + 0x4f, 0x4e, 0x4c, 0x59, 0x10, 0x00, 0x12, 0x17, 0x0a, 0x13, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, + 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, 0x5f, 0x41, 0x44, 0x4d, 0x49, 0x4e, 0x10, 0x01, 0x12, + 0x18, 0x0a, 0x14, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, + 0x5f, 0x43, 0x55, 0x53, 0x54, 0x4f, 0x4d, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x55, 0x49, 0x5f, 0x50, 0x41, 0x53, 0x53, 0x57, 0x4f, 0x52, 0x44, 0x10, 0x03, 0x12, + 0x19, 0x0a, 0x15, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x41, 0x43, 0x41, 0x52, 0x4f, 0x4f, 0x4e, + 0x5f, 0x41, 0x43, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x10, 0x04, 0x2a, 0x59, 0x0a, 0x0c, 0x53, 0x65, + 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x00, 0x12, 0x10, 0x0a, + 0x0c, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x49, 0x4e, 0x5f, 0x55, 0x53, 0x45, 0x10, 0x01, 0x12, + 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x44, + 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x45, 0x58, 0x50, 0x49, + 0x52, 0x45, 0x44, 0x10, 0x03, 0x32, 0xe8, 0x01, 0x0a, 0x08, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, + 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x0a, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, + 0x12, 0x19, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, + 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x6c, 0x69, + 0x74, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x64, 0x64, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x53, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1b, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, + 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0d, 0x52, 0x65, 0x76, 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, + 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, + 0x6f, 0x6b, 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x76, 0x6f, 0x6b, + 0x65, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x42, 0x34, 0x5a, 0x32, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6c, 0x61, 0x62, 0x73, 0x2f, 0x6c, 0x69, 0x67, + 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x2f, + 0x6c, 0x69, 0x74, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/litrpc/lit-sessions.proto b/litrpc/lit-sessions.proto index 08f081b4..08d64634 100644 --- a/litrpc/lit-sessions.proto +++ b/litrpc/lit-sessions.proto @@ -19,6 +19,7 @@ enum SessionType { TYPE_MACAROON_ADMIN = 1; TYPE_MACAROON_CUSTOM = 2; TYPE_UI_PASSWORD = 3; + TYPE_MACAROON_ACCOUNT = 4; } message AddSessionRequest { @@ -33,6 +34,8 @@ message AddSessionRequest { bool dev_server = 5; repeated MacaroonPermission macaroon_custom_permissions = 6; + + string account_id = 7; } message MacaroonPermission { @@ -86,6 +89,8 @@ message Session { uint64 created_at = 11 [jstype = JS_STRING]; MacaroonRecipe macaroon_recipe = 12; + + string account_id = 13; } message MacaroonRecipe { diff --git a/session/interface.go b/session/interface.go index eb0f2d1b..9207f9d5 100644 --- a/session/interface.go +++ b/session/interface.go @@ -19,6 +19,7 @@ const ( TypeMacaroonAdmin Type = 1 TypeMacaroonCustom Type = 2 TypeUIPassword Type = 3 + TypeMacaroonAccount Type = 4 ) // State represents the state of a session. diff --git a/session_rpcserver.go b/session_rpcserver.go index b732227a..f1e22206 100644 --- a/session_rpcserver.go +++ b/session_rpcserver.go @@ -9,6 +9,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/lightninglabs/lightning-node-connect/mailbox" + "github.com/lightninglabs/lightning-terminal/accounts" "github.com/lightninglabs/lightning-terminal/litrpc" "github.com/lightninglabs/lightning-terminal/perms" "github.com/lightninglabs/lightning-terminal/session" @@ -148,11 +149,27 @@ func (s *sessionRpcServer) AddSession(_ context.Context, permissions[entity][action] = struct{}{} } + var caveats []macaroon.Caveat switch typ { // For the default session types we use empty caveats and permissions, // the macaroons are baked correctly when creating the session. case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: + // For account based sessions we just add the account ID caveat, the + // permissions are added dynamically when creating the session. + case session.TypeMacaroonAccount: + id, err := accounts.ParseAccountID(req.AccountId) + if err != nil { + return nil, fmt.Errorf("invalid account ID: %v", err) + } + + cav := checkers.Condition(macaroons.CondLndCustom, fmt.Sprintf( + "%s %x", accounts.CondAccount, id[:], + )) + caveats = append(caveats, macaroon.Caveat{ + Id: []byte(cav), + }) + // For the custom macaroon type, we use the custom permissions specified // in the request. For the time being, the caveats list will be empty // for this type. @@ -212,14 +229,15 @@ func (s *sessionRpcServer) AddSession(_ context.Context, // No other types are currently supported. default: return nil, fmt.Errorf("invalid session type, only admin, " + - "readonly and custom macaroon types supported in LiT") + "readonly, account and custom macaroon types " + + "supported in LiT") } // Collect the de-duped permissions. - var perms []bakery.Op + var uniquePermissions []bakery.Op for entity, actions := range permissions { for action := range actions { - perms = append(perms, bakery.Op{ + uniquePermissions = append(uniquePermissions, bakery.Op{ Entity: entity, Action: action, }) @@ -228,7 +246,7 @@ func (s *sessionRpcServer) AddSession(_ context.Context, sess, err := session.NewSession( req.Label, typ, expiry, req.MailboxServerAddr, req.DevServer, - perms, nil, + uniquePermissions, caveats, ) if err != nil { return nil, fmt.Errorf("error creating new session: %v", err) @@ -291,6 +309,17 @@ func (s *sessionRpcServer) resumeSession(sess *session.Session) error { case session.TypeMacaroonAdmin, session.TypeMacaroonReadonly: permissions = s.cfg.permMgr.ActivePermissions(readOnly) + // For account based sessions we just add the account ID caveat, the + // permissions are added dynamically when creating the session. + case session.TypeMacaroonAccount: + if sess.MacaroonRecipe == nil { + return fmt.Errorf("invalid account session, expected " + + "recipe to be set") + } + + caveats = sess.MacaroonRecipe.Caveats + permissions = accounts.MacaroonPermissions + // For custom session types, we use the caveats and permissions that // were persisted on session creation. case session.TypeMacaroonCustom: @@ -567,6 +596,9 @@ func marshalRPCType(typ session.Type) (litrpc.SessionType, error) { case session.TypeUIPassword: return litrpc.SessionType_TYPE_UI_PASSWORD, nil + case session.TypeMacaroonAccount: + return litrpc.SessionType_TYPE_MACAROON_ACCOUNT, nil + default: return 0, fmt.Errorf("unknown type <%d>", typ) } @@ -587,6 +619,9 @@ func unmarshalRPCType(typ litrpc.SessionType) (session.Type, error) { case litrpc.SessionType_TYPE_UI_PASSWORD: return session.TypeUIPassword, nil + case litrpc.SessionType_TYPE_MACAROON_ACCOUNT: + return session.TypeMacaroonAccount, nil + default: return 0, fmt.Errorf("unknown type <%d>", typ) }