mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 13:27:59 +01:00
Add a gRPC service for working with pre-keys
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.auth;
|
||||
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
public class UnidentifiedAccessUtil {
|
||||
|
||||
private UnidentifiedAccessUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether an action (e.g. sending a message or retrieving pre-keys) may be taken on the target account by an
|
||||
* actor presenting the given unidentified access key.
|
||||
*
|
||||
* @param targetAccount the account on which an actor wishes to take an action
|
||||
* @param unidentifiedAccessKey the unidentified access key presented by the actor
|
||||
*
|
||||
* @return {@code true} if an actor presenting the given unidentified access key has permission to take an action on
|
||||
* the target account or {@code false} otherwise
|
||||
*/
|
||||
public static boolean checkUnidentifiedAccess(final Account targetAccount, final byte[] unidentifiedAccessKey) {
|
||||
return targetAccount.isUnrestrictedUnidentifiedAccess()
|
||||
|| targetAccount.getUnidentifiedAccessKey()
|
||||
.map(targetUnidentifiedAccessKey -> MessageDigest.isEqual(targetUnidentifiedAccessKey, unidentifiedAccessKey))
|
||||
.orElse(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.auth.grpc;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public record AuthenticatedDevice(UUID accountIdentifier, long deviceId) {
|
||||
}
|
||||
@@ -6,8 +6,12 @@
|
||||
package org.whispersystems.textsecuregcm.auth.grpc;
|
||||
|
||||
import io.grpc.Context;
|
||||
import java.util.Optional;
|
||||
import io.grpc.Status;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuples;
|
||||
|
||||
/**
|
||||
* Provides utility methods for working with authentication in the context of gRPC calls.
|
||||
@@ -17,11 +21,23 @@ public class AuthenticationUtil {
|
||||
static final Context.Key<UUID> CONTEXT_AUTHENTICATED_ACCOUNT_IDENTIFIER_KEY = Context.key("authenticated-aci");
|
||||
static final Context.Key<Long> CONTEXT_AUTHENTICATED_DEVICE_IDENTIFIER_KEY = Context.key("authenticated-device-id");
|
||||
|
||||
public static Optional<UUID> getAuthenticatedAccountIdentifier() {
|
||||
return Optional.ofNullable(CONTEXT_AUTHENTICATED_ACCOUNT_IDENTIFIER_KEY.get());
|
||||
}
|
||||
/**
|
||||
* Returns the account/device authenticated in the current gRPC context or throws an "unauthenticated" exception if
|
||||
* no authenticated account/device is available.
|
||||
*
|
||||
* @return the account/device authenticated in the current gRPC context
|
||||
*
|
||||
* @throws io.grpc.StatusRuntimeException with a status of {@code UNAUTHENTICATED} if no authenticated account/device
|
||||
* could be retrieved from the current gRPC context
|
||||
*/
|
||||
public static AuthenticatedDevice requireAuthenticatedDevice() {
|
||||
@Nullable final UUID accountIdentifier = CONTEXT_AUTHENTICATED_ACCOUNT_IDENTIFIER_KEY.get();
|
||||
@Nullable final Long deviceId = CONTEXT_AUTHENTICATED_DEVICE_IDENTIFIER_KEY.get();
|
||||
|
||||
public static Optional<Long> getAuthenticatedDeviceIdentifier() {
|
||||
return Optional.ofNullable(CONTEXT_AUTHENTICATED_DEVICE_IDENTIFIER_KEY.get());
|
||||
if (accountIdentifier != null && deviceId != null) {
|
||||
return new AuthenticatedDevice(accountIdentifier, deviceId);
|
||||
}
|
||||
|
||||
throw Status.UNAUTHENTICATED.asRuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,8 @@ import org.whispersystems.textsecuregcm.auth.BaseAccountAuthenticator;
|
||||
* Callers supply credentials by providing a username (UUID and optional device ID) and password pair in the
|
||||
* {@code x-signal-basic-auth-credentials} call header.
|
||||
* <p/>
|
||||
* Downstream services can retrieve the identity of the authenticated caller using
|
||||
* {@link AuthenticationUtil#getAuthenticatedAccountIdentifier()} and
|
||||
* {@link AuthenticationUtil#getAuthenticatedDeviceIdentifier()}.
|
||||
* Downstream services can retrieve the identity of the authenticated caller using methods in
|
||||
* {@link AuthenticationUtil}.
|
||||
* <p/>
|
||||
* Note that this authentication, while fully functional, is intended only for development and testing purposes and is
|
||||
* intended to be replaced with a more robust and efficient strategy before widespread client adoption.
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Copyright 2023 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.auth.grpc;
|
||||
|
||||
/**
|
||||
* Indicates that a caller tried to get information about the authenticated gRPC caller, but no caller has been
|
||||
* authenticated.
|
||||
*/
|
||||
public class NotAuthenticatedException extends Exception {
|
||||
}
|
||||
Reference in New Issue
Block a user