Skip to content

Commit

Permalink
alts: Introduce AltsContext to allow outside packages accessing ALTS …
Browse files Browse the repository at this point in the history
…information
  • Loading branch information
martin-schaub committed Feb 9, 2021
1 parent 9ba419a commit 514101d
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 0 deletions.
1 change: 1 addition & 0 deletions alts/BUILD.bazel
Expand Up @@ -35,6 +35,7 @@ java_library(
visibility = ["//visibility:public"],
deps = [
":alts_internal",
":handshaker_java_proto",
":handshaker_java_grpc",
"//api",
"//auth",
Expand Down
92 changes: 92 additions & 0 deletions alts/src/main/java/io/grpc/alts/AltsContext.java
@@ -0,0 +1,92 @@
/*
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.grpc.alts;

import io.grpc.ExperimentalApi;
import io.grpc.alts.internal.AltsInternalContext;
import io.grpc.alts.internal.HandshakerResult;
import io.grpc.alts.internal.Identity;
import io.grpc.alts.internal.SecurityLevel;

/** {@code AltsContext} contains security-related information on the ALTS channel. */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864")
public final class AltsContext {

private final AltsInternalContext wrapped;

AltsContext(AltsInternalContext wrapped) {
this.wrapped = wrapped;
}

/**
* Creates an {@code AltsContext} for testing purposes.
* @param peerServiceAccount the peer service account of the to be created {@code AltsContext}
* @param localServiceAccount the local service account of the to be created {@code AltsContext}
* @return the created {@code AltsContext}
*/
public static AltsContext createTestInstance(String peerServiceAccount,
String localServiceAccount) {
return new AltsContext(new AltsInternalContext(HandshakerResult.newBuilder()
.setPeerIdentity(Identity.newBuilder().setServiceAccount(peerServiceAccount).build())
.setLocalIdentity(Identity.newBuilder().setServiceAccount(localServiceAccount).build())
.build()));
}

/**
* Get security level.
*
* @return the context's security level.
*/
public SecurityLevel getSecurityLevel() {
switch (wrapped.getSecurityLevel()) {
case SECURITY_NONE:
return SecurityLevel.SECURITY_NONE;
case INTEGRITY_ONLY:
return SecurityLevel.INTEGRITY_ONLY;
case INTEGRITY_AND_PRIVACY:
return SecurityLevel.INTEGRITY_AND_PRIVACY;
default:
return SecurityLevel.UNKNOWN;
}
}

/**
* Get peer service account.
*
* @return the context's peer service account.
*/
public String getPeerServiceAccount() {
return wrapped.getPeerServiceAccount();
}

/**
* Get local service account.
*
* @return the context's local service account.
*/
public String getLocalServiceAccount() {
return wrapped.getLocalServiceAccount();
}

/** SecurityLevel of the ALTS channel. */
public enum SecurityLevel {
UNKNOWN,
SECURITY_NONE,
INTEGRITY_ONLY,
INTEGRITY_AND_PRIVACY,
}
}
56 changes: 56 additions & 0 deletions alts/src/main/java/io/grpc/alts/AltsContextUtil.java
@@ -0,0 +1,56 @@
/*
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package io.grpc.alts;

import io.grpc.ExperimentalApi;
import io.grpc.ServerCall;
import io.grpc.alts.internal.AltsInternalContext;
import io.grpc.alts.internal.AltsProtocolNegotiator;

/** Utility class for {@link AltsContext}. */
@ExperimentalApi("https://github.com/grpc/grpc-java/issues/7864")
public final class AltsContextUtil {

private AltsContextUtil(){}

/**
* Creates a {@link AltsContext} from ALTS context information in the {@link ServerCall}.
*
* @param call the {@link ServerCall} containing the ALTS information
* @return the created {@link AltsContext}
* @throws IllegalArgumentException if the {@link ServerCall} has no ALTS information.
*/
public static AltsContext createFrom(ServerCall<?,?> call) {
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
if (!(authContext instanceof AltsInternalContext)) {
throw new IllegalArgumentException("No ALTS context information found");
}
return new AltsContext((AltsInternalContext) authContext);
}

/**
* Checks if the {@link ServerCall} contains ALTS information.
*
* @param call the {@link ServerCall} to check
* @return true, if the {@link ServerCall} contains ALTS information and false otherwise.
*/
public static boolean check(ServerCall<?,?> call) {
Object authContext = call.getAttributes().get(AltsProtocolNegotiator.AUTH_CONTEXT_KEY);
return authContext instanceof AltsInternalContext;
}
}
91 changes: 91 additions & 0 deletions alts/src/test/java/io/grpc/alts/AltsContextUtilTest.java
@@ -0,0 +1,91 @@
/*
* Copyright 2018 The gRPC Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


package io.grpc.alts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import io.grpc.Attributes;
import io.grpc.ServerCall;
import io.grpc.alts.AltsContext.SecurityLevel;
import io.grpc.alts.internal.AltsInternalContext;
import io.grpc.alts.internal.AltsProtocolNegotiator;
import io.grpc.alts.internal.HandshakerResult;
import io.grpc.alts.internal.Identity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Unit tests for {@link AltsContextUtil}. */
@RunWith(JUnit4.class)
public class AltsContextUtilTest {

private final ServerCall<?,?> call = mock(ServerCall.class);

@Test
public void check_noAttributeValue() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());

assertFalse(AltsContextUtil.check(call));
}

@Test
public void contains_unexpectedAttributeValueType() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new Object())
.build());

assertFalse(AltsContextUtil.check(call));
}

@Test
public void contains_altsInternalContext() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, AltsInternalContext.getDefaultInstance())
.build());

assertTrue(AltsContextUtil.check(call));
}

@Test
public void from_altsInternalContext() {
HandshakerResult handshakerResult =
HandshakerResult.newBuilder()
.setPeerIdentity(Identity.newBuilder().setServiceAccount("remote@peer"))
.setLocalIdentity(Identity.newBuilder().setServiceAccount("local@peer"))
.build();
when(call.getAttributes()).thenReturn(Attributes.newBuilder()
.set(AltsProtocolNegotiator.AUTH_CONTEXT_KEY, new AltsInternalContext(handshakerResult))
.build());

AltsContext context = AltsContextUtil.createFrom(call);
assertEquals("remote@peer", context.getPeerServiceAccount());
assertEquals("local@peer", context.getLocalServiceAccount());
assertEquals(SecurityLevel.INTEGRITY_AND_PRIVACY, context.getSecurityLevel());
}

@Test(expected = IllegalArgumentException.class)
public void from_noAttributeValue() {
when(call.getAttributes()).thenReturn(Attributes.newBuilder().build());

AltsContextUtil.createFrom(call);
}
}

0 comments on commit 514101d

Please sign in to comment.