ObjMatrix  Check-in [c29845b7b8]

Overview
Comment:MTXClient: Add support for logging out
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c29845b7b81229ea7bf062304824a4087c160629216064ae1a647fe8286826bb
User & Date: js on 2020-10-03 16:21:34
Other Links: manifest | tags
Context
2020-10-03
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
15:32
tests: Print better error messages check-in: 86b43015f0 user: js tags: trunk
Changes

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

31
32
33
34
35
36
37







38
39
40
41
42
43
44
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







+
+
+
+
+
+
+







 *
 * @param client If the login succeeded, the newly created client
 * @param exception If the login failed, an exception
 */
typedef void (^mtx_client_login_block_t)(MTXClient *_Nullable client,
    id _Nullable exception);

/**
 * @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.
 */
88
89
90
91
92
93
94









95
96
97
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113







+
+
+
+
+
+
+
+
+



 * @param homeserver The URL of the homeserver
 * @return An initialized MTXClient
 */
- (instancetype)initWithUserID: (OFString *)userID
		      deviceID: (OFString *)deviceID
		   accessToken: (OFString *)accessToken
		    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

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

20
21
22
23
24
25
26

27
28
29
30
31
32
33
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34







+







 * 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"] &&
	    ![homeserver.scheme isEqual: @"https"])
		@throw [OFUnsupportedProtocolException
72
73
74
75
76
77
78
79

80
81

82
83
84
85
86
87
88
73
74
75
76
77
78
79

80


81
82
83
84
85
86
87
88







-
+
-
-
+







		@"identifier": @{
			@"type": @"m.id.user",
			@"user": user
		},
		@"password": password
	};

	[request asyncPerformWithBlock:
	[request asyncPerformWithBlock: ^ (mtx_response_t response,
	    ^ (OFDictionary<OFString *, id> *response, int statusCode,
	    id exception) {
					    int statusCode, id exception) {
		if (exception != nil) {
			block(nil, exception);
			return;
		}

		if (statusCode != 200) {
			id exception = [MTXLoginFailedException
166
167
168
169
170
171
172


































173
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

	    @"\tUser ID = %@\n"
	    @"\tDevice ID = %@\n"
	    @"\tAccess token = %@\n"
	    @"\tHomeserver = %@\n"
	    @">",
	    self.class, _userID, _deviceID, _accessToken, _homeserver];
}

- (MTXRequest *)requestWithPath: (OFString *)path
{
	return [MTXRequest requestWithPath: path
			       accessToken: _accessToken
				homeserver: _homeserver];
}

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

		if (statusCode != 200) {
			block([MTXLogoutFailedException
			    exceptionWithClient: self
				     statusCode: statusCode
				       response: response]);
			return;
		}

		block(nil);
	}];

	objc_autoreleasePoolPop(pool);
}
@end

Modified src/MTXRequest.h from [dd16951835] to [2eb6986a25].

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
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







+
+
+
+
+
+
+








-
+
-
-
+







 * POSSIBILITY OF SUCH DAMAGE.
 */

#import <ObjFW/ObjFW.h>

OF_ASSUME_NONNULL_BEGIN

/**
 * @brief A response to a request.
 *
 * This is a typedef for `OFDictionary<OFString *, id> *`.
 */
typedef OFDictionary<OFString *, id> *mtx_response_t;

/**
 * @brief A block called with the response for an MTXRequest.
 *
 * @param response The response to the request, as a dictionary parsed from JSON
 * @param statusCode The HTTP status code returned for the request
 * @param exception The first exception that occurred during the request,
 *		    or `nil` on success
 */
typedef void (^mtx_request_block_t)(
typedef void (^mtx_request_block_t)(mtx_response_t _Nullable response,
    OFDictionary<OFString *, id> *_Nullable response, int statusCode,
    id _Nullable exception);
    int statusCode, id _Nullable exception);

/**
 * @brief An internal class for performing a request on the Matrix server.
 */
@interface MTXRequest: OFObject <OFHTTPClientDelegate>
/**
 * @brief The access token to use.

Modified src/MTXRequest.m from [eb63bbbdde] to [8a0c920770].

97
98
99
100
101
102
103
104
105


106
107
108
109
110
111
112
97
98
99
100
101
102
103


104
105
106
107
108
109
110
111
112







-
-
+
+








	OFMutableURL *requestURL = [[_homeserver mutableCopy] autorelease];
	requestURL.path = _path;

	OFMutableDictionary *headers = [OFMutableDictionary dictionary];
	headers[@"User-Agent"] = @"ObjMatrix";
	if (_accessToken != nil)
		headers[@"Authentication"] = [OFString
		    stringWithFormat: @"Bearer %@", _accessToken];
		headers[@"Authorization"] =
		    [OFString stringWithFormat: @"Bearer %@", _accessToken];
	if (_body != nil)
		headers[@"Content-Length"] = @(_body.count).stringValue;

	OFHTTPRequest *request = [OFHTTPRequest requestWithURL: requestURL];
	request.method = _method;
	request.headers = headers;

135
136
137
138
139
140
141
142
143
144



145
146
147
148
149
150
151
135
136
137
138
139
140
141



142
143
144
145
146
147
148
149
150
151







-
-
-
+
+
+







			size_t length = [response readIntoBuffer: buffer
							  length: 512];

			[responseData addItems: buffer
					 count: length];
		}

		OFDictionary<OFString *, id> *responseJSON =
		    [OFString stringWithUTF8String: responseData.items
					    length: responseData.count]
		mtx_response_t responseJSON = [OFString
		    stringWithUTF8String: responseData.items
				  length: responseData.count]
		    .objectByParsingJSON;

		block(responseJSON, response.statusCode, nil);
	} @catch (id e) {
		block(nil, response.statusCode, e);
	}

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

20
21
22
23
24
25
26

20
21
22
23
24
25
26
27







+
 * POSSIBILITY OF SUCH DAMAGE.
 */

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

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

Modified src/exceptions/MTXLoginFailedException.h from [be4cfcccf8] to [652862dea6].

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
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







+
+







-
+




-
+



-
+



 * 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

@interface MTXLoginFailedException: OFException
@property (readonly, nonatomic) OFString *user;
@property (readonly, nonatomic) OFURL *homeserver;
@property (readonly, nonatomic) int statusCode;
@property (readonly, nonatomic) OFDictionary<OFString *, id> *response;
@property (readonly, nonatomic) mtx_response_t response;

+ (instancetype)exceptionWithUser: (OFString *)user
		       homeserver: (OFURL *)homeserver
		       statusCode: (int)statusCode
			 response: (OFDictionary<OFString *, id> *)response;
			 response: (mtx_response_t)response;
- (instancetype)initWithUser: (OFString *)user
		  homeserver: (OFURL *)homeserver
		  statusCode: (int)statusCode
		    response: (OFDictionary<OFString *, id> *)response;
		    response: (mtx_response_t)response;
@end

OF_ASSUME_NONNULL_END

Modified src/exceptions/MTXLoginFailedException.m from [6ce58b3536] to [900a59b5fd].

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
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







-
+










-
+








#import "MTXLoginFailedException.h"

@implementation MTXLoginFailedException
+ (instancetype)exceptionWithUser: (OFString *)user
		       homeserver: (OFURL *)homeserver
		       statusCode: (int)statusCode
			 response: (OFDictionary<OFString *, id> *)response
			 response: (mtx_response_t)response
{
	return [[[self alloc] initWithUser: user
				homeserver: homeserver
				statusCode: statusCode
				  response: response] autorelease];
}

- (instancetype)initWithUser: (OFString *)user
		  homeserver: (OFURL *)homeserver
		  statusCode: (int)statusCode
		    response: (OFDictionary<OFString *, id> *)response
		    response: (mtx_response_t)response
{
	self = [super init];

	@try {
		_user = [user copy];
		_homeserver = [homeserver copy];
		_statusCode = statusCode;
58
59
60
61
62
63
64







65
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72







+
+
+
+
+
+
+

{
	[_user release];
	[_homeserver release];
	[_response release];

	[super dealloc];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"Failed to log in user %@ on %@: %@",
	    _user, _homeserver, _response];
}
@end

Added src/exceptions/MTXLogoutFailedException.h version [c3b16f062e].

Added src/exceptions/MTXLogoutFailedException.m version [dd5ff28e63].

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

1
2
3
4
5
6


7
8
9
10
11
12
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
SRCS = MTXLoginFailedException.m	\
       MTXLogoutFailedException.m
INCLUDES = ${SRCS:.m=.h}

include ../../buildsys.mk

CPPFLAGS += -I. -I..

Modified tests/tests.m from [30cdad59c3] to [c6d3f94e02].

44
45
46
47
48
49
50
51

52
53
54
55
56
57
58
59
60
61












62
63
64
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
69







-
+
-
-
-
-
-



-
-
+
+
+
+
+
+
+
+
+
+
+
+




	OFURL *homeserver = [OFURL URLWithString: environment[@"OBJMATRIX_HS"]];
	[MTXClient logInWithUser: environment[@"OBJMATRIX_USER"]
			password: environment[@"OBJMATRIX_PASS"]
		      homeserver: homeserver
			   block: ^ (MTXClient *client, id exception) {
		if (exception != nil) {
			[of_stdout writeFormat: @"Error logging in: %@\n",
			of_log(@"Error logging in: %@", exception);
						exception];
			if ([exception isKindOfClass:
			    MTXLoginFailedException.class])
				[of_stdout writeFormat: @"Response: %@\n",
							[exception response]];
			[OFApplication terminateWithStatus: 1];
		}

		[of_stdout writeFormat: @"Logged in client: %@\n", client];
		[OFApplication terminate];
		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