atsign-foundation / at_client_sdk

The Dart implementation of atSDK used for implementing Atsign's technology into other software
https://pub.dev/publishers/atsign.org/packages
BSD 3-Clause "New" or "Revised" License
1.47k stars 32 forks source link

Being able to get an AtClient without having connectivity to your atServer (i.e offline access) #915

Open cconstab opened 1 year ago

cconstab commented 1 year ago

Is your feature request related to a problem? Please describe.

The problem could be that you have an application that has data which has been synched to your device but now the device is offline. With the current SDK although the data is available locally you cannot get to it as you are offline.

This kills a number of use case for instance atBuzz only works if you have an Internet connection.

Describe the solution you'd like

If the atSign has already synched at least once then return an atClient that can read/write locally and when the atServer is not reachable.

Describe alternatives you've considered

none

Additional context

This is important for both flutter and dart apps

gkc commented 1 year ago

@sitaram-kalluri If you're looking for what to pick up next, I'd suggest this one

sitaram-kalluri commented 1 year ago

@sitaram-kalluri If you're looking for what to pick up next, I'd suggest this one

@gkc: Sure, I will start on this. Thank you.

sitaram-kalluri commented 1 year ago

Following are the scenarios with expected behaviour when starting atClient in offline mode:

  1. When the network is down and atSign is onboarded, Should the user be notified that sync and notification services will not run until the network is back? Approach - 1: Introduce offline mode
    • A caution that atClient is started in offline mode. When in offline mode, the following is the behaviour of the atClient:
      • The "put" operation can be allowed with a caution that "Network is down and data will be synced/notified to server once the network is back"
        • The notification service will NOT be functional
        • The sync service will NOT be functional
        • Look-Up for the keys of other atSign are NOT allowed (lookup/plookup verb is NOT allowed. Only LLookup verb is allowed to fetch data in local secondary)
  2. If the client is onboarded in offline mode and if the server is reset, what should be the behaviour on the client side after the network is restored? Approach - 1
    • If the client is onboarded on an offline mode, keep polling on the network, Once the network is back, fetch the encryption public key from the server and compare it with the client. If the value does not match, stop the SDK services and provide an option to unpair the atSign which clears the local storage.
gkc commented 1 year ago

Re (1) : I think we should do as little as possible (ideally nothing) over and above the bare minimum of making the onboarding (flutter or cli) work. Application code can detect whether network is down if it wishes to. Re (2) : Something like this sounds reasonable. It may be better to attempt a PKAM auth and, if it actively fails (i.e. get the response code saying that pkam auth has failed), then do the stopping / unpairing / storage clearing / etc

@cconstab wdyt?

cconstab commented 1 year ago

KISS for sure before we migrate functionality into the SDK..

This we can all do in client/application code for sure if we have 3

  1. We already have a way of checking if we are online or not
  2. If online do what we do
  3. If offline then get offline atClient
  4. Check if we got online via callback (we have that already too)
  5. Migrate to online or stay offline for mo

Having a way to get an atClient in local mode is the standalone need..

VJag commented 1 year ago

Pre-conditions to have atClient to work offline:

  1. Hive storage should have been initialized (Created in create() method of AtClientImpl - called by onBoard() method of AtClientService)
  2. AtClientManager should have been initialized with setCurrentAtSign
VJag commented 1 year ago

Expected behavior:

Offline-supported operations matrix

Offline activity Can work offline?
list keys Yes
list keys shared by other @sign (scan:other@sign) No
put private key Yes
put self key Yes
put public key Yes
put shared key with cached encryption public key of recipient Yes
put shared key No
get value for a key Yes
get value from other @sign No
notify No
sync No
cconstab commented 1 year ago

Get a value from another atSign that has already been synch should be fine. Is that covered in get atKey?

sitaram-kalluri commented 1 year ago

Get a value from another atSign that has already been synch should be fine. Is that covered in get atKey?

@cconstab: The value of the key that belongs to another atSign can be fetched if there exists a cached key of the same in the current atSign.

gkc commented 1 year ago

Does this still need discussion or are we now in implementation?

sitaram-kalluri commented 1 year ago

Does this still need discussion or are we now in implementation?

@gkc: We have a version of the implementation checked-in into at_client_offline_access branch in at_client_sdk. Following is the link for the changes made. Pending work on this is to consume the changes into the apps and test them.

sitaram-kalluri commented 1 year ago

Progress made in PR 57

@sachins-geekyants has uptaken at_client offline mode changes into "wavi" app and changes are available in the following branch feat_onboard_offline.

@sachins-geekyants has reported two issues which are fixed and pushed to at_client_offline_access branch in at_client_sdk.

gkc commented 1 year ago

@sitaram-kalluri The approach as implemented right now in the PR is:

The current behaviour is, the app checks if the device is offline. If yes invokes isAtClientReadyForOfflineAccess which initializes the AtClient and verifies if the encryption public key is available in the KeyStore.

This feels like a very clunky developer experience. We should require no changes to existing application code if at all possible, and I don't really see why it's necessary here. Application code should be able to construct their AtClient in the same way as now - the difference being, the AtClient will be constructed whether online or offline, as long as some preconditions are in place.

sitaram-kalluri commented 12 months ago

When a current user logs into an application, the "onboard" method is called in the "at_client_server.dart" file of the "at_client_mobile" module. Within the "onboard" method, the encryptionPublicKey is obtained from both the cloud and the local secondary in order to determine the "keyRestorePolicyStatus". However, if there is no network connection or the cloud secondary is unreachable while fetching the encryptionPublicKey, an exception is raised. This exception is not handled within the "onboard" method, resulting in its propagation to the mobile applications.

Proposed Solution:

When an at_client is started in offline mode, there are certain operations that should not be permitted. These operations include the NotificationService, SyncService, and the creation/update of shared keys.

gkc commented 11 months ago

Setting priority to P1

sitaram-kalluri commented 11 months ago

The changes are implemented and pushed to at_client_offline_access. Will pass the branch to @purnimavenkatasubbu for testing the changes.

sitaram-kalluri commented 1 week ago

The trunk branch changes are pulled into the current branch. The at_client offline access changes are updated into the new class AtAuthServiceImpl and added the unit tests. The code changes are in the following branch: https://github.com/atsign-foundation/at_client_sdk/compare/trunk...at_client_offline_access. Pending work is to raise PR and merge the changes.