#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Copyright 2018-2023 Mike Fährmann # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. import os import sys import unittest from unittest.mock import patch sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from gallery_dl import oauth, text # noqa E402 TESTSERVER = "http://term.ie/oauth/example" CONSUMER_KEY = "key" CONSUMER_SECRET = "secret" REQUEST_TOKEN = "requestkey" REQUEST_TOKEN_SECRET = "requestsecret" ACCESS_TOKEN = "accesskey" ACCESS_TOKEN_SECRET = "accesssecret" class TestOAuthSession(unittest.TestCase): def test_concat(self): concat = oauth.concat self.assertEqual(concat(), "") self.assertEqual(concat("str"), "str") self.assertEqual(concat("str1", "str2"), "str1&str2") self.assertEqual(concat("&", "?/"), "%26&%3F%2F") self.assertEqual( concat("GET", "http://example.org/", "foo=bar&baz=a"), "GET&http%3A%2F%2Fexample.org%2F&foo%3Dbar%26baz%3Da" ) def test_nonce(self, size=16): nonce_values = set(oauth.nonce(size) for _ in range(size)) # uniqueness self.assertEqual(len(nonce_values), size) # length for nonce in nonce_values: self.assertEqual(len(nonce), size) def test_quote(self): quote = oauth.quote reserved = ",;:!\"§$%&/(){}[]=?`´+*'äöü" unreserved = ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789-._~") for char in unreserved: self.assertEqual(quote(char), char) for char in reserved: quoted = quote(char) quoted_hex = quoted.replace("%", "") self.assertTrue(quoted.startswith("%")) self.assertTrue(len(quoted) >= 3) self.assertEqual(quoted_hex.upper(), quoted_hex) def test_generate_signature(self): client = oauth.OAuth1Client( CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) request = MockRequest() params = [] self.assertEqual( client.generate_signature(request, params), "Wt2xo49dM5pkL4gsnCakNdHaVUo%3D") request = MockRequest("https://example.org/") params = [("hello", "world"), ("foo", "bar")] self.assertEqual( client.generate_signature(request, params), "ay2269%2F8uKpZqKJR1doTtpv%2Bzn0%3D") request = MockRequest("https://example.org/index.html" "?hello=world&foo=bar", method="POST") params = [("oauth_signature_method", "HMAC-SHA1")] self.assertEqual( client.generate_signature(request, params), "yVZWb1ts4smdMmXxMlhaXrkoOng%3D") def test_dunder_call(self): client = oauth.OAuth1Client( CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) request = MockRequest("https://example.org/") with patch("time.time") as tmock, \ patch("gallery_dl.oauth.nonce") as nmock: tmock.return_value = 123456789.123 nmock.return_value = "abcdefghijklmno" client(request) self.assertEqual( request.headers["Authorization"], """OAuth \ oauth_consumer_key="key",\ oauth_nonce="abcdefghijklmno",\ oauth_signature_method="HMAC-SHA1",\ oauth_timestamp="123456789",\ oauth_version="1.0",\ oauth_token="accesskey",\ oauth_signature="DjtTk5j5P3BDZFnstZ%2FtEYcwD6c%3D"\ """) def test_request_token(self): response = self._oauth_request( "/request_token.php", {}) expected = "oauth_token=requestkey&oauth_token_secret=requestsecret" self.assertEqual(response, expected, msg=response) data = text.parse_query(response) self.assertTrue(data["oauth_token"], REQUEST_TOKEN) self.assertTrue(data["oauth_token_secret"], REQUEST_TOKEN_SECRET) def test_access_token(self): response = self._oauth_request( "/access_token.php", {}, REQUEST_TOKEN, REQUEST_TOKEN_SECRET) expected = "oauth_token=accesskey&oauth_token_secret=accesssecret" self.assertEqual(response, expected, msg=response) data = text.parse_query(response) self.assertTrue(data["oauth_token"], ACCESS_TOKEN) self.assertTrue(data["oauth_token_secret"], ACCESS_TOKEN_SECRET) def test_authenticated_call(self): params = {"method": "foo", "a": "äöüß/?&#", "äöüß/?&#": "a"} response = self._oauth_request( "/echo_api.php", params, ACCESS_TOKEN, ACCESS_TOKEN_SECRET) self.assertEqual(text.parse_query(response), params) def _oauth_request(self, endpoint, params=None, oauth_token=None, oauth_token_secret=None): # the test server at 'term.ie' is unreachable raise unittest.SkipTest() session = oauth.OAuth1Session( CONSUMER_KEY, CONSUMER_SECRET, oauth_token, oauth_token_secret, ) try: response = session.get(TESTSERVER + endpoint, params=params) response.raise_for_status() return response.text except OSError: raise unittest.SkipTest() class MockRequest(): def __init__(self, url="", method="GET"): self.url = url self.method = method self.headers = {} if __name__ == "__main__": unittest.main(warnings="ignore")