| 1 |
"""
|
| 2 |
Relativity REST Auth Tester
|
| 3 |
Tests basic authentication against a Relativity Server instance.
|
| 4 |
Run this standalone - no other dependencies beyond 'requests'.
|
| 5 |
"""
|
| 6 |
|
| 7 |
import requests
|
| 8 |
import json
|
| 9 |
|
| 10 |
# --- Configuration ---
|
| 11 |
## ROOT_SITE = "https://your-provider-instance.com" # e.g. https://review.lighthouse.com
|
| 12 |
ROOT_SITE = "https://your-provider-instance.com" # e.g. https://review.lighthouse.com
|
| 13 |
## USERNAME = "your.email@lawfirm.com"
|
| 14 |
USERNAME = "your.email@lawfirm.com"
|
| 15 |
## PASSWORD = "yourpassword"
|
| 16 |
PASSWORD = "yourpassword"
|
| 17 |
# ---------------------
|
| 18 |
|
| 19 |
def test_auth(root_site, username, password):
|
| 20 |
"""
|
| 21 |
Attempts three increasingly specific calls to determine
|
| 22 |
whether auth is working and what API surface is available.
|
| 23 |
"""
|
| 24 |
auth = requests.auth.HTTPBasicAuth(username, password)
|
| 25 |
headers = {"X-CSRF-Header": "", "Content-Type": "application/json"}
|
| 26 |
|
| 27 |
results = {}
|
| 28 |
|
| 29 |
# --- Test 1: Legacy workspace list (your original endpoint) ---
|
| 30 |
# If this works, the old-style API is still live on this instance.
|
| 31 |
url1 = f"{root_site}/Relativity.REST/Relativity/Workspace"
|
| 32 |
try:
|
| 33 |
r1 = requests.get(url1, auth=auth, headers=headers, timeout=15)
|
| 34 |
results["legacy_workspace_list"] = {
|
| 35 |
"status_code": r1.status_code,
|
| 36 |
"success": r1.status_code == 200
|
| 37 |
}
|
| 38 |
if r1.status_code == 200:
|
| 39 |
data = r1.json()
|
| 40 |
count = len(data.get("Results", []))
|
| 41 |
results["legacy_workspace_list"]["workspace_count"] = count
|
| 42 |
except Exception as e:
|
| 43 |
results["legacy_workspace_list"] = {"error": str(e)}
|
| 44 |
|
| 45 |
# --- Test 2: Current Object Manager workspace query ---
|
| 46 |
# This is the modern endpoint you'd use in a rebuilt library.
|
| 47 |
url2 = f"{root_site}/Relativity.REST/api/Relativity.Objects/workspace/-1/object/query"
|
| 48 |
payload = {
|
| 49 |
"request": {
|
| 50 |
"objectType": {"artifactTypeID": 8}, # 8 = Workspace
|
| 51 |
"fields": [{"Name": "Name"}],
|
| 52 |
"rowCondition": ""
|
| 53 |
},
|
| 54 |
"start": 1,
|
| 55 |
"length": 5
|
| 56 |
}
|
| 57 |
try:
|
| 58 |
r2 = requests.post(url2, auth=auth, headers=headers,
|
| 59 |
data=json.dumps(payload), timeout=15)
|
| 60 |
results["object_manager_workspace_query"] = {
|
| 61 |
"status_code": r2.status_code,
|
| 62 |
"success": r2.status_code == 200
|
| 63 |
}
|
| 64 |
if r2.status_code == 200:
|
| 65 |
data = r2.json()
|
| 66 |
results["object_manager_workspace_query"]["total_count"] = data.get("TotalCount", "N/A")
|
| 67 |
except Exception as e:
|
| 68 |
results["object_manager_workspace_query"] = {"error": str(e)}
|
| 69 |
|
| 70 |
# --- Test 3: Saved search execution (the actual target endpoint) ---
|
| 71 |
# Using workspace -1 and a dummy search ID just to see what auth gives us.
|
| 72 |
# A 401 = bad auth. A 404 or 400 = auth worked, endpoint exists but params are wrong (expected).
|
| 73 |
url3 = f"{root_site}/Relativity.REST/api/Relativity.Objects/workspace/-1/object/query"
|
| 74 |
payload3 = {
|
| 75 |
"request": {
|
| 76 |
"objectType": {"artifactTypeID": 10}, # 10 = Document
|
| 77 |
"fields": [],
|
| 78 |
"rowCondition": "",
|
| 79 |
"searchProviderCondition": {
|
| 80 |
"savedSearchArtifactID": 0 # dummy ID - just testing auth/endpoint
|
| 81 |
}
|
| 82 |
},
|
| 83 |
"start": 1,
|
| 84 |
"length": 1
|
| 85 |
}
|
| 86 |
try:
|
| 87 |
r3 = requests.post(url3, auth=auth, headers=headers,
|
| 88 |
data=json.dumps(payload3), timeout=15)
|
| 89 |
results["saved_search_endpoint"] = {
|
| 90 |
"status_code": r3.status_code,
|
| 91 |
# 401 = auth failed, 400/404 = auth ok but bad params (fine for a test)
|
| 92 |
"auth_appears_valid": r3.status_code != 401
|
| 93 |
}
|
| 94 |
except Exception as e:
|
| 95 |
results["saved_search_endpoint"] = {"error": str(e)}
|
| 96 |
|
| 97 |
return results
|
| 98 |
|
| 99 |
|
| 100 |
if __name__ == "__main__":
|
| 101 |
print(f"\nTesting: {ROOT_SITE}")
|
| 102 |
print("-" * 50)
|
| 103 |
results = test_auth(ROOT_SITE, USERNAME, PASSWORD)
|
| 104 |
for test_name, result in results.items():
|
| 105 |
print(f"\n[{test_name}]")
|
| 106 |
for k, v in result.items():
|
| 107 |
print(f" {k}: {v}") |