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

Enable test mode on API gateway #389

Merged
merged 12 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions examples/applications/gateway-authentication/gateways.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,20 +21,20 @@ gateways:
topic: input-topic
parameters:
- sessionId
produceOptions:
produce-options:
Copy link
Member

Choose a reason for hiding this comment

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

this reads like a breaking change and we have stuff in production, please don't do it

Copy link
Member Author

Choose a reason for hiding this comment

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

no it's not, it's an alias and they both work

headers:
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId
- id: consume-output-no-auth
type: consume
topic: output-topic
parameters:
- sessionId
consumeOptions:
consume-options:
filters:
headers:
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: produce-input-auth-google
type: produce
Expand All @@ -45,12 +45,13 @@ gateways:
provider: google
configuration:
clientId: "{{ secrets.google.client-id }}"
produceOptions:
allow-admin-requests: true
produce-options:
headers:
- key: langstream-client-user-id
valueFromAuthentication: subject
value-from-authentication: subject
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: consume-output-auth-google
type: consume
Expand All @@ -61,13 +62,14 @@ gateways:
provider: google
configuration:
clientId: "{{ secrets.google.client-id }}"
consumeOptions:
allow-admin-requests: true
consume-options:
filters:
headers:
- key: langstream-client-user-id
valueFromAuthentication: subject
value-from-authentication: subject
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: produce-input-auth-github
type: produce
Expand All @@ -78,26 +80,28 @@ gateways:
provider: github
configuration:
clientId: "{{ secrets.github.client-id }}"
produceOptions:
allow-admin-requests: true
produce-options:
headers:
- key: langstream-client-user-id
valueFromAuthentication: login
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: consume-output-auth-github
type: consume
topic: output-topic
parameters:
- sessionId
authentication:
provider: github
configuration:
clientId: "{{ secrets.github.client-id }}"
consumeOptions:
- id: consume-output-auth-github
type: consume
topic: output-topic
parameters:
- sessionId
authentication:
provider: github
configuration:
clientId: "{{ secrets.github.client-id }}"
allow-admin-requests: true
consume-options:
filters:
headers:
- key: langstream-client-user-id
valueFromAuthentication: login
value-from-authentication: login
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId
18 changes: 10 additions & 8 deletions examples/applications/openai-completions/gateways.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ gateways:
topic: input-topic
parameters:
- sessionId
produceOptions:
produce-options:
headers:
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: consume-output
type: consume
topic: output-topic
parameters:
- sessionId
consumeOptions:
consume-options:
filters:
headers:
- key: langstream-client-session-id
valueFromParameters: sessionId
value-from-parameters: sessionId

- id: consume-history
type: consume
Expand All @@ -48,10 +48,11 @@ gateways:
provider: google
configuration:
clientId: "{{ secrets.google.client-id }}"
produceOptions:
allow-admin-requests: true
produce-options:
headers:
- key: langstream-client-user-id
valueFromAuthentication: subject
value-from-authentication: subject

- id: consume-output-auth
type: consume
Expand All @@ -60,9 +61,10 @@ gateways:
provider: google
configuration:
clientId: "{{ secrets.google.client-id }}"
consumeOptions:
allow-admin-requests: true
consume-options:
filters:
headers:
- key: langstream-client-user-id
valueFromAuthentication: subject
value-from-authentication: subject

Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright DataStax, Inc.

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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>langstream-api-gateway-auth</artifactId>
<groupId>ai.langstream</groupId>
<version>0.0.16-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>langstream-http-gateway-admin-auth</artifactId>

<dependencies>
<dependency>
<groupId>ai.langstream</groupId>
<artifactId>langstream-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright DataStax, Inc.
*
* 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 ai.langstream.apigateway.auth.impl.jwt.admin;

import ai.langstream.api.gateway.GatewayAdminAuthenticationProvider;
import ai.langstream.api.gateway.GatewayAdminRequestContext;
import ai.langstream.api.gateway.GatewayAuthenticationResult;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Map;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class HttpAdminAuthenticationProvider implements GatewayAdminAuthenticationProvider {
Copy link
Member

Choose a reason for hiding this comment

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

why only "admin", we can make it a regular implementation


private static final ObjectMapper mapper = new ObjectMapper();
private HttpAdminAuthenticationProviderConfiguration httpConfiguration;
private HttpClient httpClient;

@Override
public String type() {
return "http";
}

@Override
@SneakyThrows
public void initialize(Map<String, Object> configuration) {
httpConfiguration =
mapper.convertValue(
configuration, HttpAdminAuthenticationProviderConfiguration.class);
httpClient =
HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(30))
.followRedirects(HttpClient.Redirect.ALWAYS)
.build();
}

@Override
public GatewayAuthenticationResult authenticate(GatewayAdminRequestContext context) {

final Map<String, String> placeholders = Map.of("tenant", context.tenant());
final String uri = resolvePlaceholders(placeholders, httpConfiguration.getPathTemplate());
final String url = httpConfiguration.getBaseUrl() + uri;

log.info("Authenticating admin with url: {}", url);

final HttpRequest.Builder builder = HttpRequest.newBuilder().uri(URI.create(url));

httpConfiguration.getHeaders().forEach(builder::header);
builder.header("Authorization", "Bearer " + context.credentials());
final HttpRequest request = builder.GET().build();

final HttpResponse<Void> response;
try {
response = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
} catch (Throwable e) {
return GatewayAuthenticationResult.authenticationFailed(e.getMessage());
}
if (httpConfiguration.getAcceptedStatuses().contains(response.statusCode())) {
return GatewayAuthenticationResult.authenticationSuccessful(
context.adminCredentialsInputs());
}
return GatewayAuthenticationResult.authenticationFailed(
"Http authentication failed: " + response.statusCode());
}

private static String resolvePlaceholders(Map<String, String> placeholders, String url) {
for (Map.Entry<String, String> entry : placeholders.entrySet()) {
url = url.replace("{" + entry.getKey() + "}", entry.getValue());
}
return url;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright DataStax, Inc.
*
* 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 ai.langstream.apigateway.auth.impl.jwt.admin;

import com.fasterxml.jackson.annotation.JsonAlias;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class HttpAdminAuthenticationProviderConfiguration {

@JsonAlias("base-url")
private String baseUrl;

@JsonAlias("path-template")
private String pathTemplate;

private Map<String, String> headers = new HashMap<>();

@JsonAlias("accepted-statuses")
private List<Integer> acceptedStatuses = List.of(200, 201);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ai.langstream.apigateway.auth.impl.jwt.admin.HttpAdminAuthenticationProvider
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Copyright DataStax, Inc.

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.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>langstream-api-gateway-auth</artifactId>
<groupId>ai.langstream</groupId>
<version>0.0.16-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>langstream-jwt-gateway-admin-auth</artifactId>

<dependencies>
<dependency>
<groupId>ai.langstream</groupId>
<artifactId>langstream-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ai.langstream</groupId>
<artifactId>langstream-auth-jwt</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Loading
Loading