Changed directory name.
This commit is contained in:
126
src/saml2test/__init__.py
Normal file
126
src/saml2test/__init__.py
Normal file
@@ -0,0 +1,126 @@
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from saml2test.check import CRITICAL
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
|
||||
class FatalError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CheckError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class HTTP_ERROR(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Unknown(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# class Trace(object):
|
||||
# def __init__(self):
|
||||
# self.trace = []
|
||||
# self.start = time.time()
|
||||
#
|
||||
# def request(self, msg):
|
||||
# delta = time.time() - self.start
|
||||
# self.trace.append("%f --> %s" % (delta, msg))
|
||||
#
|
||||
# def reply(self, msg):
|
||||
# delta = time.time() - self.start
|
||||
# self.trace.append("%f <-- %s" % (delta, msg))
|
||||
#
|
||||
# def info(self, msg, who="saml2client"):
|
||||
# delta = time.time() - self.start
|
||||
# self.trace.append("%f - INFO - [%s] %s" % (delta, who, msg))
|
||||
#
|
||||
# def error(self, msg, who="saml2client"):
|
||||
# delta = time.time() - self.start
|
||||
# self.trace.append("%f - ERROR - [%s] %s" % (delta, who, msg))
|
||||
#
|
||||
# def warning(self, msg, who="saml2client"):
|
||||
# delta = time.time() - self.start
|
||||
# self.trace.append("%f - WARNING - [%s] %s" % (delta, who, msg))
|
||||
#
|
||||
# def __str__(self):
|
||||
# return "\n". join([t.encode("utf-8") for t in self.trace])
|
||||
#
|
||||
# def clear(self):
|
||||
# self.trace = []
|
||||
#
|
||||
# def __getitem__(self, item):
|
||||
# return self.trace[item]
|
||||
#
|
||||
# def next(self):
|
||||
# for line in self.trace:
|
||||
# yield line
|
||||
|
||||
|
||||
class ContextFilter(logging.Filter):
|
||||
"""
|
||||
This is a filter which injects time laps information into the log.
|
||||
"""
|
||||
|
||||
def start(self):
|
||||
self.start = time.time()
|
||||
|
||||
def filter(self, record):
|
||||
record.delta = time.time() - self.start
|
||||
return True
|
||||
|
||||
|
||||
def start_script(path, *args):
|
||||
popen_args = [path]
|
||||
popen_args.extend(args)
|
||||
return Popen(popen_args, stdout=PIPE, stderr=PIPE)
|
||||
|
||||
|
||||
def stop_script_by_name(name):
|
||||
import subprocess
|
||||
import signal
|
||||
import os
|
||||
|
||||
p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
|
||||
for line in out.splitlines():
|
||||
if name in line:
|
||||
pid = int(line.split(None, 1)[0])
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
|
||||
def stop_script_by_pid(pid):
|
||||
import signal
|
||||
import os
|
||||
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
|
||||
def get_page(url):
|
||||
resp = requests.get(url)
|
||||
if resp.status_code == 200:
|
||||
return resp.text
|
||||
else:
|
||||
raise HTTP_ERROR(resp.status)
|
||||
|
||||
|
||||
def exception_trace(tag, exc, log=None):
|
||||
message = traceback.format_exception(*sys.exc_info())
|
||||
|
||||
try:
|
||||
_exc = "Exception: %s" % exc
|
||||
except UnicodeEncodeError:
|
||||
_exc = "Exception: %s" % exc.message.encode("utf-8", "replace")
|
||||
|
||||
return {"status": CRITICAL, "message": _exc, "content": "".join(message)}
|
||||
@@ -98,6 +98,7 @@ class Interaction(object):
|
||||
def __init__(self, httpc, interactions=None):
|
||||
self.httpc = httpc
|
||||
self.interactions = interactions
|
||||
self.who = "Form process"
|
||||
|
||||
def pick_interaction(self, _base="", content="", req=None):
|
||||
unic = content
|
||||
@@ -135,6 +136,7 @@ class Interaction(object):
|
||||
_match += 1
|
||||
|
||||
if _match == len(interaction["matches"]):
|
||||
logger.info("Matched: %s" % interaction["matches"])
|
||||
return interaction
|
||||
|
||||
raise InteractionNeeded("No interaction matched")
|
||||
@@ -146,6 +148,7 @@ class Interaction(object):
|
||||
:param response: A HTTP request response. A DResponse instance
|
||||
:param content: The HTTP response content
|
||||
:param url: The url the request was sent to
|
||||
:param kwargs: Extra key word arguments
|
||||
:return: The picked form or None of no form matched the criteria.
|
||||
"""
|
||||
|
||||
@@ -253,6 +256,7 @@ class Interaction(object):
|
||||
:param orig_response: The original response (as returned by requests)
|
||||
:return: The response do_click() returns
|
||||
"""
|
||||
logger.info("select_form")
|
||||
response = RResponse(orig_response)
|
||||
try:
|
||||
_url = response.url
|
||||
@@ -300,11 +304,6 @@ class Interaction(object):
|
||||
:return: The response do_click() returns
|
||||
"""
|
||||
|
||||
try:
|
||||
_trace = kwargs["trace"]
|
||||
except KeyError:
|
||||
_trace = False
|
||||
|
||||
if not path.startswith("http"):
|
||||
try:
|
||||
_url = orig_response.url
|
||||
@@ -316,7 +315,8 @@ class Interaction(object):
|
||||
else:
|
||||
url = path
|
||||
|
||||
return self.httpc.send(url, "GET", trace=_trace)
|
||||
logger.info("GET %s" % url)
|
||||
return self.httpc.send(url, "GET")
|
||||
#return resp, ""
|
||||
|
||||
def post_form(self, orig_response, **kwargs):
|
||||
@@ -375,8 +375,7 @@ class Action(object):
|
||||
def post_op(self, result, conv, args):
|
||||
pass
|
||||
|
||||
def __call__(self, httpc, conv, trace, location, response, content,
|
||||
features):
|
||||
def __call__(self, httpc, conv, location, response, content, features):
|
||||
intact = Interaction(httpc)
|
||||
function = intact.interaction(self.args)
|
||||
|
||||
@@ -385,12 +384,10 @@ class Action(object):
|
||||
except (KeyError, AttributeError):
|
||||
_args = {}
|
||||
|
||||
_args.update({"_trace_": trace, "location": location,
|
||||
"features": features, "conv": conv})
|
||||
_args.update({"location": location, "features": features, "conv": conv})
|
||||
|
||||
if trace:
|
||||
trace.reply("FUNCTION: %s" % function.__name__)
|
||||
trace.reply("ARGS: %s" % _args)
|
||||
logger.info("<-- FUNCTION: %s" % function.__name__)
|
||||
logger.info("<-- ARGS: %s" % _args)
|
||||
|
||||
result = function(response, **_args)
|
||||
self.post_op(result, conv, _args)
|
||||
@@ -1,5 +1,4 @@
|
||||
__author__ = 'rohe0002'
|
||||
|
||||
import logging
|
||||
import json
|
||||
|
||||
from urlparse import urlparse
|
||||
@@ -8,6 +7,10 @@ from mechanize import ParseResponseEx
|
||||
from mechanize._form import ControlNotFoundError, AmbiguityError
|
||||
from mechanize._form import ListControl
|
||||
|
||||
__author__ = 'rohe0002'
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FlowException(Exception):
|
||||
def __init__(self, function="", content="", url=""):
|
||||
@@ -88,16 +91,15 @@ class DResponse():
|
||||
self._len = len(message)
|
||||
|
||||
|
||||
def do_request(client, url, method, body="", headers=None, trace=False):
|
||||
def do_request(client, url, method, body="", headers=None):
|
||||
"""
|
||||
Sends a HTTP request. It handles trace logging if asked for
|
||||
Sends a HTTP request.
|
||||
|
||||
:param client: The client instance
|
||||
:param url: Where to send the request
|
||||
:param method: The HTTP method to use for the request
|
||||
:param body: The request body
|
||||
:param headers: The requset headers
|
||||
:param trace: A class instance to use for trace logging
|
||||
:return: A tuple of
|
||||
url - the url the request was sent to
|
||||
response - the response to the request
|
||||
@@ -106,19 +108,17 @@ def do_request(client, url, method, body="", headers=None, trace=False):
|
||||
if headers is None:
|
||||
headers = {}
|
||||
|
||||
if trace:
|
||||
trace.request("URL: %s" % url)
|
||||
trace.request("BODY: %s" % body)
|
||||
trace.request("Headers: %s" % (headers,))
|
||||
logger.info("--> URL: %s" % url)
|
||||
logger.info("--> BODY: %s" % body)
|
||||
logger.info("--> Headers: %s" % (headers,))
|
||||
|
||||
response = client.http_request(url, method=method, data=body,
|
||||
headers=headers)
|
||||
|
||||
if trace:
|
||||
trace.reply("RESPONSE: %s" % response)
|
||||
trace.reply("CONTENT: %s" % response.text)
|
||||
if response.cookies:
|
||||
trace.reply("COOKIES: %s" % response.cookies)
|
||||
logger.info("<-- RESPONSE: %s" % response)
|
||||
logger.info("<-- CONTENT: %s" % response.text)
|
||||
if response.cookies:
|
||||
logger.info("<-- COOKIES: %s" % response.cookies)
|
||||
|
||||
return url, response, response.text
|
||||
|
||||
@@ -223,15 +223,11 @@ def do_click(client, form, **kwargs):
|
||||
headers[key] = val
|
||||
|
||||
url = request._Request__original
|
||||
try:
|
||||
_trace = kwargs["_trace_"]
|
||||
except KeyError:
|
||||
_trace = False
|
||||
|
||||
if form.method == "POST":
|
||||
return do_request(client, url, "POST", request.data, headers, _trace)
|
||||
return do_request(client, url, "POST", request.data, headers)
|
||||
else:
|
||||
return do_request(client, url, "GET", headers=headers, trace=_trace)
|
||||
return do_request(client, url, "GET", headers=headers)
|
||||
|
||||
|
||||
def select_form(client, orig_response, content, **kwargs):
|
||||
@@ -293,11 +289,6 @@ def chose(client, orig_response, content, path, **kwargs):
|
||||
:return: The response do_click() returns
|
||||
"""
|
||||
|
||||
try:
|
||||
_trace = kwargs["trace"]
|
||||
except KeyError:
|
||||
_trace = False
|
||||
|
||||
if not path.startswith("http"):
|
||||
try:
|
||||
_url = orig_response.url
|
||||
@@ -309,8 +300,7 @@ def chose(client, orig_response, content, path, **kwargs):
|
||||
else:
|
||||
url = path
|
||||
|
||||
return do_request(client, url, "GET", trace=_trace)
|
||||
#return resp, ""
|
||||
return do_request(client, url, "GET")
|
||||
|
||||
|
||||
def post_form(client, orig_response, content, **kwargs):
|
||||
@@ -357,7 +347,6 @@ class Operation(object):
|
||||
self.args = args or {}
|
||||
self.request = None
|
||||
self.conv = conv
|
||||
self.trace = conv.trace
|
||||
self.features = features
|
||||
self.cconf = conv.client_config
|
||||
|
||||
@@ -376,8 +365,8 @@ class Operation(object):
|
||||
|
||||
_args["location"] = location
|
||||
|
||||
self.trace.reply("FUNCTION: %s" % self.function.__name__)
|
||||
self.trace.reply("ARGS: %s" % (_args,))
|
||||
logger.info("--> FUNCTION: %s" % self.function.__name__)
|
||||
logger.info("--> ARGS: %s" % (_args,))
|
||||
|
||||
result = self.function(self.conv.client, response, content, **_args)
|
||||
self.post_op(result, self.conv, _args)
|
||||
@@ -4,14 +4,14 @@ import traceback
|
||||
import logging
|
||||
from urlparse import parse_qs
|
||||
|
||||
from srtest.opfunc import Operation
|
||||
from srtest import FatalError
|
||||
from srtest.check import ExpectedError
|
||||
from srtest.check import INTERACTION
|
||||
from srtest.interaction import Interaction
|
||||
from srtest.interaction import Action
|
||||
from srtest.interaction import InteractionNeeded
|
||||
from srtest.status import STATUSCODE
|
||||
from saml2test.opfunc import Operation
|
||||
from saml2test import FatalError
|
||||
from saml2test.check import ExpectedError
|
||||
from saml2test.check import INTERACTION
|
||||
from saml2test.interaction import Interaction
|
||||
from saml2test.interaction import Action
|
||||
from saml2test.interaction import InteractionNeeded
|
||||
from saml2test.status import STATUSCODE
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
@@ -24,12 +24,11 @@ class Conversation(object):
|
||||
:ivar protocol_response: List of the received protocol messages
|
||||
"""
|
||||
|
||||
def __init__(self, client, config, trace, interaction,
|
||||
def __init__(self, client, config, interaction,
|
||||
check_factory=None, msg_factory=None,
|
||||
features=None, verbose=False, expect_exception=None):
|
||||
self.client = client
|
||||
self.client_config = config
|
||||
self.trace = trace
|
||||
self.test_output = []
|
||||
self.features = features
|
||||
self.verbose = verbose
|
||||
@@ -50,14 +49,14 @@ class Conversation(object):
|
||||
|
||||
def check_severity(self, stat):
|
||||
if stat["status"] >= 4:
|
||||
self.trace.error("WHERE: %s" % stat["id"])
|
||||
self.trace.error("STATUS:%s" % STATUSCODE[stat["status"]])
|
||||
logger.error("WHERE: %s" % stat["id"])
|
||||
logger.error("STATUS:%s" % STATUSCODE[stat["status"]])
|
||||
try:
|
||||
self.trace.error("HTTP STATUS: %s" % stat["http_status"])
|
||||
logger.error("HTTP STATUS: %s" % stat["http_status"])
|
||||
except KeyError:
|
||||
pass
|
||||
try:
|
||||
self.trace.error("INFO: %s" % stat["message"])
|
||||
logger.error("INFO: %s" % stat["message"])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
@@ -118,8 +117,8 @@ class Conversation(object):
|
||||
raise FatalError(
|
||||
"Too long sequence of redirects: %s" % rdseq)
|
||||
|
||||
self.trace.reply("REDIRECT TO: %s" % url)
|
||||
logger.debug("REDIRECT TO: %s" % url)
|
||||
logger.info("HTTP %d Location: %s" % (_response.status_code,
|
||||
url))
|
||||
# If back to me
|
||||
for_me = False
|
||||
for redirect_uri in self.my_endpoints():
|
||||
@@ -142,12 +141,13 @@ class Conversation(object):
|
||||
break
|
||||
else:
|
||||
try:
|
||||
logger.info("GET %s" % url)
|
||||
_response = self.client.send(url, "GET")
|
||||
except Exception, err:
|
||||
raise FatalError("%s" % err)
|
||||
|
||||
content = _response.text
|
||||
self.trace.reply("CONTENT: %s" % content)
|
||||
logger.info("<-- CONTENT: %s" % content)
|
||||
self.position = url
|
||||
self.last_content = content
|
||||
self.response = _response
|
||||
@@ -165,11 +165,11 @@ class Conversation(object):
|
||||
_spec = self.interaction.pick_interaction(_base, content)
|
||||
except InteractionNeeded:
|
||||
self.position = url
|
||||
self.trace.error("Page Content: %s" % content)
|
||||
logger.error("Page Content: %s" % content)
|
||||
raise
|
||||
except KeyError:
|
||||
self.position = url
|
||||
self.trace.error("Page Content: %s" % content)
|
||||
logger.error("Page Content: %s" % content)
|
||||
self.err_check("interaction-needed")
|
||||
|
||||
if _spec == _last_action:
|
||||
@@ -180,15 +180,15 @@ class Conversation(object):
|
||||
_last_action = _spec
|
||||
|
||||
if len(_spec) > 2:
|
||||
self.trace.info(">> %s <<" % _spec["page-type"])
|
||||
logger.info(">> %s <<" % _spec["page-type"])
|
||||
if _spec["page-type"] == "login":
|
||||
self.login_page = content
|
||||
|
||||
_op = Action(_spec["control"])
|
||||
|
||||
try:
|
||||
_response = _op(self.client, self, self.trace, url,
|
||||
_response, content, self.features)
|
||||
_response = _op(self.client, self, url, _response, content,
|
||||
self.features)
|
||||
if isinstance(_response, dict):
|
||||
self.last_response = _response
|
||||
self.last_content = _response
|
||||
@@ -1,113 +0,0 @@
|
||||
import logging
|
||||
import time
|
||||
import traceback
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
from srtest.check import CRITICAL
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__author__ = 'rolandh'
|
||||
|
||||
|
||||
class FatalError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class CheckError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class HTTP_ERROR(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Unknown(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class Trace(object):
|
||||
def __init__(self):
|
||||
self.trace = []
|
||||
self.start = time.time()
|
||||
|
||||
def request(self, msg):
|
||||
delta = time.time() - self.start
|
||||
self.trace.append("%f --> %s" % (delta, msg))
|
||||
|
||||
def reply(self, msg):
|
||||
delta = time.time() - self.start
|
||||
self.trace.append("%f <-- %s" % (delta, msg))
|
||||
|
||||
def info(self, msg):
|
||||
delta = time.time() - self.start
|
||||
self.trace.append("%f %s" % (delta, msg))
|
||||
|
||||
def error(self, msg):
|
||||
delta = time.time() - self.start
|
||||
self.trace.append("%f [ERROR] %s" % (delta, msg))
|
||||
|
||||
def warning(self, msg):
|
||||
delta = time.time() - self.start
|
||||
self.trace.append("%f [WARNING] %s" % (delta, msg))
|
||||
|
||||
def __str__(self):
|
||||
return "\n". join([t.encode("utf-8") for t in self.trace])
|
||||
|
||||
def clear(self):
|
||||
self.trace = []
|
||||
|
||||
def __getitem__(self, item):
|
||||
return self.trace[item]
|
||||
|
||||
def next(self):
|
||||
for line in self.trace:
|
||||
yield line
|
||||
|
||||
|
||||
def start_script(path, *args):
|
||||
popen_args = [path]
|
||||
popen_args.extend(args)
|
||||
return Popen(popen_args, stdout=PIPE, stderr=PIPE)
|
||||
|
||||
|
||||
def stop_script_by_name(name):
|
||||
import subprocess
|
||||
import signal
|
||||
import os
|
||||
|
||||
p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE)
|
||||
out, err = p.communicate()
|
||||
|
||||
for line in out.splitlines():
|
||||
if name in line:
|
||||
pid = int(line.split(None, 1)[0])
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
|
||||
def stop_script_by_pid(pid):
|
||||
import signal
|
||||
import os
|
||||
|
||||
os.kill(pid, signal.SIGKILL)
|
||||
|
||||
|
||||
def get_page(url):
|
||||
resp = requests.get(url)
|
||||
if resp.status_code == 200:
|
||||
return resp.text
|
||||
else:
|
||||
raise HTTP_ERROR(resp.status)
|
||||
|
||||
|
||||
def exception_trace(tag, exc, log=None):
|
||||
message = traceback.format_exception(*sys.exc_info())
|
||||
|
||||
try:
|
||||
_exc = "Exception: %s" % exc
|
||||
except UnicodeEncodeError:
|
||||
_exc = "Exception: %s" % exc.message.encode("utf-8", "replace")
|
||||
|
||||
return {"status": CRITICAL, "message": _exc, "content": "".join(message)}
|
||||
Reference in New Issue
Block a user