use of org.whispersystems.signalservice.internal.ServiceResponse in project Signal-Android by WhisperSystems.
the class RefreshOwnProfileJob method setProfileBadges.
private void setProfileBadges(@Nullable List<SignalServiceProfile.Badge> badges) {
if (badges == null) {
return;
}
Set<String> localDonorBadgeIds = Recipient.self().getBadges().stream().filter(badge -> badge.getCategory() == Badge.Category.Donor).map(Badge::getId).collect(Collectors.toSet());
Set<String> remoteDonorBadgeIds = badges.stream().filter(badge -> Objects.equals(badge.getCategory(), Badge.Category.Donor.getCode())).map(SignalServiceProfile.Badge::getId).collect(Collectors.toSet());
boolean remoteHasSubscriptionBadges = remoteDonorBadgeIds.stream().anyMatch(RefreshOwnProfileJob::isSubscription);
boolean localHasSubscriptionBadges = localDonorBadgeIds.stream().anyMatch(RefreshOwnProfileJob::isSubscription);
boolean remoteHasBoostBadges = remoteDonorBadgeIds.stream().anyMatch(RefreshOwnProfileJob::isBoost);
boolean localHasBoostBadges = localDonorBadgeIds.stream().anyMatch(RefreshOwnProfileJob::isBoost);
if (!remoteHasSubscriptionBadges && localHasSubscriptionBadges) {
Badge mostRecentExpiration = Recipient.self().getBadges().stream().filter(badge -> badge.getCategory() == Badge.Category.Donor).filter(badge -> isSubscription(badge.getId())).max(Comparator.comparingLong(Badge::getExpirationTimestamp)).get();
Log.d(TAG, "Marking subscription badge as expired, should notify next time the conversation list is open.", true);
SignalStore.donationsValues().setExpiredBadge(mostRecentExpiration);
if (!SignalStore.donationsValues().isUserManuallyCancelled()) {
Log.d(TAG, "Detected an unexpected subscription expiry.", true);
Subscriber subscriber = SignalStore.donationsValues().getSubscriber();
boolean isDueToPaymentFailure = false;
if (subscriber != null) {
ServiceResponse<ActiveSubscription> response = ApplicationDependencies.getDonationsService().getSubscription(subscriber.getSubscriberId()).blockingGet();
if (response.getResult().isPresent()) {
ActiveSubscription activeSubscription = response.getResult().get();
if (activeSubscription.isFailedPayment()) {
Log.d(TAG, "Unexpected expiry due to payment failure.", true);
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationReason(activeSubscription.getActiveSubscription().getStatus());
isDueToPaymentFailure = true;
}
}
}
if (!isDueToPaymentFailure) {
Log.d(TAG, "Unexpected expiry due to inactivity.", true);
SignalStore.donationsValues().setUnexpectedSubscriptionCancelationReason(UnexpectedSubscriptionCancellation.INACTIVE.getStatus());
}
MultiDeviceSubscriptionSyncRequestJob.enqueue();
SignalStore.donationsValues().setShouldCancelSubscriptionBeforeNextSubscribeAttempt(true);
}
} else if (!remoteHasBoostBadges && localHasBoostBadges) {
Badge mostRecentExpiration = Recipient.self().getBadges().stream().filter(badge -> badge.getCategory() == Badge.Category.Donor).filter(badge -> isBoost(badge.getId())).max(Comparator.comparingLong(Badge::getExpirationTimestamp)).get();
Log.d(TAG, "Marking boost badge as expired, should notify next time the conversation list is open.", true);
SignalStore.donationsValues().setExpiredBadge(mostRecentExpiration);
}
boolean userHasVisibleBadges = badges.stream().anyMatch(SignalServiceProfile.Badge::isVisible);
boolean userHasInvisibleBadges = badges.stream().anyMatch(b -> !b.isVisible());
List<Badge> appBadges = badges.stream().map(Badges::fromServiceBadge).collect(Collectors.toList());
if (userHasVisibleBadges && userHasInvisibleBadges) {
boolean displayBadgesOnProfile = SignalStore.donationsValues().getDisplayBadgesOnProfile();
Log.d(TAG, "Detected mixed visibility of badges. Telling the server to mark them all " + (displayBadgesOnProfile ? "" : "not") + " visible.", true);
BadgeRepository badgeRepository = new BadgeRepository(context);
badgeRepository.setVisibilityForAllBadges(displayBadgesOnProfile, appBadges).blockingSubscribe();
} else {
SignalDatabase.recipients().setBadges(Recipient.self().getId(), appBadges);
}
}
use of org.whispersystems.signalservice.internal.ServiceResponse in project Signal-Android by WhisperSystems.
the class CdshService method getRegisteredUsers.
public Single<ServiceResponse<Map<String, ACI>>> getRegisteredUsers(String username, String password, Set<String> e164Numbers) {
return Single.create(emitter -> {
AtomicReference<Stage> stage = new AtomicReference<>(Stage.WAITING_TO_INITIALIZE);
List<String> addressBook = e164Numbers.stream().map(e -> e.substring(1)).collect(Collectors.toList());
String url = String.format("%s/discovery/%s/%s", baseUrl, hexPublicKey, hexCodeHash);
Request request = new Request.Builder().url(url).build();
WebSocket webSocket = client.newWebSocket(request, new WebSocketListener() {
@Override
public void onMessage(WebSocket webSocket, ByteString bytes) {
switch(stage.get()) {
case WAITING_TO_INITIALIZE:
enclave.completeHandshake(bytes.toByteArray());
byte[] request = enclave.establishedSend(buildPlaintextRequest(username, password, addressBook));
stage.set(Stage.WAITING_FOR_RESPONSE);
webSocket.send(ByteString.of(request));
break;
case WAITING_FOR_RESPONSE:
byte[] response = enclave.establishedRecv(bytes.toByteArray());
try {
Map<String, ACI> out = parseResponse(addressBook, response);
emitter.onSuccess(ServiceResponse.forResult(out, 200, null));
} catch (IOException e) {
emitter.onSuccess(ServiceResponse.forUnknownError(e));
} finally {
webSocket.close(1000, "OK");
}
break;
case FAILURE:
Log.w(TAG, "Received a message after we entered the failure state! Ignoring.");
webSocket.close(1000, "OK");
break;
}
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
if (code != 1000) {
Log.w(TAG, "Remote side is closing with non-normal code " + code);
webSocket.close(1000, "Remote closed with code " + code);
stage.set(Stage.FAILURE);
emitter.onSuccess(ServiceResponse.forApplicationError(new NonSuccessfulResponseCodeException(code), code, null));
}
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
emitter.onSuccess(ServiceResponse.forApplicationError(t, response != null ? response.code() : 0, null));
stage.set(Stage.FAILURE);
webSocket.close(1000, "OK");
}
});
webSocket.send(ByteString.of(enclave.initialRequest()));
emitter.setCancellable(() -> webSocket.close(1000, "OK"));
});
}
use of org.whispersystems.signalservice.internal.ServiceResponse in project Signal-Android by WhisperSystems.
the class MessagingService method sendToGroup.
public Single<ServiceResponse<SendGroupMessageResponse>> sendToGroup(byte[] body, byte[] joinedUnidentifiedAccess, long timestamp, boolean online) {
List<String> headers = new LinkedList<String>() {
{
add("content-type:application/vnd.signal-messenger.mrm");
add("Unidentified-Access-Key:" + Base64.encodeBytes(joinedUnidentifiedAccess));
}
};
String path = String.format(Locale.US, "/v1/messages/multi_recipient?ts=%s&online=%s", timestamp, online);
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder().setId(new SecureRandom().nextLong()).setVerb("PUT").setPath(path).addAllHeaders(headers).setBody(ByteString.copyFrom(body)).build();
return signalWebSocket.request(requestMessage).map(DefaultResponseMapper.extend(SendGroupMessageResponse.class).withCustomError(401, (status, errorBody, getHeader) -> new InvalidUnidentifiedAccessHeaderException()).withCustomError(404, (status, errorBody, getHeader) -> new NotFoundException("At least one unregistered user in message send.")).withCustomError(409, (status, errorBody, getHeader) -> {
GroupMismatchedDevices[] mismatchedDevices = JsonUtil.fromJsonResponse(errorBody, GroupMismatchedDevices[].class);
return new GroupMismatchedDevicesException(mismatchedDevices);
}).withCustomError(410, (status, errorBody, getHeader) -> {
GroupStaleDevices[] staleDevices = JsonUtil.fromJsonResponse(errorBody, GroupStaleDevices[].class);
return new GroupStaleDevicesException(staleDevices);
}).build()::map).onErrorReturn(ServiceResponse::forUnknownError);
}
use of org.whispersystems.signalservice.internal.ServiceResponse in project Signal-Android by WhisperSystems.
the class MessagingService method send.
public Single<ServiceResponse<SendMessageResponse>> send(OutgoingPushMessageList list, Optional<UnidentifiedAccess> unidentifiedAccess) {
List<String> headers = new LinkedList<String>() {
{
add("content-type:application/json");
}
};
WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder().setId(new SecureRandom().nextLong()).setVerb("PUT").setPath(String.format("/v1/messages/%s", list.getDestination())).addAllHeaders(headers).setBody(ByteString.copyFrom(JsonUtil.toJson(list).getBytes())).build();
ResponseMapper<SendMessageResponse> responseMapper = DefaultResponseMapper.extend(SendMessageResponse.class).withResponseMapper((status, body, getHeader, unidentified) -> {
SendMessageResponse sendMessageResponse = Util.isEmpty(body) ? new SendMessageResponse(false, unidentified) : JsonUtil.fromJsonResponse(body, SendMessageResponse.class);
sendMessageResponse.setSentUnidentfied(unidentified);
return ServiceResponse.forResult(sendMessageResponse, status, body);
}).withCustomError(404, (status, body, getHeader) -> new UnregisteredUserException(list.getDestination(), new NotFoundException("not found"))).build();
return signalWebSocket.request(requestMessage, unidentifiedAccess).map(responseMapper::map).onErrorReturn(ServiceResponse::forUnknownError);
}
use of org.whispersystems.signalservice.internal.ServiceResponse in project Signal-Android by WhisperSystems.
the class DonationsServiceTest method givenASubscriberId_whenIGetASuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndNonEmptyObject.
@Test
public void givenASubscriberId_whenIGetASuccessfulResponse_thenItIsMappedWithTheCorrectStatusCodeAndNonEmptyObject() throws Exception {
// GIVEN
SubscriberId subscriberId = SubscriberId.generate();
when(pushServiceSocket.getSubscription(subscriberId.serialize())).thenReturn(getActiveSubscription());
// WHEN
TestObserver<ServiceResponse<ActiveSubscription>> testObserver = testSubject.getSubscription(subscriberId).test();
// THEN
TEST_SCHEDULER.triggerActions();
verify(pushServiceSocket).getSubscription(subscriberId.serialize());
testObserver.assertComplete().assertValue(value -> value.getStatus() == 200 && value.getResult().isPresent());
}
Aggregations