ObjMatrix  Check-in [092c122c69]

Overview
Comment:Add support for fetching room list
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 092c122c690b6e64c67120c6c153e82fceb484078dd3d713d56e01ce13c3902d
User & Date: js on 2020-10-03 17:08:07
Other Links: manifest | tags
Context
2020-10-03
17:20
More validation of server responses check-in: 71e1a46c8f user: js tags: trunk
17:08
Add support for fetching room list check-in: 092c122c69 user: js tags: trunk
16:21
MTXClient: Add support for logging out check-in: c29845b7b8 user: js tags: trunk
Changes

Modified src/MTXClient.h from [04928e6321] to [fa482021bd].

38
39
40
41
42
43
44









45
46
47
48
49
50
51
/**
 * @brief A block called when the device was logged out.
 *
 * @param exception `nil` on success, otherwise an exception
 */
typedef void (^mtx_client_logout_block_t)(id _Nullable exception);










/**
 * @brief A class that represents a client.
 */
@interface MTXClient: OFObject
/**
 * @brief The user ID used by the client.
 */







>
>
>
>
>
>
>
>
>







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/**
 * @brief A block called when the device was logged out.
 *
 * @param exception `nil` on success, otherwise an exception
 */
typedef void (^mtx_client_logout_block_t)(id _Nullable exception);

/**
 * @brief A block called when the room list was fetched.
 *
 * @param rooms An array of joined rooms, or nil on error
 * @param exception An exception if fetching the room list failed
 */
typedef void (^mtx_client_room_list_block_t)(
    OFArray<OFString *> *_Nullable rooms, id _Nullable exception);

/**
 * @brief A class that represents a client.
 */
@interface MTXClient: OFObject
/**
 * @brief The user ID used by the client.
 */
101
102
103
104
105
106
107
108
109
110







111
112
113
		    homeserver: (OFURL *)homeserver OF_DESIGNATED_INITIALIZER;

/**
 * @brief Logs out the device and invalidates the access token.
 *
 * @warning The client can no longer be used after this succeeded!
 *
 * @param block The block to call when logging out succeeded or failed
 */
- (void)asyncLogOutWithBlock: (mtx_client_logout_block_t)block;







@end

OF_ASSUME_NONNULL_END







|


>
>
>
>
>
>
>



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
		    homeserver: (OFURL *)homeserver OF_DESIGNATED_INITIALIZER;

/**
 * @brief Logs out the device and invalidates the access token.
 *
 * @warning The client can no longer be used after this succeeded!
 *
 * @param block A block to call when logging out succeeded or failed
 */
- (void)asyncLogOutWithBlock: (mtx_client_logout_block_t)block;

/**
 * @brief Fetches the list of joined rooms.
 *
 * @param block A block to call with the list of joined room
 */
- (void)asyncFetchRoomList: (mtx_client_room_list_block_t)block;
@end

OF_ASSUME_NONNULL_END

Modified src/MTXClient.m from [745a831094] to [9f44985428].

19
20
21
22
23
24
25

26
27
28
29
30
31
32
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXClient.h"
#import "MTXRequest.h"


#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"

static void
validateHomeserver(OFURL *homeserver)
{
	if (![homeserver.scheme isEqual: @"http"] &&







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXClient.h"
#import "MTXRequest.h"

#import "MTXFetchRoomListFailedException.h"
#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"

static void
validateHomeserver(OFURL *homeserver)
{
	if (![homeserver.scheme isEqual: @"http"] &&
197
198
199
200
201
202
203


























204
205
206
207
				     statusCode: statusCode
				       response: response]);
			return;
		}

		block(nil);
	}];



























	objc_autoreleasePoolPop(pool);
}
@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>




198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
				     statusCode: statusCode
				       response: response]);
			return;
		}

		block(nil);
	}];

	objc_autoreleasePoolPop(pool);
}

- (void)asyncFetchRoomList: (mtx_client_room_list_block_t)block
{
	void *pool = objc_autoreleasePoolPush();
	MTXRequest *request =
	    [self requestWithPath: @"/_matrix/client/r0/joined_rooms"];
	[request asyncPerformWithBlock: ^ (mtx_response_t response,
					    int statusCode, id exception) {
		if (exception != nil) {
			block(nil, exception);
			return;
		}

		if (statusCode != 200 || response[@"joined_rooms"] == nil) {
			block(nil, [MTXFetchRoomListFailedException
			    exceptionWithClient: self
				     statusCode: statusCode
				       response: response]);
			return;
		}

		block(response[@"joined_rooms"], nil);
	}];

	objc_autoreleasePoolPop(pool);
}
@end

Modified src/ObjMatrix.h from [85f68e7b26] to [43fe4f29c2].

19
20
21
22
23
24
25

26
27
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXClient.h"
#import "MTXRequest.h"


#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"







>


19
20
21
22
23
24
25
26
27
28
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXClient.h"
#import "MTXRequest.h"

#import "MTXFetchRoomListFailedException.h"
#import "MTXLoginFailedException.h"
#import "MTXLogoutFailedException.h"

Added src/exceptions/MTXClientException.h version [1816edf39c].

























































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * https://fossil.nil.im/objmatrix
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import <ObjFW/ObjFW.h>

#import "MTXRequest.h"

OF_ASSUME_NONNULL_BEGIN

@class MTXClient;

@interface MTXClientException: OFException
@property (readonly, nonatomic) MTXClient *client;
@property (readonly, nonatomic) int statusCode;
@property (readonly, nonatomic) mtx_response_t response;

+ (instancetype)exceptionWithClient: (MTXClient *)client
			 statusCode: (int)statusCode
			   response: (mtx_response_t)response;
- (instancetype)initWithClient: (OFString *)user
		    statusCode: (int)statusCode
		      response: (mtx_response_t)response;
@end

OF_ASSUME_NONNULL_END

Added src/exceptions/MTXClientException.m version [42e31b0030].





























































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * https://fossil.nil.im/objmatrix
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXLogoutFailedException.h"

#import "MTXClient.h"

@implementation MTXClientException
+ (instancetype)exceptionWithClient: (MTXClient *)client
			 statusCode: (int)statusCode
			   response: (mtx_response_t)response
{
	return [[[self alloc] initWithClient: client
				  statusCode: statusCode
				    response: response] autorelease];
}

- (instancetype)initWithClient: (MTXClient *)client
		    statusCode: (int)statusCode
		      response: (mtx_response_t)response
{
	self = [super init];

	@try {
		_client = [client retain];
		_statusCode = statusCode;
		_response = [response copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_client release];
	[_response release];

	[super dealloc];
}
@end

Added src/exceptions/MTXFetchRoomListFailedException.h version [08ccc9d6d9].

































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * https://fossil.nil.im/objmatrix
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import <ObjFW/ObjFW.h>

#import "MTXClientException.h"

OF_ASSUME_NONNULL_BEGIN

@interface MTXFetchRoomListFailedException: MTXClientException
@end

OF_ASSUME_NONNULL_END

Added src/exceptions/MTXFetchRoomListFailedException.m version [48606353c7].





































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * Copyright (c) 2020, Jonathan Schleifer <js@nil.im>
 *
 * https://fossil.nil.im/objmatrix
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice is present in all copies.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import "MTXFetchRoomListFailedException.h"

#import "MTXClient.h"

@implementation MTXFetchRoomListFailedException
- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to fetch room list for %@: %@",
	    self.client.userID, self.response];
}
@end

Modified src/exceptions/MTXLogoutFailedException.h from [c3b16f062e] to [b5d9144c08].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import <ObjFW/ObjFW.h>

#import "MTXRequest.h"

OF_ASSUME_NONNULL_BEGIN

@class MTXClient;

@interface MTXLogoutFailedException: OFException
@property (readonly, nonatomic) MTXClient *client;
@property (readonly, nonatomic) int statusCode;
@property (readonly, nonatomic) mtx_response_t response;

+ (instancetype)exceptionWithClient: (MTXClient *)client
			 statusCode: (int)statusCode
			   response: (mtx_response_t)response;
- (instancetype)initWithClient: (OFString *)user
		    statusCode: (int)statusCode
		      response: (mtx_response_t)response;
@end

OF_ASSUME_NONNULL_END







|



<
<
|
<
<
<
<
<
<
<
<
<
<



18
19
20
21
22
23
24
25
26
27
28


29










30
31
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#import <ObjFW/ObjFW.h>

#import "MTXClientException.h"

OF_ASSUME_NONNULL_BEGIN



@interface MTXLogoutFailedException: MTXClientException










@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/MTXLogoutFailedException.m from [dd5ff28e63] to [6372c5e6df].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

67
68
 */

#import "MTXLogoutFailedException.h"

#import "MTXClient.h"

@implementation MTXLogoutFailedException
+ (instancetype)exceptionWithClient: (MTXClient *)client
			 statusCode: (int)statusCode
			   response: (mtx_response_t)response
{
	return [[[self alloc] initWithClient: client
				  statusCode: statusCode
				    response: response] autorelease];
}

- (instancetype)initWithClient: (MTXClient *)client
		    statusCode: (int)statusCode
		      response: (mtx_response_t)response
{
	self = [super init];

	@try {
		_client = [client retain];
		_statusCode = statusCode;
		_response = [response copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_client release];
	[_response release];

	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to log out user %@: %@", _client.userID, _response];

}
@end







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
>


21
22
23
24
25
26
27



































28
29
30
31
32
33
34
 */

#import "MTXLogoutFailedException.h"

#import "MTXClient.h"

@implementation MTXLogoutFailedException



































- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to log out user %@: %@",
	    self.client.userID, self.response];
}
@end

Modified src/exceptions/Makefile from [8e5700e68b] to [390f755e9e].

1
2
3
4
5


6
7
8
9
10
11
12
13
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}



SRCS = MTXLoginFailedException.m	\
       MTXLogoutFailedException.m
INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I..






>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
include ../../extra.mk

STATIC_PIC_LIB_NOINST = ${EXCEPTIONS_LIB_A}
STATIC_LIB_NOINST = ${EXCEPTIONS_A}

SRCS = MTXClientException.m			\
       MTXFetchRoomListFailedException.m	\
       MTXLoginFailedException.m		\
       MTXLogoutFailedException.m
INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I..

Modified tests/tests.m from [c6d3f94e02] to [e5d8332c51].

26
27
28
29
30
31
32




33
34
35
36
37
38
39

@interface Tests: OFObject <OFApplicationDelegate>
@end

OF_APPLICATION_DELEGATE(Tests)

@implementation Tests




- (void)applicationDidFinishLaunching
{
	__auto_type environment = OFApplication.environment;
	if (environment[@"OBJMATRIX_USER"] == nil ||
	    environment[@"OBJMATRIX_PASS"] == nil ||
	    environment[@"OBJMATRIX_HS"] == nil) {
		[of_stderr writeString: @"Please set OBJMATRIX_USER, "







>
>
>
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

@interface Tests: OFObject <OFApplicationDelegate>
@end

OF_APPLICATION_DELEGATE(Tests)

@implementation Tests
{
	MTXClient *_client;
}

- (void)applicationDidFinishLaunching
{
	__auto_type environment = OFApplication.environment;
	if (environment[@"OBJMATRIX_USER"] == nil ||
	    environment[@"OBJMATRIX_PASS"] == nil ||
	    environment[@"OBJMATRIX_HS"] == nil) {
		[of_stderr writeString: @"Please set OBJMATRIX_USER, "
48
49
50
51
52
53
54

55
56





















57
58
59
60
61
62
63
64
65
66
67
68
69
		      homeserver: homeserver
			   block: ^ (MTXClient *client, id exception) {
		if (exception != nil) {
			of_log(@"Error logging in: %@", exception);
			[OFApplication terminateWithStatus: 1];
		}


		of_log(@"Logged in client: %@", client);






















		[client asyncLogOutWithBlock: ^ (id exception) {
			if (exception != nil) {
				of_log(@"Failed to log out: %@\n", exception);
				[OFApplication terminateWithStatus: 1];
			}

			of_log(@"Logged out client");

			[OFApplication terminate];
		}];
	}];
}
@end







>
|

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|

|

|
|
<


52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92

93
94
		      homeserver: homeserver
			   block: ^ (MTXClient *client, id exception) {
		if (exception != nil) {
			of_log(@"Error logging in: %@", exception);
			[OFApplication terminateWithStatus: 1];
		}

		_client = [client retain];
		of_log(@"Logged in client: %@", _client);

		[self fetchRoomList];
	}];
}

- (void)fetchRoomList
{
	[_client asyncFetchRoomList: ^ (OFArray<OFString *> *rooms,
					 id exception) {
		if (exception != nil) {
			of_log(@"Failed to fetch room list: %@", exception);
			[OFApplication terminateWithStatus: 1];
		}

		of_log(@"Fetched room list: %@", rooms);

		[self logOut];
	}];
}

- (void)logOut
{
	[_client asyncLogOutWithBlock: ^ (id exception) {
		if (exception != nil) {
			of_log(@"Failed to log out: %@\n", exception);
			[OFApplication terminateWithStatus: 1];
		}

		of_log(@"Logged out client");

		[OFApplication terminate];
	}];

}
@end