Skip to content

Commit

Permalink
Merge pull request #230 from iqmessenger-bv/accessTokenConnection
Browse files Browse the repository at this point in the history
Access token connection
  • Loading branch information
michaelklishin committed Mar 5, 2024
2 parents 85779a8 + ce99fc9 commit 30538c8
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 18 deletions.
4 changes: 4 additions & 0 deletions RMQClient.xcodeproj/project.pbxproj
Expand Up @@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
1029A0E22087A97E00C72924 /* ConnectionDeadlockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1029A0E12087A97E00C72924 /* ConnectionDeadlockTests.swift */; };
4DF6E46D27F6E98100C43208 /* RMQClient.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AEE7FE911C3BCA6000DF8C4F /* RMQClient.framework */; };
5CE0C5292B873842000087B7 /* ConnectionUpdateSecretTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */; };
70311B0B21ED538600AE1804 /* RMQConnectionDefaults.h in Headers */ = {isa = PBXBuildFile; fileRef = 70311B0A21ED538600AE1804 /* RMQConnectionDefaults.h */; };
70338A2421FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 70338A2321FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift */; };
705359A921D174A400CF6456 /* TestCertificates in Resources */ = {isa = PBXBuildFile; fileRef = 705359A821D174A400CF6456 /* TestCertificates */; };
Expand Down Expand Up @@ -238,6 +239,7 @@
/* Begin PBXFileReference section */
1029A0E12087A97E00C72924 /* ConnectionDeadlockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectionDeadlockTests.swift; sourceTree = "<group>"; };
4DF6E43627F6E90700C43208 /* MemoryTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MemoryTest.app; sourceTree = BUILT_PRODUCTS_DIR; };
5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionUpdateSecretTest.swift; sourceTree = "<group>"; };
70311B0A21ED538600AE1804 /* RMQConnectionDefaults.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RMQConnectionDefaults.h; sourceTree = "<group>"; };
70338A2321FBAA7C00C9069D /* TLSConnectionIntegrationTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TLSConnectionIntegrationTest.swift; sourceTree = "<group>"; };
705359A821D174A400CF6456 /* TestCertificates */ = {isa = PBXFileReference; lastKnownFileType = folder; path = TestCertificates; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -491,6 +493,7 @@
AE26FA2F1C970E9A00CDBBAA /* Channels */ = {
isa = PBXGroup;
children = (
5CE0C5282B873842000087B7 /* ConnectionUpdateSecretTest.swift */,
AE26FA2D1C970DF100CDBBAA /* RMQChannelContract.swift */,
AE8279841C8D86110013ADD1 /* ChannelAllocationTest.swift */,
AE8AD2681CC545ED00229444 /* RMQFramesetValidatorTest.swift */,
Expand Down Expand Up @@ -1292,6 +1295,7 @@
AE9DB00D1D12AA120005F44B /* RMQTransactionalConfirmationsTest.swift in Sources */,
AE11F1B21D155C8A007AD330 /* RMQMessageTest.swift in Sources */,
AE9DB0091D11FDED0005F44B /* ConfirmationsSpy.swift in Sources */,
5CE0C5292B873842000087B7 /* ConnectionUpdateSecretTest.swift in Sources */,
AEA8A7621CC97C7900371E38 /* RMQGCDSerialQueueTest.swift in Sources */,
AE59345B1C8735FA00560A73 /* ChannelSpy.swift in Sources */,
AE8AD25C1CC4E67F00229444 /* RMQUnallocatedChannelTest.swift in Sources */,
Expand Down
10 changes: 10 additions & 0 deletions RMQClient/RMQConnection.h
Expand Up @@ -242,4 +242,14 @@
*/
- (nonnull id<RMQChannel>)createChannel;

/*!
* @brief Update secret.
* This method updates the secret used to authenticate this connection.
* It is used when secrets have an expiration date and need to be renewed, like OAuth 2 tokens.
* @param secret The new secret.
* @param reason The reason for the secret update.
*/
- (void)updateSecret:(nonnull NSString *)secret
reason:(nonnull NSString *)reason;

@end
16 changes: 16 additions & 0 deletions RMQClient/RMQConnection.m
Expand Up @@ -608,6 +608,14 @@ - (void)start {
return ch;
}

- (void)updateSecret:(NSString *)secret
reason:(NSString *)reason
{
[self.commandQueue enqueue:^{
[self sendFrameset:[[RMQFrameset alloc] initWithChannelNumber:@0 method:[self methodForUpdateSecret:secret reason:reason]]];
}];
}

- (BOOL)hasCompletedHandshake {
return self.handshakeComplete;
}
Expand Down Expand Up @@ -746,6 +754,14 @@ - (void)closeAllUserChannels {
}
}

- (RMQConnectionUpdateSecret *)methodForUpdateSecret:(NSString *)secret
reason:(NSString *)reason {
RMQLongstr *secretLongstr = [[RMQLongstr alloc] init:secret];
RMQShortstr *reasonShortstr = [[RMQShortstr alloc] init:reason];
return [[RMQConnectionUpdateSecret alloc] initWithSecret:secretLongstr
reason:reasonShortstr];
}

- (RMQConnectionClose *)amqClose {
return [[RMQConnectionClose alloc] initWithReplyCode:[[RMQShort alloc] init:200]
replyText:[[RMQShortstr alloc] init:@"Goodbye"]
Expand Down
2 changes: 2 additions & 0 deletions RMQClient/RMQMethodMap.m
Expand Up @@ -18,6 +18,8 @@ + (NSDictionary *)methodMap {
@[@(10), @(51)] : [RMQConnectionCloseOk class],
@[@(10), @(60)] : [RMQConnectionBlocked class],
@[@(10), @(61)] : [RMQConnectionUnblocked class],
@[@(10), @(70)] : [RMQConnectionUpdateSecret class],
@[@(10), @(71)] : [RMQConnectionUpdateSecretOk class],
@[@(20), @(10)] : [RMQChannelOpen class],
@[@(20), @(11)] : [RMQChannelOpenOk class],
@[@(20), @(20)] : [RMQChannelFlow class],
Expand Down
9 changes: 9 additions & 0 deletions RMQClient/RMQMethods.h
Expand Up @@ -86,6 +86,15 @@ typedef NS_OPTIONS(NSUInteger, RMQConnectionOpenOptions) {
@end
@interface RMQConnectionUnblocked : RMQValue <RMQMethod>

@end
@interface RMQConnectionUpdateSecret : RMQValue <RMQMethod>
@property (nonnull, copy, nonatomic, readonly) RMQLongstr *secret;
@property (nonnull, copy, nonatomic, readonly) RMQShortstr *reason;
- (nonnull instancetype)initWithSecret:(nonnull RMQLongstr *)secret
reason:(nonnull RMQShortstr *)reason;
@end
@interface RMQConnectionUpdateSecretOk : RMQValue <RMQMethod>

@end
@interface RMQChannelOpen : RMQValue <RMQMethod>
@property (nonnull, copy, nonatomic, readonly) RMQShortstr *reserved1;
Expand Down
91 changes: 91 additions & 0 deletions RMQClient/RMQMethods.m
Expand Up @@ -639,6 +639,97 @@ - (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }


- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
self.payloadArguments = @[];
}
return self;
}

- (NSData *)amqEncoded {
NSMutableData *encoded = [NSMutableData new];
[encoded appendData:[[RMQShort alloc] init:self.classID.integerValue].amqEncoded];
[encoded appendData:[[RMQShort alloc] init:self.methodID.integerValue].amqEncoded];
for (id<RMQEncodable>arg in self.payloadArguments) {
[encoded appendData:arg.amqEncoded];
}
return encoded;
}

@end

@interface RMQConnectionUpdateSecret ()
@property (nonnull, copy, nonatomic, readwrite) RMQLongstr *secret;
@property (nonnull, copy, nonatomic, readwrite) RMQShortstr *reason;
@property (nonatomic, readwrite) NSArray *payloadArguments;
@property (nonatomic, readwrite) BOOL hasContent;
@end

@implementation RMQConnectionUpdateSecret

+ (NSArray *)propertyClasses {
return @[[RMQLongstr class],
[RMQShortstr class]];
}
- (NSNumber *)classID { return @10; }
- (NSNumber *)methodID { return @70; }
- (Class)syncResponse { return [RMQConnectionUpdateSecretOk class]; }
- (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }

- (nonnull instancetype)initWithSecret:(nonnull RMQLongstr *)secret
reason:(nonnull RMQShortstr *)reason {
self = [super init];
if (self) {
self.secret = secret;
self.reason = reason;
self.payloadArguments = @[self.secret,
self.reason];
}
return self;
}

- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
self.secret = ((RMQLongstr *)frame[0]);
self.reason = ((RMQShortstr *)frame[1]);
self.payloadArguments = @[self.secret,
self.reason];
}
return self;
}

- (NSData *)amqEncoded {
NSMutableData *encoded = [NSMutableData new];
[encoded appendData:[[RMQShort alloc] init:self.classID.integerValue].amqEncoded];
[encoded appendData:[[RMQShort alloc] init:self.methodID.integerValue].amqEncoded];
for (id<RMQEncodable>arg in self.payloadArguments) {
[encoded appendData:arg.amqEncoded];
}
return encoded;
}

@end

@interface RMQConnectionUpdateSecretOk ()
@property (nonatomic, readwrite) NSArray *payloadArguments;
@property (nonatomic, readwrite) BOOL hasContent;
@end

@implementation RMQConnectionUpdateSecretOk

+ (NSArray *)propertyClasses {
return @[];
}
- (NSNumber *)classID { return @10; }
- (NSNumber *)methodID { return @71; }
- (Class)syncResponse { return nil; }
- (NSNumber *)frameTypeID { return @1; }
- (BOOL)hasContent { return NO; }


- (instancetype)initWithDecodedFrame:(NSArray *)frame {
self = [super init];
if (self) {
Expand Down
26 changes: 26 additions & 0 deletions RMQClientTests/ConnectionUpdateSecretTest.swift
@@ -0,0 +1,26 @@
//
// ConnectionUpdateSecretTest.swift
// RMQClientTests
//
// Created by Andrew Urban on 22.02.2024.
// Copyright © 2024 VMware. All rights reserved.
//

import XCTest

final class ConnectionUpdateSecretTest: XCTestCase {

func testSendsUpdateSecretMethod() {
let (transport, q, conn, _) = ConnectionWithFakesHelper.connectionAfterHandshake()

let secret = "someSecret"
let reason = "some test reason"

conn.updateSecret(secret, reason: reason);

try? q.step()

transport.assertClientSentMethod(MethodFixtures.connectionUpdateSecret(secret, reason: reason), channelNumber: 0)
}

}
5 changes: 5 additions & 0 deletions RMQClientTests/MethodFixtures.swift
Expand Up @@ -214,6 +214,11 @@ class MethodFixtures {
static func connectionTuneOk() -> RMQConnectionTuneOk {
return RMQConnectionTuneOk(channelMax: RMQShort(65535), frameMax: RMQLong(RMQFrameMax), heartbeat: RMQShort(60))
}

static func connectionUpdateSecret(_ secret: String,
reason: String) -> RMQConnectionUpdateSecret {
return RMQConnectionUpdateSecret(secret: RMQLongstr(secret), reason: RMQShortstr(reason))
}

static func exchangeBind(_ source: String, destination: String, routingKey: String) -> RMQExchangeBind {
return RMQExchangeBind(destination: destination, source: source, routingKey: routingKey)
Expand Down
30 changes: 30 additions & 0 deletions codegen/amqp0-9-1.extended.xml
Expand Up @@ -4,6 +4,7 @@
WARNING: Modified from the official 0-9-1 specification XML by
the addition of:
confirm.select and confirm.select-ok,
connection.update-secret and connection.update-secret-ok,
exchange.bind and exchange.bind-ok,
exchange.unbind and exchange.unbind-ok,
basic.nack,
Expand Down Expand Up @@ -914,6 +915,35 @@
<chassis name = "server" implement = "MUST"/>
<chassis name = "client" implement = "MUST"/>
</method>

<method name = "update-secret" synchronous = "1" index = "70" label = "update secret">
<doc>
This method updates the secret used to authenticate this connection. It is used when secrets have an expiration date and need to be renewed, like OAuth 2 tokens.
</doc>

<chassis name = "client" implement = "MUST" />
<response name = "update-secret-ok" />

<field name = "secret" domain = "longstr">
<doc>
The new secret.
</doc>
</field>

<field name = "reason" domain = "shortstr">
<doc>
The reason for the secret update.
</doc>
</field>
</method>

<method name = "update-secret-ok" synchronous = "1" index = "71" label = "update secret response">
<doc>
This method confirms the updated secret is valid.
</doc>
<chassis name = "server" implement = "MUST" />
</method>

</class>

<!-- == CHANNEL ========================================================== -->
Expand Down
14 changes: 1 addition & 13 deletions docker/Dockerfile
@@ -1,16 +1,4 @@
FROM ubuntu:18.04

RUN apt-get update -y
RUN apt-get install -y gnupg2 wget
RUN wget -O - "https://github.com/rabbitmq/signing-keys/releases/download/2.0/rabbitmq-release-signing-key.asc" | apt-key add -

COPY apt/sources.list.d/bintray.rabbitmq.list /etc/apt/sources.list.d/bintray.rabbitmq.list
COPY apt/preferences.d/erlang /etc/apt/preferences.d/erlang

RUN apt-get update -y

RUN apt-get upgrade -y && \
apt-get install -y rabbitmq-server
FROM rabbitmq:3.12-management

COPY docker-entrypoint.sh /
COPY certificates/*.pem /etc/rabbitmq/
Expand Down
3 changes: 0 additions & 3 deletions docker/apt/preferences.d/erlang

This file was deleted.

2 changes: 0 additions & 2 deletions docker/apt/sources.list.d/bintray.rabbitmq.list

This file was deleted.

0 comments on commit 30538c8

Please sign in to comment.