xref: /haiku/src/apps/haikudepot/server/JwtTokenHelper.cpp (revision e1c4049fed1047bdb957b0529e1921e97ef94770)
1 /*
2  * Copyright 2023, Andrew Lindesay <apl@lindesay.co.nz>.
3  * All rights reserved. Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "JwtTokenHelper.h"
8 
9 #include "DataIOUtils.h"
10 #include "Json.h"
11 #include "JsonMessageWriter.h"
12 
13 #include <ctype.h>
14 
15 
16 /*static*/ bool
17 JwtTokenHelper::IsValid(const BString& value)
18 {
19 	int countDots = 0;
20 
21 	for (int i = 0; i < value.Length(); i++) {
22 		char ch = value[i];
23 
24 		if ('.' == ch)
25 			countDots++;
26 		else {
27 			if (!_IsBase64(ch))
28 				return false;
29 		}
30 	}
31 
32 	return 2 == countDots;
33 }
34 
35 
36 /*! A JWT token is split into three parts separated by a '.' character. The
37     middle section is a base-64 encoded string and within the string is JSON
38     structured data. The JSON data contains key-value pairs which carry data
39     about the token. This method will take a JWT token, will find the middle
40     section and will parse the claims into the supplied 'message' parameter.
41 */
42 
43 /*static*/ status_t
44 JwtTokenHelper::ParseClaims(const BString& token, BMessage& message)
45 {
46 	int firstDot = token.FindFirst('.');
47 
48 	if (firstDot == B_ERROR)
49 		return B_BAD_VALUE;
50 
51 	// find the end of the first section by looking for the next dot.
52 
53 	int secondDot = token.FindFirst('.', firstDot + 1);
54 
55 	if (secondDot == B_ERROR)
56 		return B_BAD_VALUE;
57 
58 	BMemoryIO memoryIo(&(token.String())[firstDot + 1], (secondDot - firstDot) - 1);
59 	Base64DecodingDataIO base64DecodingIo(&memoryIo, '-', '_');
60 	BJsonMessageWriter writer(message);
61 	BJson::Parse(&base64DecodingIo, &writer);
62 
63 	return writer.ErrorStatus();
64 }
65 
66 
67 /*! Note this is base64 "url" standard that disallows "/" and "+" and instead
68     uses "-" and "_".
69 */
70 
71 /*static*/ bool
72 JwtTokenHelper::_IsBase64(char ch)
73 {
74 	return isalnum(ch)
75 		|| '=' == ch
76 		|| '-' == ch
77 		|| '_' == ch;
78 }
79