Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Merge pull request #938 from matrix-org/rav/add_device_id_to_client_ips
Browse files Browse the repository at this point in the history
Record device_id in client_ips
  • Loading branch information
richvdh authored Jul 20, 2016
2 parents d36b1d8 + ec041b3 commit e9e3eaa
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 8 deletions.
29 changes: 23 additions & 6 deletions synapse/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,10 @@ def get_user_by_req(self, request, allow_guest=False, rights="access"):
token_id = user_info["token_id"]
is_guest = user_info["is_guest"]

# device_id may not be present if get_user_by_access_token has been
# stubbed out.
device_id = user_info.get("device_id")

ip_addr = self.hs.get_ip_from_request(request)
user_agent = request.requestHeaders.getRawHeaders(
"User-Agent",
Expand All @@ -597,7 +601,8 @@ def get_user_by_req(self, request, allow_guest=False, rights="access"):
user=user,
access_token=access_token,
ip=ip_addr,
user_agent=user_agent
user_agent=user_agent,
device_id=device_id,
)

if is_guest and not allow_guest:
Expand Down Expand Up @@ -695,20 +700,28 @@ def get_user_from_macaroon(self, macaroon_str, rights="access"):
"user": user,
"is_guest": True,
"token_id": None,
"device_id": None,
}
elif rights == "delete_pusher":
# We don't store these tokens in the database
ret = {
"user": user,
"is_guest": False,
"token_id": None,
"device_id": None,
}
else:
# This codepath exists so that we can actually return a
# token ID, because we use token IDs in place of device
# identifiers throughout the codebase.
# TODO(daniel): Remove this fallback when device IDs are
# properly implemented.
# This codepath exists for several reasons:
# * so that we can actually return a token ID, which is used
# in some parts of the schema (where we probably ought to
# use device IDs instead)
# * the only way we currently have to invalidate an
# access_token is by removing it from the database, so we
# have to check here that it is still in the db
# * some attributes (notably device_id) aren't stored in the
# macaroon. They probably should be.
# TODO: build the dictionary from the macaroon once the
# above are fixed
ret = yield self._look_up_user_by_access_token(macaroon_str)
if ret["user"] != user:
logger.error(
Expand Down Expand Up @@ -782,10 +795,14 @@ def _look_up_user_by_access_token(self, token):
self.TOKEN_NOT_FOUND_HTTP_STATUS, "Unrecognised access token.",
errcode=Codes.UNKNOWN_TOKEN
)
# we use ret.get() below because *lots* of unit tests stub out
# get_user_by_access_token in a way where it only returns a couple of
# the fields.
user_info = {
"user": UserID.from_string(ret.get("name")),
"token_id": ret.get("token_id", None),
"is_guest": False,
"device_id": ret.get("device_id"),
}
defer.returnValue(user_info)

Expand Down
3 changes: 2 additions & 1 deletion synapse/storage/client_ips.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def __init__(self, hs):
super(ClientIpStore, self).__init__(hs)

@defer.inlineCallbacks
def insert_client_ip(self, user, access_token, ip, user_agent):
def insert_client_ip(self, user, access_token, ip, user_agent, device_id):
now = int(self._clock.time_msec())
key = (user.to_string(), access_token, ip)

Expand All @@ -59,6 +59,7 @@ def insert_client_ip(self, user, access_token, ip, user_agent):
"access_token": access_token,
"ip": ip,
"user_agent": user_agent,
"device_id": device_id,
},
values={
"last_seen": now,
Expand Down
10 changes: 9 additions & 1 deletion tests/api/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def test_get_user_by_req_user_valid_token(self):
user_info = {
"name": self.test_user,
"token_id": "ditto",
"device_id": "device",
}
self.store.get_user_by_access_token = Mock(return_value=user_info)

Expand Down Expand Up @@ -143,7 +144,10 @@ def test_get_user_from_macaroon(self):
# TODO(danielwh): Remove this mock when we remove the
# get_user_by_access_token fallback.
self.store.get_user_by_access_token = Mock(
return_value={"name": "@baldrick:matrix.org"}
return_value={
"name": "@baldrick:matrix.org",
"device_id": "device",
}
)

user_id = "@baldrick:matrix.org"
Expand All @@ -158,6 +162,10 @@ def test_get_user_from_macaroon(self):
user = user_info["user"]
self.assertEqual(UserID.from_string(user_id), user)

# TODO: device_id should come from the macaroon, but currently comes
# from the db.
self.assertEqual(user_info["device_id"], "device")

@defer.inlineCallbacks
def test_get_guest_user_from_macaroon(self):
user_id = "@baldrick:matrix.org"
Expand Down

0 comments on commit e9e3eaa

Please sign in to comment.