Skip to content

Commit

Permalink
Merge branch 'v116' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
yyluchkiv committed Sep 26, 2023
2 parents 7b43042 + 6ee3270 commit a98aa5f
Show file tree
Hide file tree
Showing 15 changed files with 259 additions and 80 deletions.
2 changes: 2 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

### v1.16
- Docker "servers" (tech1-framework-b2b-mongodb-server, tech1-framework-b2b-postgres-server) → GitHub Packages
- Add "create_at", "updated_at", "metadata_renew_cron", "metadata_renew_manually" → tech1_users_sessions (PostgreSQL) + liquibase
- Add "create_at", "updated_at", "metadata_renew_cron", "metadata_renew_manually" → tech1_users_sessions (MongoDB) + MIGRATION

### v1.15
- Move <distributionManagement> ossrh → "release" profile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,44 @@
import io.tech1.framework.domain.base.Username;
import io.tech1.framework.domain.http.requests.UserRequestMetadata;

import static io.tech1.framework.domain.constants.StringConstants.UNDEFINED;
import static io.tech1.framework.domain.utilities.time.TimestampUtility.getCurrentTimestamp;

public record UserSession(
boolean persisted,
UserSessionId id,
long createdAt,
long updatedAt,
Username username,
JwtAccessToken accessToken,
JwtRefreshToken refreshToken,
UserRequestMetadata metadata
UserRequestMetadata metadata,
boolean metadataRenewCron,
boolean metadataRenewManually
) {

public static UserSession ofPersisted(
UserSessionId id,
long createdAt,
long updatedAt,
Username username,
JwtAccessToken accessToken,
JwtRefreshToken refreshToken,
UserRequestMetadata metadata
UserRequestMetadata metadata,
boolean metadataRenewCron,
boolean metadataRenewManually
) {
return new UserSession(true, id, username, accessToken, refreshToken, metadata);
return new UserSession(
true,
id,
createdAt,
updatedAt,
username,
accessToken,
refreshToken,
metadata,
metadataRenewCron,
metadataRenewManually
);
}

public static UserSession ofNotPersisted(
Expand All @@ -33,6 +52,18 @@ public static UserSession ofNotPersisted(
JwtRefreshToken refreshToken,
UserRequestMetadata metadata
) {
return new UserSession(false, new UserSessionId(UNDEFINED), username, accessToken, refreshToken, metadata);
var currentTimestamp = getCurrentTimestamp();
return new UserSession(
false,
UserSessionId.undefined(),
currentTimestamp,
currentTimestamp,
username,
accessToken,
refreshToken,
metadata,
false,
false
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,7 @@ public static ResponseUserSession2 of(
UserRequestMetadata metadata
) {
var current = cookie.value().equals(accessToken.value());
var activity = "";
if (current) {
activity = "Current session";
} else {
activity = "—";
}
var activity = current ? "Current session" : "—";

var whereTuple3 = metadata.getWhereTuple3();
var whatTuple2 = metadata.getWhatTuple2();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,19 @@
import com.fasterxml.jackson.annotation.JsonValue;
import org.jetbrains.annotations.NotNull;

import static io.tech1.framework.domain.constants.StringConstants.UNDEFINED;

public record UserSessionId(@NotNull String value) {

@JsonCreator
public static UserSessionId of(String value) {
return new UserSessionId(value);
}

public static UserSessionId undefined() {
return new UserSessionId(UNDEFINED);
}

@JsonValue
@Override
public String toString() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,17 @@ public void save(JwtUser user, JwtAccessToken accessToken, JwtRefreshToken refre
var metadata = UserRequestMetadata.processing(clientIpAddr);
var session = userSessionTP.value();
if (userSessionTP.present()) {
session = ofPersisted(session.id(), session.username(), session.accessToken(), session.refreshToken(), metadata);
session = ofPersisted(
session.id(),
session.createdAt(),
session.updatedAt(),
session.username(),
session.accessToken(),
session.refreshToken(),
metadata,
session.metadataRenewCron(),
session.metadataRenewManually()
);
} else {
session = ofNotPersisted(username, accessToken, refreshToken, metadata);
}
Expand Down Expand Up @@ -94,10 +104,14 @@ public UserSession saveUserRequestMetadata(EventSessionAddUserRequestMetadata ev
var userAgentDetails = this.userAgentDetailsUtility.getUserAgentDetails(event.userAgentHeader());
var session = ofPersisted(
event.session().id(),
event.session().createdAt(),
event.session().updatedAt(),
event.session().username(),
event.session().accessToken(),
event.session().refreshToken(),
UserRequestMetadata.processed(geoLocation, userAgentDetails)
UserRequestMetadata.processed(geoLocation, userAgentDetails),
event.session().metadataRenewCron(),
event.session().metadataRenewManually()
);
return this.usersSessionsRepository.saveAs(session);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
import lombok.experimental.UtilityClass;

import static io.tech1.framework.domain.utilities.random.EntityUtility.entity;
import static io.tech1.framework.domain.utilities.random.RandomUtility.randomStringLetterOrNumbersOnly;
import static io.tech1.framework.domain.utilities.random.RandomUtility.randomUserRequestMetadata;
import static io.tech1.framework.domain.utilities.random.RandomUtility.*;
import static io.tech1.framework.domain.utilities.time.TimestampUtility.getCurrentTimestamp;
import static java.util.Collections.singletonList;

@UtilityClass
Expand Down Expand Up @@ -43,13 +43,25 @@ public static ResponseInvitationCode getInvitationCode(Username owner, Username
// =================================================================================================================
// UserSessions
// =================================================================================================================
public static UserSession session(String owner, String accessToken, String refreshToken) {
public static UserSession session(Username owner, JwtAccessToken accessToken, JwtRefreshToken refreshToken) {
return UserSession.ofPersisted(
entity(UserSessionId.class),
getCurrentTimestamp(),
getCurrentTimestamp(),
owner,
accessToken,
refreshToken,
randomUserRequestMetadata(),
randomBoolean(),
randomBoolean()
);
}

public static UserSession session(String owner, String accessToken, String refreshToken) {
return session(
Username.of(owner),
JwtAccessToken.of(accessToken),
JwtRefreshToken.of(refreshToken),
randomUserRequestMetadata()
JwtRefreshToken.of(refreshToken)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import io.tech1.framework.domain.base.Username;
import io.tech1.framework.domain.properties.base.TimeAmount;
import io.tech1.framework.domain.system.reset_server.ResetServerStatus;
import io.tech1.framework.domain.utilities.time.TimestampUtility;
import lombok.experimental.UtilityClass;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

Expand All @@ -33,6 +32,7 @@
import static io.tech1.framework.domain.utilities.random.EntityUtility.entity;
import static io.tech1.framework.domain.utilities.random.RandomUtility.*;
import static io.tech1.framework.domain.utilities.time.DateUtility.convertLocalDateTime;
import static io.tech1.framework.domain.utilities.time.TimestampUtility.getCurrentTimestamp;
import static java.time.ZoneOffset.UTC;

@UtilityClass
Expand Down Expand Up @@ -73,7 +73,7 @@ public static Claims validClaims() {
public static Claims expiredClaims() {
var claims = new DefaultClaims();
claims.setSubject(TECH1.identifier());
var currentTimestamp = TimestampUtility.getCurrentTimestamp();
var currentTimestamp = getCurrentTimestamp();
var issuedAt = new Date(currentTimestamp);
var expiration = new Date(currentTimestamp - 1000);
claims.setIssuedAt(issuedAt);
Expand All @@ -87,7 +87,17 @@ public static InvitationCode randomInvitationCode() {
}

public static UserSession randomPersistedSession() {
return UserSession.ofPersisted(entity(UserSessionId.class), randomUsername(), entity(JwtAccessToken.class), entity(JwtRefreshToken.class), randomUserRequestMetadata());
return UserSession.ofPersisted(
entity(UserSessionId.class),
getCurrentTimestamp(),
getCurrentTimestamp(),
randomUsername(),
entity(JwtAccessToken.class),
entity(JwtRefreshToken.class),
randomUserRequestMetadata(),
randomBoolean(),
randomBoolean()
);
}

public static RequestUserRegistration1 registration1() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import io.tech1.framework.b2b.base.security.jwt.utils.impl.SecurityJwtTokenUtilsImpl;
import io.tech1.framework.domain.base.Username;
import io.tech1.framework.domain.enums.Status;
import io.tech1.framework.domain.http.requests.UserRequestMetadata;
import io.tech1.framework.domain.tuples.TuplePresence;
import io.tech1.framework.properties.ApplicationFrameworkProperties;
import io.tech1.framework.properties.tests.contexts.ApplicationFrameworkPropertiesContext;
Expand All @@ -39,6 +38,7 @@
import java.util.List;
import java.util.Set;

import static io.tech1.framework.b2b.base.security.jwt.tests.random.BaseSecurityJwtDbRandomUtility.session;
import static io.tech1.framework.b2b.base.security.jwt.tests.random.BaseSecurityJwtRandomUtility.randomPersistedSession;
import static io.tech1.framework.domain.constants.StringConstants.UNDEFINED;
import static io.tech1.framework.domain.tests.constants.TestsFlagsConstants.FLAG_UNKNOWN;
Expand Down Expand Up @@ -141,7 +141,7 @@ void saveUserSessionNotNullTest() {
var username = user.username();
var accessToken = entity(JwtAccessToken.class);
var refreshToken = entity(JwtRefreshToken.class);
var userSession = UserSession.ofPersisted(entity(UserSessionId.class), username, accessToken, refreshToken, entity(UserRequestMetadata.class));
var userSession = session(username, accessToken, refreshToken);
when(this.usersSessionsRepository.isPresent(accessToken)).thenReturn(present(userSession));
when(this.usersSessionsRepository.saveAs(any(UserSession.class))).thenReturn(userSession);

Expand Down Expand Up @@ -188,7 +188,7 @@ void saveUserSessionNullTest() {
var accessToken = entity(JwtAccessToken.class);
var refreshToken = entity(JwtRefreshToken.class);
when(this.usersSessionsRepository.isPresent(accessToken)).thenReturn(TuplePresence.absent());
var userSession = UserSession.ofPersisted(entity(UserSessionId.class), username, accessToken, refreshToken, entity(UserRequestMetadata.class));
var userSession = session(username, accessToken, refreshToken);
when(this.usersSessionsRepository.saveAs(any(UserSession.class))).thenReturn(userSession);

// Act
Expand Down Expand Up @@ -279,26 +279,20 @@ void saveUserRequestMetadataTest() {
void getExpiredSessionsTest() {
// Arrange
var usernames = new HashSet<>(Set.of(TECH1));
var sessionInvalidUserSession = UserSession.ofPersisted(
entity(UserSessionId.class),
var sessionInvalidUserSession = session(
randomUsername(),
entity(JwtAccessToken.class),
new JwtRefreshToken("<invalid>"),
entity(UserRequestMetadata.class)
new JwtRefreshToken("<invalid>")
);
var sessionExpiredUserSession = UserSession.ofPersisted(
entity(UserSessionId.class),
var sessionExpiredUserSession = session(
randomUsername(),
entity(JwtAccessToken.class),
new JwtRefreshToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtdWx0aXVzZXI0MyIsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJhZG1pbiJ9LHsiYXV0aG9yaXR5IjoidXNlciJ9XSwiaWF0IjoxNjQyNzc0NTk3LCJleHAiOjE2NDI3NzQ2Mjd9.aCeKIy8uvei_c_aXoHlVhQ1N8wmjfguXgi2fWMRYVp8"),
entity(UserRequestMetadata.class)
new JwtRefreshToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtdWx0aXVzZXI0MyIsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJhZG1pbiJ9LHsiYXV0aG9yaXR5IjoidXNlciJ9XSwiaWF0IjoxNjQyNzc0NTk3LCJleHAiOjE2NDI3NzQ2Mjd9.aCeKIy8uvei_c_aXoHlVhQ1N8wmjfguXgi2fWMRYVp8")
);
var sessionAliveUserSession = UserSession.ofPersisted(
entity(UserSessionId.class),
var sessionAliveUserSession = session(
randomUsername(),
entity(JwtAccessToken.class),
new JwtRefreshToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtdWx0aXVzZXI0MyIsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJhZG1pbiJ9LHsiYXV0aG9yaXR5IjoidXNlciJ9XSwiaWF0IjoxNjQyNzc0Nzc4LCJleHAiOjQ3OTg0NDgzNzh9._BMUZR3wls5O1BYDm_4loYi3vn70GjE39Cpuqh-Z_bY"),
entity(UserRequestMetadata.class)
new JwtRefreshToken("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJtdWx0aXVzZXI0MyIsImF1dGhvcml0aWVzIjpbeyJhdXRob3JpdHkiOiJhZG1pbiJ9LHsiYXV0aG9yaXR5IjoidXNlciJ9XSwiaWF0IjoxNjQyNzc0Nzc4LCJleHAiOjQ3OTg0NDgzNzh9._BMUZR3wls5O1BYDm_4loYi3vn70GjE39Cpuqh-Z_bY")
);
var usersSessions = List.of(sessionInvalidUserSession, sessionExpiredUserSession, sessionAliveUserSession);
when(this.usersSessionsRepository.findByUsernameInAsAny(usernames)).thenReturn(usersSessions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

import io.tech1.framework.b2b.base.security.jwt.domain.db.UserSession;
import io.tech1.framework.b2b.base.security.jwt.domain.identifiers.UserSessionId;
import io.tech1.framework.b2b.base.security.jwt.domain.jwt.JwtAccessToken;
import io.tech1.framework.b2b.base.security.jwt.domain.jwt.JwtRefreshToken;
import io.tech1.framework.b2b.base.security.jwt.repositories.UsersSessionsRepository;
import io.tech1.framework.b2b.base.security.jwt.tests.contexts.TestsApplicationValidatorsContext;
import io.tech1.framework.b2b.base.security.jwt.validators.BaseUsersSessionsRequestsValidator;
Expand All @@ -22,7 +20,6 @@
import org.springframework.test.context.support.AnnotationConfigContextLoader;

import static io.tech1.framework.domain.utilities.random.EntityUtility.entity;
import static io.tech1.framework.domain.utilities.random.RandomUtility.randomUserRequestMetadata;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.catchThrowable;
import static org.mockito.Mockito.verify;
Expand Down Expand Up @@ -91,18 +88,11 @@ void validateDeleteByIdAccessDeniedTest() {
@Test
void validateDeleteByIdOkTest() {
// Arrange
var username = entity(Username.class);
var session = UserSession.ofPersisted(
entity(UserSessionId.class),
username,
entity(JwtAccessToken.class),
entity(JwtRefreshToken.class),
randomUserRequestMetadata()
);
var session = entity(UserSession.class);
when(this.usersSessionsRepository.isPresent(session.id())).thenReturn(TuplePresence.present(session));

// Act
this.componentUnderTest.validateDeleteById(username, session.id());
this.componentUnderTest.validateDeleteById(session.username(), session.id());

// Assert
verify(this.usersSessionsRepository).isPresent(session.id());
Expand Down
Loading

0 comments on commit a98aa5f

Please sign in to comment.