Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion castle/api/approve_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class APIApproveDevice(object):
@staticmethod
def call(device_token):
return APIRequest().call(CommandsApproveDevice.build(device_token))
return APIRequest().call(CommandsApproveDevice.call(device_token))
2 changes: 1 addition & 1 deletion castle/api/get_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class APIGetDevice(object):
@staticmethod
def call(device_token):
return APIRequest().call(CommandsGetDevice.build(device_token))
return APIRequest().call(CommandsGetDevice.call(device_token))
2 changes: 1 addition & 1 deletion castle/api/get_devices_for_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class APIGetDevicesForUser(object):
@staticmethod
def call(user_id):
return APIRequest().call(CommandsGetDevicesForUser.build(user_id))
return APIRequest().call(CommandsGetDevicesForUser.call(user_id))
2 changes: 1 addition & 1 deletion castle/api/report_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class APIReportDevice(object):
@staticmethod
def call(device_token):
return APIRequest().call(CommandsReportDevice.build(device_token))
return APIRequest().call(CommandsReportDevice.call(device_token))
2 changes: 1 addition & 1 deletion castle/api/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
class APIReview(object):
@staticmethod
def call(review_id):
return APIRequest().call(CommandsReview.build(review_id))
return APIRequest().call(CommandsReview.call(review_id))
20 changes: 14 additions & 6 deletions castle/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
from castle.context.merge import ContextMerge
from castle.commands.authenticate import CommandsAuthenticate
from castle.commands.identify import CommandsIdentify
from castle.commands.impersonate import CommandsImpersonate
from castle.commands.start_impersonation import CommandsStartImpersonation
from castle.commands.end_impersonation import CommandsEndImpersonation
from castle.commands.track import CommandsTrack
from castle.errors import InternalServerError, RequestError, ImpersonationFailed
from castle.failover.prepare_response import FailoverPrepareResponse
Expand Down Expand Up @@ -65,7 +66,7 @@ def _add_timestamp_if_necessary(self, options):
def authenticate(self, options):
if self.tracked():
self._add_timestamp_if_necessary(options)
command = CommandsAuthenticate(self.context).build(options)
command = CommandsAuthenticate(self.context).call(options)
try:
response = self.api.call(command)
response.update(failover=False, failover_reason=None)
Expand All @@ -83,11 +84,18 @@ def identify(self, options):
if not self.tracked():
return None
self._add_timestamp_if_necessary(options)
return self.api.call(CommandsIdentify(self.context).build(options))
return self.api.call(CommandsIdentify(self.context).call(options))

def impersonate(self, options):
def start_impersonation(self, options):
self._add_timestamp_if_necessary(options)
response = self.api.call(CommandsImpersonate(self.context).build(options))
response = self.api.call(CommandsStartImpersonation(self.context).call(options))
if not response.get('success'):
raise ImpersonationFailed
return response

def end_impersonation(self, options):
self._add_timestamp_if_necessary(options)
response = self.api.call(CommandsEndImpersonation(self.context).call(options))
if not response.get('success'):
raise ImpersonationFailed
return response
Expand All @@ -96,7 +104,7 @@ def track(self, options):
if not self.tracked():
return None
self._add_timestamp_if_necessary(options)
return self.api.call(CommandsTrack(self.context).build(options))
return self.api.call(CommandsTrack(self.context).call(options))

def disable_tracking(self):
self.do_not_track = True
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/approve_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class CommandsApproveDevice(object):

@staticmethod
def build(device_token):
def call(device_token):
ValidatorsPresent.call({'device_token': device_token}, 'device_token')

return Command(
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/authenticate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CommandsAuthenticate(object):
def __init__(self, context):
self.context = context

def build(self, options):
def call(self, options):
ValidatorsPresent.call(options, 'event')
context = ContextMerge.call(self.context, options.get('context'))
context = ContextSanitize.call(context)
Expand Down
23 changes: 23 additions & 0 deletions castle/commands/end_impersonation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from castle.command import Command
from castle.utils.timestamp import UtilsTimestamp as generate_timestamp
from castle.context.merge import ContextMerge
from castle.context.sanitize import ContextSanitize
from castle.validators.present import ValidatorsPresent


class CommandsEndImpersonation(object):
def __init__(self, context):
self.context = context

def call(self, options):
ValidatorsPresent.call(options, 'user_id')

context = ContextMerge.call(self.context, options.get('context'))
context = ContextSanitize.call(context)
ValidatorsPresent.call(context, 'user_agent', 'ip')

if context:
options.update({'context': context})
options.update({'sent_at': generate_timestamp.call()})

return Command(method='delete', path='impersonate', data=options)
2 changes: 1 addition & 1 deletion castle/commands/get_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class CommandsGetDevice(object):

@staticmethod
def build(device_token):
def call(device_token):
ValidatorsPresent.call({'device_token': device_token}, 'device_token')

return Command(
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/get_devices_for_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class CommandsGetDevicesForUser(object):

@staticmethod
def build(user_id):
def call(user_id):
ValidatorsPresent.call({'user_id': user_id}, 'user_id')

return Command(
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CommandsIdentify(object):
def __init__(self, context):
self.context = context

def build(self, options):
def call(self, options):
ValidatorsNotSupported.call(options, 'properties')
context = ContextMerge.call(self.context, options.get('context'))
context = ContextSanitize.call(context)
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/report_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class CommandsReportDevice(object):

@staticmethod
def build(device_token):
def call(device_token):
ValidatorsPresent.call({'device_token': device_token}, 'device_token')

return Command(
Expand Down
2 changes: 1 addition & 1 deletion castle/commands/review.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class CommandsReview(object):

@staticmethod
def build(review_id):
def call(review_id):
ValidatorsPresent.call({'review_id': review_id}, 'review_id')

return Command(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
from castle.validators.present import ValidatorsPresent


class CommandsImpersonate(object):
class CommandsStartImpersonation(object):
def __init__(self, context):
self.context = context

def build(self, options):
def call(self, options):
ValidatorsPresent.call(options, 'user_id')

context = ContextMerge.call(self.context, options.get('context'))
Expand All @@ -20,6 +20,4 @@ def build(self, options):
options.update({'context': context})
options.update({'sent_at': generate_timestamp.call()})

method = ('delete' if options.get('reset', False) else 'post')

return Command(method=method, path='impersonate', data=options)
return Command(method='post', path='impersonate', data=options)
2 changes: 1 addition & 1 deletion castle/commands/track.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class CommandsTrack(object):
def __init__(self, context):
self.context = context

def build(self, options):
def call(self, options):
ValidatorsPresent.call(options, 'event')
context = ContextMerge.call(self.context, options.get('context'))
context = ContextSanitize.call(context)
Expand Down
3 changes: 2 additions & 1 deletion castle/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
'castle.test.command_test',
'castle.test.commands.approve_device_test',
'castle.test.commands.authenticate_test',
'castle.test.commands.end_impersonation_test',
'castle.test.commands.get_device_test',
'castle.test.commands.get_devices_for_user_test',
'castle.test.commands.identify_test',
'castle.test.commands.impersonate_test',
'castle.test.commands.report_device_test',
'castle.test.commands.review_test',
'castle.test.commands.start_impersonation_test',
'castle.test.commands.track_test',
'castle.test.configuration_test',
'castle.test.context.get_default_test',
Expand Down
35 changes: 31 additions & 4 deletions castle/test/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def test_init(self):
self.assertIsInstance(client.api, APIRequest)

@responses.activate
def test_impersonate(self):
def test_start_impersonation(self):
response_text = {'success': True}
responses.add(
responses.POST,
Expand All @@ -62,10 +62,23 @@ def test_impersonate(self):
)
client = Client.from_request(request(), {})
options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'}
self.assertEqual(client.impersonate(options), response_text)
self.assertEqual(client.start_impersonation(options), response_text)

@responses.activate
def test_impersonate_failed(self):
def test_end_impersonation(self):
response_text = {'success': True}
responses.add(
responses.DELETE,
'https://api.castle.io/v1/impersonate',
json=response_text,
status=200
)
client = Client.from_request(request(), {})
options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'}
self.assertEqual(client.end_impersonation(options), response_text)

@responses.activate
def test_start_impersonation_failed(self):
response_text = {}
responses.add(
responses.POST,
Expand All @@ -76,7 +89,21 @@ def test_impersonate_failed(self):
client = Client.from_request(request(), {})
options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'}
with self.assertRaises(ImpersonationFailed):
client.impersonate(options)
client.start_impersonation(options)

@responses.activate
def test_end_impersonation_failed(self):
response_text = {}
responses.add(
responses.DELETE,
'https://api.castle.io/v1/impersonate',
json=response_text,
status=200
)
client = Client.from_request(request(), {})
options = {'properties': {'impersonator': 'admin'}, 'user_id': '1234'}
with self.assertRaises(ImpersonationFailed):
client.end_impersonation(options)

@responses.activate
def test_identify_tracked_true(self):
Expand Down
8 changes: 4 additions & 4 deletions castle/test/commands/approve_device_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ def device_token():


class CommandsApproveDeviceTestCase(unittest.TestCase):
def test_build_no_device_token(self):
def test_call_no_device_token(self):
with self.assertRaises(InvalidParametersError):
CommandsApproveDevice.build('')
CommandsApproveDevice.call('')

def test_build(self):
command = CommandsApproveDevice.build(device_token())
def test_call(self):
command = CommandsApproveDevice.call(device_token())
self.assertIsInstance(command, Command)
self.assertEqual(command.method, 'put')
self.assertEqual(command.path, 'devices/1234/approve')
Expand Down
24 changes: 12 additions & 12 deletions castle/test/commands/authenticate_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_init(self):
obj = CommandsAuthenticate(context)
self.assertEqual(obj.context, context)

def test_build(self):
def test_call(self):
context = {'test': '1'}
options = default_options_plus(context={'spam': True})

Expand All @@ -51,46 +51,46 @@ def test_build(self):
expected = default_command_with_data(**expected_data)

self.assertEqual(CommandsAuthenticate(
context).build(options), expected)
context).call(options), expected)

def test_build_no_event(self):
def test_call_no_event(self):
context = {}
options = default_options()
options.pop('event')

with self.assertRaises(InvalidParametersError):
CommandsAuthenticate(context).build(options)
CommandsAuthenticate(context).call(options)

def test_build_no_user_id(self):
def test_call_no_user_id(self):
context = {}
options = default_options()
options.pop('user_id')

expected = default_command_with_data(**options)

self.assertEqual(CommandsAuthenticate(context).build(options), expected)
self.assertEqual(CommandsAuthenticate(context).call(options), expected)

def test_build_properties_allowed(self):
def test_call_properties_allowed(self):
context = {}
options = default_options_plus(properties={'test': '1'})
options.update({'context': context})

expected = default_command_with_data(**options)

self.assertEqual(CommandsAuthenticate(
context).build(options), expected)
context).call(options), expected)

def test_build_user_traits_allowed(self):
def test_call_user_traits_allowed(self):
context = {}
options = default_options_plus(user_traits={'email': 'a@b.com'})
options.update({'context': context})

expected = default_command_with_data(**options)

self.assertEqual(CommandsAuthenticate(
context).build(options), expected)
context).call(options), expected)

def test_build_risk_policy_allowed(self):
def test_call_risk_policy_allowed(self):
context = {}
risk_policy = {
'id': 'q-rbeMzBTdW2Fd09sbz55A',
Expand All @@ -102,4 +102,4 @@ def test_build_risk_policy_allowed(self):
options = default_options_plus(risk_policy=risk_policy)
expected = default_command_with_data(**options)
self.assertEqual(CommandsAuthenticate(
context).build(options), expected)
context).call(options), expected)
Loading