diff --git a/library/security/jwt/src/jwt_encoder.e b/library/security/jwt/src/jwt_encoder.e deleted file mode 100644 index 9c81ece3..00000000 --- a/library/security/jwt/src/jwt_encoder.e +++ /dev/null @@ -1,275 +0,0 @@ -note - description: "JSON Web Token encoder" - date: "$Date$" - revision: "$Revision$" - -class - JWT_ENCODER - -feature -- Basic operations - - encoded_values (a_values: STRING_TABLE [READABLE_STRING_GENERAL]; a_secret: READABLE_STRING_8; a_algo: READABLE_STRING_8): STRING - local - j: JSON_OBJECT - do - create j.make_with_capacity (a_values.count) - across - a_values as ic - loop - j.put_string (ic.item, ic.key) - end - Result := encoded_json (j, a_secret, a_algo) - end - - encoded_json (a_json: JSON_OBJECT; a_secret: READABLE_STRING_8; a_algo: READABLE_STRING_8): STRING - local - vis: JSON_PRETTY_STRING_VISITOR - s: STRING - do - create s.make_empty - create vis.make (s) - vis.visit_json_object (a_json) - Result := encoded_string (s, a_secret, a_algo) - end - - encoded_string (a_payload: READABLE_STRING_8; a_secret: READABLE_STRING_8; a_algo: READABLE_STRING_8): STRING - local - alg, sign: STRING_8 - l_enc_payload, l_enc_header: READABLE_STRING_8 - do - reset_error - if a_algo.is_case_insensitive_equal_general (alg_hs256) then - alg := alg_hs256 - elseif a_algo.is_case_insensitive_equal_general (alg_none) then - alg := alg_none - else - report_unsupported_alg_error (a_algo) - alg := alg_hs256 -- Default ... - end - l_enc_header := base64url_encode (header ("JWT", alg)) - l_enc_payload := base64url_encode (a_payload) - sign := signature (l_enc_header, l_enc_payload, a_secret, alg) - create Result.make (l_enc_header.count + 1 + l_enc_payload.count + 1 + sign.count) - Result.append (l_enc_header) - Result.append_character ('.') - Result.append (l_enc_payload) - Result.append_character ('.') - Result.append (sign) - end - - decoded_string (a_token: READABLE_STRING_8; a_secret: READABLE_STRING_8; a_algo: detachable READABLE_STRING_8): detachable STRING - local - i,j,n: INTEGER - alg, l_enc_payload, l_enc_header, l_signature: READABLE_STRING_8 - do - reset_error - n := a_token.count - i := a_token.index_of ('.', 1) - if i > 0 then - j := a_token.index_of ('.', i + 1) - if j > 0 then - l_enc_header := a_token.substring (1, i - 1) - l_enc_payload := a_token.substring (i + 1, j - 1) - l_signature := a_token.substring (j + 1, n) - Result := base64url_decode (l_enc_payload) - alg := a_algo - if alg = Void then - alg := signature_algorithm_from_encoded_header (l_enc_header) - if alg = Void then - -- Use default - alg := alg_hs256 - end - end - check alg_set: alg /= Void end - if alg.is_case_insensitive_equal (alg_hs256) then - alg := alg_hs256 - elseif alg.is_case_insensitive_equal (alg_none) then - alg := alg_none - else - alg := alg_hs256 - report_unsupported_alg_error (alg) - end - - if not l_signature.same_string (signature (l_enc_header, l_enc_payload, a_secret, alg)) then - report_unverified_token_error - end - else - report_invalid_token - end - else - report_invalid_token - end - end - -feature -- Error status - - error_code: INTEGER - -- Last error, if any. - - has_error: BOOLEAN - -- Last `encoded_string` reported an error? - do - Result := error_code /= 0 - end - - has_unsupported_alg_error: BOOLEAN - do - Result := error_code = unsupported_alg_error - end - - has_unverified_token_error: BOOLEAN - do - Result := error_code = unverified_token_error - end - - has_invalid_token_error: BOOLEAN - do - Result := error_code = invalid_token_error - end - -feature {NONE} -- Error reporting - - reset_error - do - error_code := 0 - end - - report_unsupported_alg_error (alg: READABLE_STRING_8) - do - error_code := unsupported_alg_error - end - - report_unverified_token_error - do - error_code := unverified_token_error - end - - report_invalid_token - do - error_code := invalid_token_error - end - -feature {NONE} -- Constants - - unsupported_alg_error: INTEGER = -2 - - unverified_token_error: INTEGER = -4 - - invalid_token_error: INTEGER = -8 - - alg_hs256: STRING = "HS256" - -- HMAC SHA256. - - alg_none: STRING = "none" - -- for unsecured token. - -feature -- Conversion - - header (a_type: detachable READABLE_STRING_8; alg: READABLE_STRING_8): STRING - do - create Result.make_empty - Result.append ("{%"typ%":%"") - if a_type /= Void then - Result.append (a_type) - else - Result.append ("JWT") - end - Result.append ("%",%"alg%":%"") - Result.append (alg) - Result.append ("%"}") - end - -feature {NONE} -- Conversion - - signature_algorithm_from_encoded_header (a_enc_header: READABLE_STRING_8): detachable STRING_8 - local - jp: JSON_PARSER - do - create jp.make_with_string (base64url_decode (a_enc_header)) - jp.parse_content - if - attached jp.parsed_json_object as jo and then - attached {JSON_STRING} jo.item ("alg") as j_alg - then - Result := j_alg.unescaped_string_8 - end - end - -feature -- Base64 - - base64url_encode (s: READABLE_STRING_8): STRING_8 - local - urlencoder: URL_ENCODER - base64: BASE64 - do - create urlencoder - create base64 - Result := urlsafe_encode (base64.encoded_string (s)) - end - -feature {NONE} -- Implementation - - signature (a_enc_header, a_enc_payload: READABLE_STRING_8; a_secret: READABLE_STRING_8; alg: READABLE_STRING_8): STRING_8 - local - s: STRING - do - if alg = alg_none then - create Result.make_empty - else - create s.make (a_enc_header.count + 1 + a_enc_payload.count) - s.append (a_enc_header) - s.append_character ('.') - s.append (a_enc_payload) - if alg = alg_hs256 then - Result := base64_hmacsha256 (s, a_secret) - else - Result := base64_hmacsha256 (s, a_secret) - end - Result := urlsafe_encode (Result) - end - end - - base64url_decode (s: READABLE_STRING_8): STRING_8 - local - urlencoder: URL_ENCODER - base64: BASE64 - do - create urlencoder - create base64 - Result := base64.decoded_string (urlsafe_decode (s)) - end - - urlsafe_encode (s: READABLE_STRING_8): STRING_8 - do - create Result.make_from_string (s) - Result.replace_substring_all ("=", "") - Result.replace_substring_all ("+", "-") - Result.replace_substring_all ("/", "_") - end - - urlsafe_decode (s: READABLE_STRING_8): STRING_8 - local - i: INTEGER - do - create Result.make_from_string (s) - Result.replace_substring_all ("-", "+") - Result.replace_substring_all ("_", "/") - from - i := Result.count \\ 4 - until - i = 0 - loop - i := i - 1 - Result.extend ('=') - end - end - - base64_hmacsha256 (s: READABLE_STRING_8; a_secret: READABLE_STRING_8): STRING_8 - local - ut: JWT_UTILITIES - do - create ut - Result := ut.base64_hmacsha256 (s, a_secret) - end - -end