Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
109 changes: 109 additions & 0 deletions datamodel-valkey/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.unitvectory</groupId>
<artifactId>serviceauthcentral</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>

<groupId>com.unitvectory.serviceauthcentral</groupId>
<artifactId>datamodel-valkey</artifactId>

<properties>
</properties>

<dependencies>
<dependency>
<groupId>com.unitvectory</groupId>
<artifactId>consistgen</artifactId>
</dependency>
<dependency>
<groupId>com.unitvectory.serviceauthcentral</groupId>
<artifactId>util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.unitvectory.serviceauthcentral</groupId>
<artifactId>datamodel</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${project.build.directory}/generated-sources/annotations</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
7 changes: 7 additions & 0 deletions datamodel-valkey/src/lombok.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This tells lombok this directory is the root,
# no need to look somewhere else for java code.
config.stopBubbling = true
# This will add the @lombok.Generated annotation
# to all the code generated by Lombok,
# so it can be excluded from coverage by jacoco.
lombok.addLombokGeneratedAnnotation = true
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2026 the original author or 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
*
* https://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 com.unitvectory.serviceauthcentral.datamodel.valkey.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.core.StringRedisTemplate;

import com.unitvectory.consistgen.epoch.EpochTimeProvider;
import com.unitvectory.serviceauthcentral.datamodel.repository.AuthorizationRepository;
import com.unitvectory.serviceauthcentral.datamodel.repository.ClientRepository;
import com.unitvectory.serviceauthcentral.datamodel.repository.JwkCacheRepository;
import com.unitvectory.serviceauthcentral.datamodel.repository.LoginCodeRepository;
import com.unitvectory.serviceauthcentral.datamodel.repository.LoginStateRepository;
import com.unitvectory.serviceauthcentral.datamodel.valkey.repository.ValkeyAuthorizationRepository;
import com.unitvectory.serviceauthcentral.datamodel.valkey.repository.ValkeyClientRepository;
import com.unitvectory.serviceauthcentral.datamodel.valkey.repository.ValkeyJwkCacheRepository;
import com.unitvectory.serviceauthcentral.datamodel.valkey.repository.ValkeyLoginCodeRepository;
import com.unitvectory.serviceauthcentral.datamodel.valkey.repository.ValkeyLoginStateRepository;

@Configuration
@Profile("datamodel-valkey")
public class ValkeyConfig {

@Autowired
private StringRedisTemplate stringRedisTemplate;

@Autowired
private EpochTimeProvider epochTimeProvider;

@Bean
public AuthorizationRepository authorizationRepository() {
return new ValkeyAuthorizationRepository(stringRedisTemplate, epochTimeProvider);
}

@Bean
public ClientRepository clientRepository() {
return new ValkeyClientRepository(stringRedisTemplate, epochTimeProvider);
}

@Bean
public JwkCacheRepository jwkCacheRepository() {
return new ValkeyJwkCacheRepository(stringRedisTemplate);
}

@Bean
public LoginCodeRepository loginCodeRepository() {
return new ValkeyLoginCodeRepository(stringRedisTemplate);
}

@Bean
public LoginStateRepository loginStateRepository() {
return new ValkeyLoginStateRepository(stringRedisTemplate);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2026 the original author or 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
*
* https://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 com.unitvectory.serviceauthcentral.datamodel.valkey.mapper;

import java.util.List;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import com.unitvectory.serviceauthcentral.datamodel.valkey.model.ValkeyClientScope;
import com.unitvectory.serviceauthcentral.datamodel.model.ClientScope;

/**
* The mapper for ClientScope
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
@Mapper
public interface ClientScopeMapper {

ClientScopeMapper INSTANCE = Mappers.getMapper(ClientScopeMapper.class);

@Mapping(target = "scope", source = "scope")
@Mapping(target = "description", source = "description")
ValkeyClientScope clientScopeToValkeyClientScope(ClientScope clientScope);

List<ValkeyClientScope> clientScopeToValkeyClientScope(List<ClientScope> clientScopes);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2026 the original author or 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
*
* https://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 com.unitvectory.serviceauthcentral.datamodel.valkey.mapper;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import com.unitvectory.serviceauthcentral.datamodel.valkey.model.ValkeyCachedJwk;
import com.unitvectory.serviceauthcentral.datamodel.model.CachedJwk;

/**
* The mapper for the ValkeyCachedJwk
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
@Mapper
public interface ValkeyCachedJwkMapper {

ValkeyCachedJwkMapper INSTANCE = Mappers.getMapper(ValkeyCachedJwkMapper.class);

@Mapping(target = "url", source = "url")
@Mapping(target = "ttl", source = "ttl")
@Mapping(target = "valid", source = "jwk.valid")
@Mapping(target = "kid", source = "jwk.kid")
@Mapping(target = "kty", source = "jwk.kty")
@Mapping(target = "alg", source = "jwk.alg")
@Mapping(target = "use", source = "jwk.use")
@Mapping(target = "n", source = "jwk.n")
@Mapping(target = "e", source = "jwk.e")
ValkeyCachedJwk cachedJwkToValkeyCachedJwk(String url, long ttl, CachedJwk jwk);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2026 the original author or 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
*
* https://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 com.unitvectory.serviceauthcentral.datamodel.valkey.mapper;

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

import com.unitvectory.serviceauthcentral.datamodel.valkey.model.ValkeyClient;
import com.unitvectory.serviceauthcentral.datamodel.valkey.model.ValkeyClientSummary;

/**
* The mapper for the ValkeyClientSummary
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
@Mapper
public interface ValkeyClientSummaryMapper {

ValkeyClientSummaryMapper INSTANCE = Mappers.getMapper(ValkeyClientSummaryMapper.class);

@Mapping(target = "clientId", source = "clientId")
@Mapping(target = "description", source = "description")
ValkeyClientSummary valkeyClientToValkeyClientSummary(ValkeyClient client);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright 2026 the original author or 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
*
* https://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 com.unitvectory.serviceauthcentral.datamodel.valkey.model;

import java.util.List;
import com.unitvectory.serviceauthcentral.datamodel.model.Authorization;
import com.unitvectory.serviceauthcentral.util.HashingUtil;

import lombok.Builder;
import lombok.NonNull;
import lombok.Value;

/**
* The Valkey Authorization
*
* @author Jared Hatfield (UnitVectorY Labs)
*/
@Value
@Builder
public class ValkeyAuthorization implements Authorization {

private String authorizationCreated;

private String subject;

private String audience;

private List<String> authorizedScopes;

public boolean matches(@NonNull String subject, @NonNull String audience) {
return subject.equals(this.subject) && audience.equals(this.audience);
}

@Override
public String getDocumentId() {
String subjectHash = HashingUtil.sha256(subject);
String audienceHash = HashingUtil.sha256(audience);
return HashingUtil.sha256(subjectHash + audienceHash);
}
}
Loading
Loading