docs: def decrypt_token(self, username, token):
          '''
          Decrypt a token.
          '''
          version, user_type, _from = self._parse_username(username)
          if (version > self.maximum_token_version or
                  version < self.minimum_token_version):
              raise TokenValidationError('Unacceptable token version.')
          try:
              token_key = '{0}{1}{2}{3}'.format(
                  hashlib.sha256(ensure_bytes(token)).hexdigest(),
                  _from,
                  self.to_auth_context,
                  user_type
              )
          except Exception:
              raise TokenValidationError('Authentication error.')
          if token_key not in self.TOKENS:
              try:
                  token = base64.b64decode(token)
                  # Ensure normal context fields override whatever is in
                  # extra_context.
                  context = copy.deepcopy(self.extra_context)
                  context['to'] = self.to_auth_context
                  context['from'] = _from
                  if version > 1:
                      context['user_type'] = user_type
                  data = self.kms_client.decrypt(
                      CiphertextBlob=token,
                      EncryptionContext=context
                  )
                  # Decrypt doesn't take KeyId as an argument. We need to verify
                  # the correct key was used to do the decryption.
                  # Annoyingly, the KeyId from the data is actually an arn.
                  key_arn = data['KeyId']
                  if user_type == 'service':
                      if not self._valid_service_auth_key(key_arn):
                          raise TokenValidationError(
                              'Authentication error (wrong KMS key).'
                          )
                  elif user_type == 'user':
                      if not self._valid_user_auth_key(key_arn):
                          raise TokenValidationError(
                              'Authentication error (wrong KMS key).'
                          )
                  else:
                      raise TokenValidationError(
                          'Authentication error. Unsupported user_type.'
                      )
                  plaintext = data['Plaintext']
                  payload = json.loads(plaintext)
                  key_alias = self._get_key_alias_from_cache(key_arn)
                  ret = {'payload': payload, 'key_alias': key_alias}
              except TokenValidationError:
                  raise
              except (ConnectionError, EndpointConnectionError):
                  logging.exception('Failure connecting to AWS endpoint.')
                  raise TokenValidationError(
                      'Authentication error. Failure connecting to AWS endpoint.'
                  )
              # We don't care what exception is thrown. For paranoia's sake, fail
              # here.
              except Exception:
                  logging.exception('Failed to validate token.')
                  raise TokenValidationError(
                      'Authentication error. General error.'
                  )
          else:
              ret = self.TOKENS[token_key]
          now = datetime.datetime.utcnow()
          try:
              not_before = datetime.datetime.strptime(
                  ret['payload']['not_before'],
                  TIME_FORMAT
              )
              not_after = datetime.datetime.strptime(
                  ret['payload']['not_after'],
                  TIME_FORMAT
              )
          except Exception:
              logging.exception(
                  'Failed to get not_before and not_after from token payload.'
              )
              raise TokenValidationError(
                  'Authentication error. Missing validity.'
              )
          delta = (not_after - not_before).seconds / 60
          if delta > self.auth_token_max_lifetime:
              logging.warning('Token used which exceeds max token lifetime.')
              raise TokenValidationError(
                  'Authentication error. Token lifetime exceeded.'
              )
          if (now < not_before) or (now > not_after):
              logging.warning('Invalid time validity for token.')
              raise TokenValidationError(
                  'Authentication error. Invalid time validity for token.'
              )
          self.TOKENS[token_key] = ret
          return self.TOKENS[token_key]