瀏覽代碼

fix(api): reorder code and user data unpacking during code deserialization

Peter Thomassen 3 年之前
父節點
當前提交
c373930310
共有 1 個文件被更改,包括 6 次插入4 次删除
  1. 6 4
      api/desecapi/serializers.py

+ 6 - 4
api/desecapi/serializers.py

@@ -759,8 +759,10 @@ class AuthenticatedActionSerializer(serializers.ModelSerializer):
         return {'code': self._pack_code(data)}
         return {'code': self._pack_code(data)}
 
 
     def to_internal_value(self, data):
     def to_internal_value(self, data):
-        # calculate code TTL
+        # Allow injecting validity period from context.  This is used, for example, for authentication, where the code's
+        # integrity and timestamp is checked by AuthenticatedBasicUserActionSerializer with validity injected as needed.
         validity_period = self.context.get('validity_period', self.validity_period)
         validity_period = self.context.get('validity_period', self.validity_period)
+        # calculate code TTL
         try:
         try:
             ttl = validity_period.total_seconds()
             ttl = validity_period.total_seconds()
         except AttributeError:
         except AttributeError:
@@ -778,11 +780,11 @@ class AuthenticatedActionSerializer(serializers.ModelSerializer):
                 msg = f'This code is invalid, possibly because it expired (validity: {validity_period}).'
                 msg = f'This code is invalid, possibly because it expired (validity: {validity_period}).'
             raise serializers.ValidationError({api_settings.NON_FIELD_ERRORS_KEY: msg})
             raise serializers.ValidationError({api_settings.NON_FIELD_ERRORS_KEY: msg})
 
 
-        # add extra fields added by the user
-        unpacked_data.update(**data)
+        # add extra fields added by the user, but give precedence to fields unpacked from the code
+        data = {**data, **unpacked_data}
 
 
         # do the regular business
         # do the regular business
-        return super().to_internal_value(unpacked_data)
+        return super().to_internal_value(data)
 
 
     def act(self):
     def act(self):
         self.instance.act()
         self.instance.act()