Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace blob type with string #168

Merged
merged 3 commits into from
Jan 22, 2025
Merged

Conversation

cp-megh-l
Copy link
Collaborator

@cp-megh-l cp-megh-l commented Jan 22, 2025

Summary by CodeRabbit

  • Data Model Changes

    • Updated data type for location and encryption-related fields from Blob to String
    • Modified handling of identity keys, location coordinates, and encrypted data representations
  • Security Rules

    • Simplified Firestore security rules for spaces, user locations, and key records
    • Relaxed type and permission checks for certain document operations
  • Utility Updates

    • Added new utility methods for encoding and converting between String and ByteArray
    • Introduced more flexible data conversion mechanisms for encryption and decryption processes
  • Imports

    • Added import statements for new utility functions to enhance data handling capabilities in various services

Copy link

coderabbitai bot commented Jan 22, 2025

Warning

Rate limit exceeded

@cp-megh-l has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 10 minutes and 20 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c79976f and 6a79b75.

📒 Files selected for processing (1)
  • data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (3 hunks)

Walkthrough

This pull request introduces significant changes to data type representations across multiple files in the project. The primary modification involves transitioning from Blob to String types for various encrypted fields, particularly in location, user, and space-related models. Two new utility functions, toBytes() and encodeToString(), are added to facilitate Base64 encoding and decoding. The changes affect data models, services, and Firestore security rules, indicating a comprehensive refactoring of how encrypted data is handled and stored.

Changes

File Change Summary
app/src/main/java/com/canopas/yourspace/ui/MainViewModel.kt Added import for toBytes extension function
app/src/main/java/com/canopas/yourspace/ui/flow/auth/SignInMethodViewModel.kt Added import for toBytes extension function
data/src/main/java/com/canopas/yourspace/data/models/location/ApiLocation.kt Changed latitude and longitude from Blob to String
data/src/main/java/com/canopas/yourspace/data/models/location/LocationJourney.kt Updated location-related properties from Blob to String in multiple classes
data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt Modified ApiSpaceMember and EncryptedDistribution to use String instead of Blob
data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt Changed identity key properties from Blob to String
data/src/main/java/com/canopas/yourspace/data/service/location/ApiLocationService.kt Updated serialization method for location encryption
data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt Added toBytes() and encodeToString() extension functions, updated encryption methods
data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt Added import for toBytes function
data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt Updated key handling with new encoding methods
data/src/main/java/com/canopas/yourspace/data/utils/EphemeralECDHUtils.kt Modified encryption methods to use string encoding
firestore.rules Updated security rules to accommodate new data types and simplified permissions

Possibly related PRs

Suggested reviewers

  • cp-radhika-s

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary or Summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (4)
data/src/main/java/com/canopas/yourspace/data/models/location/LocationJourney.kt (1)

51-52: Consider using null as default value for encrypted coordinates.

Empty strings as default values for encrypted coordinates might not be the best choice:

  1. It doesn't clearly indicate the absence of data
  2. It might cause issues if the encryption logic expects non-empty input

Consider this alternative:

-    val latitude: String = "", // Encrypted latitude
-    val longitude: String = "" // Encrypted longitude
+    val latitude: String? = null, // Base64 encoded encrypted latitude
+    val longitude: String? = null, // Base64 encoded encrypted longitude
data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (2)

32-36: Consider using mapNotNull for better performance.

The current implementation maps over routes but returns null if any route fails. Using mapNotNull would be more idiomatic and potentially more efficient.

-    val decryptedRoutes = routes.map { route ->
-        val lat = groupCipher.decryptPoint(route.latitude.toBytes()) ?: return null
-        val long = groupCipher.decryptPoint(route.longitude.toBytes()) ?: return null
-        JourneyRoute(lat, long)
-    }
+    val decryptedRoutes = try {
+        routes.mapNotNull { route ->
+            val lat = groupCipher.decryptPoint(route.latitude.toBytes()) ?: return null
+            val long = groupCipher.decryptPoint(route.longitude.toBytes()) ?: return null
+            JourneyRoute(lat, long)
+        }
+    } catch (e: Exception) {
+        Timber.e(e, "Failed to decrypt route")
+        return null
+    }

Line range hint 97-114: Consider precision handling for double values.

Converting doubles to/from strings might lead to precision loss. Consider:

  1. Using a specific decimal format for consistent precision.
  2. Adding validation for the decimal range.
+private val COORDINATE_FORMAT = "%.10f"
+
 fun GroupCipher.encryptPoint(distributionId: UUID, data: Double): String? {
     return try {
-        encrypt(distributionId, data.toString().toByteArray(Charsets.UTF_8))
+        encrypt(distributionId, COORDINATE_FORMAT.format(data).toByteArray(Charsets.UTF_8))
             .serialize()
             .encodeToString()
     } catch (e: Exception) {
         Timber.e(e, "Failed to encrypt double")
         null
     }
 }
data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt (1)

79-81: Consider handling validation exceptions gracefully.

The validation logic in the init block could throw runtime exceptions. Consider implementing a more graceful error handling approach.

 data class EncryptedDistribution(
     val id: String = UUID.randomUUID().toString(),
     val recipient_id: String = "",
     val ephemeral_pub: String = "",
     val iv: String = "",
     val ciphertext: String = "",
     val created_at: Long = System.currentTimeMillis()
 ) {
+    companion object {
+        fun create(
+            recipientId: String,
+            ephemeralPub: String,
+            iv: String,
+            ciphertext: String
+        ): Result<EncryptedDistribution> {
+            return try {
+                val distribution = EncryptedDistribution(
+                    recipient_id = recipientId,
+                    ephemeral_pub = ephemeralPub,
+                    iv = iv,
+                    ciphertext = ciphertext
+                )
+                Result.success(distribution)
+            } catch (e: IllegalArgumentException) {
+                Result.failure(e)
+            }
+        }
+    }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7ed458 and 3d2a958.

📒 Files selected for processing (12)
  • app/src/main/java/com/canopas/yourspace/ui/MainViewModel.kt (1 hunks)
  • app/src/main/java/com/canopas/yourspace/ui/flow/auth/SignInMethodViewModel.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/location/ApiLocation.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/location/LocationJourney.kt (2 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt (3 hunks)
  • data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/service/location/ApiLocationService.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (3 hunks)
  • data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt (1 hunks)
  • data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt (4 hunks)
  • data/src/main/java/com/canopas/yourspace/data/utils/EphemeralECDHUtils.kt (2 hunks)
  • firestore.rules (5 hunks)
✅ Files skipped from review due to trivial changes (3)
  • app/src/main/java/com/canopas/yourspace/ui/flow/auth/SignInMethodViewModel.kt
  • data/src/main/java/com/canopas/yourspace/data/service/space/ApiSpaceService.kt
  • app/src/main/java/com/canopas/yourspace/ui/MainViewModel.kt
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (15)
data/src/main/java/com/canopas/yourspace/data/models/location/LocationJourney.kt (1)

32-35: Verify the security implications of storing encrypted data as strings.

While transitioning from Blob to String can simplify data handling, please ensure:

  1. The Base64 encoding/decoding process preserves the full entropy of the encrypted data
  2. The migration strategy handles existing Blob data correctly
  3. Any Firestore queries or indexes on these fields are updated accordingly

Let's verify the impact on the codebase:

✅ Verification successful

The transition from Blob to String appears secure and well-implemented.

The codebase shows:

  • Proper encryption/decryption cycle using groupCipher with byte array conversion
  • No direct Firestore queries on encrypted fields
  • Clean separation between encrypted and decrypted data models
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Firestore queries using these fields
rg -A 3 "from_latitude|from_longitude|to_latitude|to_longitude" --type kotlin

# Look for migration code
rg -B 2 -A 2 "migration|upgrade|convert.*Blob" --type kotlin

Length of output: 21519

data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (1)

61-63: Verify the distributionId parameter usage.

The distributionId is crucial for secure encryption. Ensure that:

  1. It's properly generated and unique per group.
  2. It's not reused across different encryption operations.
  3. It's securely stored and managed.
✅ Verification successful

✓ The distributionId implementation is secure and properly managed

The verification confirms that:

  • UUIDs are randomly generated for each distribution message
  • They're properly integrated with the Signal Protocol's security model
  • Each encryption operation uses a fresh UUID
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for distributionId generation and usage patterns
rg -A 5 "distributionId.*UUID" 

Length of output: 4517


Script:

#!/bin/bash
# Search for UUID generation patterns related to distribution
rg -A 3 "UUID\.(random|from)" 

Length of output: 8551

data/src/main/java/com/canopas/yourspace/data/models/location/ApiLocation.kt (1)

22-23: Consider adding Base64 validation for encrypted coordinates.

While the comments clarify that the fields contain Base64 encoded data, there's no validation to ensure the strings are valid Base64 encoded values.

data/src/main/java/com/canopas/yourspace/data/models/user/ApiUser.kt (1)

28-30: LGTM! Consistent with the type conversion pattern.

The changes maintain nullability and include helpful comments. The transition from Blob? to String? is implemented correctly.

data/src/main/java/com/canopas/yourspace/data/models/space/ApiSpace.kt (2)

4-4: LGTM! Required import for byte conversion.

The import is necessary for the validation logic.


27-27: LGTM! Consistent with other identity key changes.

The change from Blob? to String? aligns with similar changes in ApiUser.kt.

data/src/main/java/com/canopas/yourspace/data/utils/EphemeralECDHUtils.kt (2)

4-5: LGTM! Required imports for string encoding/decoding.

The imports are necessary for the type conversion changes.


54-56: LGTM! Secure conversion to Base64 strings.

The encryption process remains secure with the Base64 encoding of binary data.

data/src/main/java/com/canopas/yourspace/data/service/user/ApiUserService.kt (4)

8-9: LGTM! Required imports added for string encoding/decoding.

The new imports support the transition from Blob to String type.


144-146: LGTM! Consistent string encoding for identity keys in document updates.

The change correctly uses string encoding for all identity keys in the Firestore document update.


151-153: LGTM! Consistent string encoding in the returned user object.

The change maintains consistency by using string encoding for all identity keys in the returned user object.


59-59: Verify the encryption/decryption flow with the new string encoding.

The change from Blob to String encoding for the private key looks correct, but we should verify the complete flow.

Run this script to verify the encryption/decryption flow:

Also applies to: 74-74

✅ Verification successful

The encryption/decryption flow with string encoding is secure and properly implemented

The complete flow has been verified:

  • Secure key derivation using PBKDF2 with proper salt handling
  • AES-GCM encryption with proper IV handling
  • Consistent Base64 encoding for string representation
  • No security compromises in the encryption/decryption chain
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the complete encryption/decryption flow
# Test: Check for any direct Blob usage that might have been missed
# and verify the encryption/decryption methods are consistently using the new string encoding

# Search for any remaining Blob usage
echo "Checking for remaining Blob usage..."
rg -l "Blob\." 

# Verify encryption/decryption flow
echo "Verifying encryption/decryption flow..."
ast-grep --pattern 'decryptPrivateKey($key, $salt, $pass)'

Length of output: 663


Script:

#!/bin/bash
# Search for encryption/decryption related code and string encoding
echo "Checking encryption/decryption methods..."
rg -A 5 "encrypt|decrypt" --type kotlin

echo "\nChecking Blob usage context..."
rg -A 5 "Blob\." --type kotlin

echo "\nChecking string encoding methods..."
rg -A 3 "encode.*String|decode.*String" --type kotlin

Length of output: 61705


Script:

#!/bin/bash
# Check the encryption implementation details
echo "Checking PrivateKeyUtils implementation..."
rg -A 20 "class PrivateKeyUtils" --type kotlin

echo "\nChecking key derivation..."
rg -A 10 "deriveKeyFromPasskey" --type kotlin

Length of output: 3369

data/src/main/java/com/canopas/yourspace/data/service/location/ApiLocationService.kt (1)

131-132: LGTM! Consistent string encoding for encrypted location data.

The change correctly uses string encoding for encrypted latitude and longitude values while preserving the underlying encryption logic.

Run this script to verify the location encryption flow:

✅ Verification successful

Verified: Location encryption changes are consistent and complete

The encryption/decryption cycle is properly maintained:

  • Encryption and serialization are consistently implemented across location-related files
  • Proper string encoding/decoding is used for data storage
  • The only Blob usage is for an unrelated public key operation
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the location encryption flow
# Test: Check if the encryption is consistently using string encoding
# and verify no Blob usage remains in location-related files

echo "Checking location-related files for remaining Blob usage..."
fd -e kt -e java location | xargs rg "Blob\."

echo "Verifying location encryption flow..."
ast-grep --pattern 'encrypt($_, $_, $_).serialize().encodeToString()'

Length of output: 489


Script:

#!/bin/bash
# Check for complete encryption/decryption flow in location service
echo "Checking encryption/decryption methods..."
rg -A 3 "encrypt.*(?:latitude|longitude)" data/src/main/java/com/canopas/yourspace/data/service/location/

echo -e "\nChecking decryption methods..."
rg -A 3 "decrypt.*(?:latitude|longitude)" data/src/main/java/com/canopas/yourspace/data/service/location/

echo -e "\nChecking serialization patterns..."
rg -A 2 "serialize\(\)\.encodeToString\(\)" data/src/main/java/com/canopas/yourspace/data/service/location/

Length of output: 5442

firestore.rules (2)

229-230: LGTM! Updated type checks for journey coordinates.

The type checks have been correctly updated to validate string types for encrypted coordinates.


245-245: LGTM! Updated type check for sender key record.

The type check has been correctly updated to validate string type for the encrypted record.

firestore.rules Show resolved Hide resolved
firestore.rules Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (2)

19-19: Add error handling for Base64 encoding.

Similar to toBytes(), add error handling for Base64 encoding to maintain consistency and robustness.

-fun ByteArray.encodeToString(): String = Base64.getEncoder().encodeToString(this)
+fun ByteArray.encodeToString(): String? = try {
+    Base64.getEncoder().encodeToString(this)
+} catch (e: Exception) {
+    Timber.e(e, "Failed to encode base64 string")
+    null
+}

Line range hint 102-120: Consider precision implications in point conversion.

The current implementation converts doubles to strings and back, which could potentially lose precision. Consider using a more precise serialization method like java.nio.ByteBuffer for floating-point numbers.

 fun GroupCipher.decryptPoint(data: ByteArray?): Double? {
     return try {
-        data?.let { decrypt(it).toString(Charsets.UTF_8).toDoubleOrNull() }
+        data?.let {
+            val bytes = decrypt(it)
+            ByteBuffer.wrap(bytes).double
+        }
     } catch (e: Exception) {
         Timber.e(e, "Failed to decrypt double")
         null
     }
 }

 fun GroupCipher.encryptPoint(distributionId: UUID, data: Double): String? {
     return try {
-        encrypt(distributionId, data.toString().toByteArray(Charsets.UTF_8))
+        val buffer = ByteBuffer.allocate(java.lang.Double.BYTES)
+        buffer.putDouble(data)
+        encrypt(distributionId, buffer.array())
             .serialize()
             .encodeToString()
     } catch (e: Exception) {
         Timber.e(e, "Failed to encrypt double")
         null
     }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2a958 and c79976f.

📒 Files selected for processing (1)
  • data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (2)
data/src/main/java/com/canopas/yourspace/data/service/location/JourneyKtx.kt (2)

Line range hint 25-59: Well-structured decryption implementation!

The decryption flow is robust with proper null checks, clear error handling, and good separation between required and optional coordinates.


65-81: Consider adding coordinate validation.

For data integrity, consider validating latitude (-90 to 90) and longitude (-180 to 180) ranges before encryption.

Note: This suggestion was previously declined with the explanation that coordinates are received from a trusted source (fused location provider).

@cp-megh-l cp-megh-l merged commit 0aa1874 into main Jan 22, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants