Skip to content
Closed
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
21 changes: 16 additions & 5 deletions server/src/main/java/org/eclipse/openvsx/ExtensionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ public void reactivateExtensions(UserData user) {
var affectedExtensions = new LinkedHashSet<Extension>();
var versions = repositories.findVersionsByUser(user, false);
for (var version : versions) {
if (version.getState() == ExtensionVersion.State.DELETED) {
continue;
}
version.setActive(true);
affectedExtensions.add(version.getExtension());
}
Expand All @@ -225,10 +228,20 @@ public ResultJson deleteExtension(
var results = new ArrayList<ResultJson>();
if(repositories.isDeleteAllVersions(namespaceName, extensionName, targetVersions, user)) {
var extension = repositories.findExtension(extensionName, namespaceName);
if (extension == null || repositories.countVersions(namespaceName, extensionName) == 0) {
var message = "Extension not found: " + NamingUtil.toExtensionId(namespaceName, extensionName);
throw new ErrorResultException(message, HttpStatus.NOT_FOUND);
}
results.add(deleteExtension(user, extension));
} else {
for (var targetVersion : targetVersions) {
var extVersion = repositories.findVersion(user, targetVersion.version(), targetVersion.targetPlatform(), extensionName, namespaceName);
var extVersion = repositories.findVersion(
user,
targetVersion.version(),
targetVersion.targetPlatform(),
extensionName,
namespaceName
);
if (extVersion == null) {
var message = "Extension not found: " + NamingUtil.toLogFormat(namespaceName, extensionName, targetVersion.targetPlatform(), targetVersion.version());
throw new ErrorResultException(message, HttpStatus.NOT_FOUND);
Expand Down Expand Up @@ -275,8 +288,7 @@ protected ResultJson deleteExtension(UserData user, Extension extension) throws
cache.evictExtensionJsons(deprecatedExtension);
}

entityManager.remove(extension);
search.removeSearchEntry(extension);
updateExtension(extension);

var result = ResultJson.success("Deleted " + NamingUtil.toExtensionId(extension));
logs.logAction(user, result);
Expand All @@ -286,7 +298,6 @@ protected ResultJson deleteExtension(UserData user, Extension extension) throws
protected ResultJson deleteExtension(UserData user, ExtensionVersion extVersion) {
var extension = extVersion.getExtension();
removeExtensionVersion(extVersion);
extension.getVersions().remove(extVersion);
updateExtension(extension);

var result = ResultJson.success("Deleted " + NamingUtil.toLogFormat(extVersion));
Expand All @@ -301,6 +312,6 @@ private void removeExtensionVersion(ExtensionVersion extVersion) {

repositories.findFiles(extVersion).map(RemoveFileJobRequest::new).forEach(scheduler::enqueue);
repositories.deleteFiles(extVersion);
entityManager.remove(extVersion);
extVersion.setState(ExtensionVersion.State.DELETED);
}
}
12 changes: 4 additions & 8 deletions server/src/main/java/org/eclipse/openvsx/admin/AdminService.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,7 @@ public void deleteExtensionAndDependencies(Extension extension, UserData admin,
cache.evictExtensionJsons(deprecatedExtension);
}

entityManager.remove(extension);
search.removeSearchEntry(extension);
extensions.updateExtension(extension);
logs.logAction(admin, ResultJson.success("Deleted " + NamingUtil.toExtensionId(extension)));
}

Expand All @@ -177,7 +176,6 @@ protected void deleteExtensionAndDependencies(ExtensionVersion extVersion, UserD
}

removeExtensionVersion(extVersion);
extension.getVersions().remove(extVersion);
extensions.updateExtension(extension);
logs.logAction(admin, ResultJson.success("Deleted " + NamingUtil.toLogFormat(extVersion)));
}
Expand Down Expand Up @@ -208,7 +206,7 @@ public ResultJson deleteExtension(
public ResultJson deleteExtension(String namespaceName, String extensionName, UserData admin)
throws ErrorResultException {
var extension = repositories.findExtension(extensionName, namespaceName);
if (extension == null) {
if (extension == null || repositories.countVersions(namespaceName, extensionName) == 0) {
var extensionId = NamingUtil.toExtensionId(namespaceName, extensionName);
throw new ErrorResultException("Extension not found: " + extensionId, HttpStatus.NOT_FOUND);
}
Expand Down Expand Up @@ -259,8 +257,7 @@ protected ResultJson deleteExtension(Extension extension, UserData admin) throws
cache.evictExtensionJsons(deprecatedExtension);
}

entityManager.remove(extension);
search.removeSearchEntry(extension);
extensions.updateExtension(extension);

var result = ResultJson.success("Deleted " + NamingUtil.toExtensionId(extension));
logs.logAction(admin, result);
Expand All @@ -270,7 +267,6 @@ protected ResultJson deleteExtension(Extension extension, UserData admin) throws
protected ResultJson deleteExtension(ExtensionVersion extVersion, UserData admin) {
var extension = extVersion.getExtension();
removeExtensionVersion(extVersion);
extension.getVersions().remove(extVersion);
extensions.updateExtension(extension);

var result = ResultJson.success("Deleted " + NamingUtil.toLogFormat(extVersion));
Expand Down Expand Up @@ -323,7 +319,7 @@ private void removeExtensionVersion(ExtensionVersion extVersion) {

repositories.findFiles(extVersion).map(RemoveFileJobRequest::new).forEach(scheduler::enqueue);
repositories.deleteFiles(extVersion);
entityManager.remove(extVersion);
extVersion.setState(ExtensionVersion.State.DELETED);
}

private String userNotFoundMessage(String user) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,13 @@ public enum State {
@ManyToOne
private PersonalAccessToken publishedWith;

/**
* Legacy persisted mirror of {@link #state} kept for compatibility with active-based queries.
*
* @deprecated Use {@link #getState()} / {@link #setState(State)}. This field is planned for
* removal once repositories and SQL queries fully migrate to state-based filtering.
*/
@Deprecated(forRemoval = true)
private boolean active;

@Enumerated(EnumType.STRING)
Expand Down Expand Up @@ -322,10 +329,18 @@ public void setPublishedWith(PersonalAccessToken publishedWith) {
this.publishedWith = publishedWith;
}

/**
* @deprecated Use {@code getState() == State.ACTIVE}.
*/
@Deprecated(forRemoval = true)
public boolean isActive() {
return state == State.ACTIVE;
}

/**
* @deprecated Use {@link #setState(State)} with {@link State#ACTIVE} or {@link State#INACTIVE}.
*/
@Deprecated(forRemoval = true)
public void setActive(boolean active) {
setState(active ? State.ACTIVE : State.INACTIVE);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ private ExtensionVersion createExtensionVersion(ExtensionProcessor processor, Us

entityManager.persist(extension);
} else {
var existingVersion = repositories.findVersion(extVersion.getVersion(), extVersion.getTargetPlatform(), extension);
var existingVersion = repositories.findVersionIncludingDeleted(extVersion.getVersion(), extVersion.getTargetPlatform(), extension);
if (existingVersion != null) {
var extVersionId = NamingUtil.toLogFormat(namespaceName, extensionName, extVersion.getTargetPlatform(), extVersion.getVersion());
var message = "Extension " + extVersionId + " is already published";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -477,19 +477,22 @@ private ExtensionVersion toExtensionVersionFull(
newNamespace.setPublicId(row.get(NAMESPACE.PUBLIC_ID));
}

var user = new UserData();
user.setId(row.get(USER_DATA.ID));
user.setRole(row.get(USER_DATA.ROLE));
user.setLoginName(row.get(USER_DATA.LOGIN_NAME));
user.setFullName(row.get(USER_DATA.FULL_NAME));
user.setAvatarUrl(row.get(USER_DATA.AVATAR_URL));
user.setProviderUrl(row.get(USER_DATA.PROVIDER_URL));
user.setProvider(row.get(USER_DATA.PROVIDER));

var token = new PersonalAccessToken();
token.setUser(user);

extVersion.setPublishedWith(token);
var userId = row.get(USER_DATA.ID);
if (userId != null) {
var user = new UserData();
user.setId(userId);
user.setRole(row.get(USER_DATA.ROLE));
user.setLoginName(row.get(USER_DATA.LOGIN_NAME));
user.setFullName(row.get(USER_DATA.FULL_NAME));
user.setAvatarUrl(row.get(USER_DATA.AVATAR_URL));
user.setProviderUrl(row.get(USER_DATA.PROVIDER_URL));
user.setProvider(row.get(USER_DATA.PROVIDER));

var token = new PersonalAccessToken();
token.setUser(user);
extVersion.setPublishedWith(token);
}

extVersion.setType(ExtensionVersion.Type.REGULAR);
return extVersion;
}
Expand Down Expand Up @@ -569,6 +572,7 @@ public List<VersionTargetPlatformsJson> findTargetPlatformsGroupedByVersion(Exte
)
.from(EXTENSION_VERSION)
.where(EXTENSION_VERSION.EXTENSION_ID.eq(extension.getId()))
.and(EXTENSION_VERSION.STATE.ne(ExtensionVersion.State.DELETED.name()))
.groupBy(
EXTENSION_VERSION.SEMVER_MAJOR,
EXTENSION_VERSION.SEMVER_MINOR,
Expand Down Expand Up @@ -609,6 +613,7 @@ public List<VersionTargetPlatformsJson> findTargetPlatformsGroupedByVersion(Exte
.join(PERSONAL_ACCESS_TOKEN).on(PERSONAL_ACCESS_TOKEN.ID.eq(EXTENSION_VERSION.PUBLISHED_WITH_ID))
.where(EXTENSION_VERSION.EXTENSION_ID.eq(extension.getId()))
.and(PERSONAL_ACCESS_TOKEN.USER_DATA.eq(user.getId()))
.and(EXTENSION_VERSION.STATE.ne(ExtensionVersion.State.DELETED.name()))
.groupBy(
EXTENSION_VERSION.SEMVER_MAJOR,
EXTENSION_VERSION.SEMVER_MINOR,
Expand Down Expand Up @@ -1481,6 +1486,19 @@ public Integer count(String namespaceName, String extensionName) {
.fetchOne("count", Integer.class);
}

public Integer countNonDeleted(String namespaceName, String extensionName) {
return dsl.select(DSL.count().as("count"))
.from(EXTENSION_VERSION)
.join(EXTENSION)
.on(EXTENSION.ID.eq(EXTENSION_VERSION.EXTENSION_ID))
.join(NAMESPACE)
.on(NAMESPACE.ID.eq(EXTENSION.NAMESPACE_ID))
.where(NAMESPACE.NAME.equalIgnoreCase(namespaceName))
.and(EXTENSION.NAME.equalIgnoreCase(extensionName))
.and(EXTENSION_VERSION.STATE.ne(ExtensionVersion.State.DELETED.name()))
.fetchOne("count", Integer.class);
}

public boolean isDeleteAllVersions(String namespaceName, String extensionName, List<TargetPlatformVersionJson> targetVersions, UserData user) {
if(targetVersions.isEmpty()) {
return false;
Expand All @@ -1492,6 +1510,7 @@ public boolean isDeleteAllVersions(String namespaceName, String extensionName, L
.join(NAMESPACE).on(NAMESPACE.ID.eq(EXTENSION.NAMESPACE_ID))
.and(NAMESPACE.NAME.equalIgnoreCase(namespaceName))
.and(EXTENSION.NAME.equalIgnoreCase(extensionName))
.and(EXTENSION_VERSION.STATE.ne(ExtensionVersion.State.DELETED.name()))
.fetchOne("all", Integer.class);

var rows = targetVersions.stream().map((tv) -> DSL.row(tv.version(), tv.targetPlatform())).toArray(Row2[]::new);
Expand All @@ -1507,6 +1526,7 @@ public boolean isDeleteAllVersions(String namespaceName, String extensionName, L
.where(PERSONAL_ACCESS_TOKEN.USER_DATA.eq(user.getId()))
.and(NAMESPACE.NAME.equalIgnoreCase(namespaceName))
.and(EXTENSION.NAME.equalIgnoreCase(extensionName))
.and(EXTENSION_VERSION.STATE.ne(ExtensionVersion.State.DELETED.name()))
.fetchOne("actual", Integer.class);

return Objects.equals(actual, all);
Expand All @@ -1515,10 +1535,10 @@ public boolean isDeleteAllVersions(String namespaceName, String extensionName, L
public Page<ExtensionVersion> findChanges(LocalDateTime since, LocalDateTime before, int size, int offset) {
var conditions = new ArrayList<Condition>();
if (since != null) {
conditions.add(EXTENSION_VERSION.TIMESTAMP.greaterOrEqual(since));
conditions.add(EXTENSION_VERSION.LAST_UPDATED.greaterOrEqual(since));
}
if (before != null) {
conditions.add(EXTENSION_VERSION.TIMESTAMP.lessThan(before));
conditions.add(EXTENSION_VERSION.LAST_UPDATED.lessThan(before));
}

var countField = DSL.count();
Expand All @@ -1529,7 +1549,7 @@ public Page<ExtensionVersion> findChanges(LocalDateTime since, LocalDateTime bef

var query = baseExtensionVersionQuery();
query.addConditions(conditions);
query.addOrderBy(EXTENSION_VERSION.TIMESTAMP.desc());
query.addOrderBy(EXTENSION_VERSION.LAST_UPDATED.desc());
query.addLimit(size);
query.addOffset(offset);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,34 @@ public interface ExtensionVersionRepository extends Repository<ExtensionVersion,

ExtensionVersion findByVersionAndTargetPlatformAndExtension(String version, String targetPlatform, Extension extension);

ExtensionVersion findByVersionAndTargetPlatformAndExtensionAndStateNot(
String version,
String targetPlatform,
Extension extension,
ExtensionVersion.State state
);

ExtensionVersion findByVersionAndTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCase(String version, String targetPlatform, String extensionName, String namespace);

ExtensionVersion findByVersionAndTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCaseAndStateNot(
String version,
String targetPlatform,
String extensionName,
String namespace,
ExtensionVersion.State state
);

ExtensionVersion findByPublishedWithUserAndVersionAndTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCase(UserData user, String version, String targetPlatform, String extensionName, String namespace);

ExtensionVersion findByPublishedWithUserAndVersionAndTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCaseAndStateNot(
UserData user,
String version,
String targetPlatform,
String extensionName,
String namespace,
ExtensionVersion.State state
);

Streamable<ExtensionVersion> findByVersionAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCase(String version, String extensionName, String namespace);

Streamable<ExtensionVersion> findByPublishedWithAndActive(PersonalAccessToken publishedWith, boolean active);
Expand All @@ -41,11 +65,21 @@ public interface ExtensionVersionRepository extends Repository<ExtensionVersion,

Streamable<ExtensionVersion> findBySignatureKeyPairNotOrSignatureKeyPairIsNull(SignatureKeyPair keyPair);

@Query("select ev from ExtensionVersion ev where concat(',', ev.bundledExtensions, ',') like concat('%,', ?1, ',%')")
Streamable<ExtensionVersion> findByBundledExtensions(String extensionId);

@Query("select ev from ExtensionVersion ev where concat(',', ev.dependencies, ',') like concat('%,', ?1, ',%')")
Streamable<ExtensionVersion> findByDependencies(String extensionId);
@Query("""
select ev
from ExtensionVersion ev
where concat(',', ev.bundledExtensions, ',') like concat('%,', ?1, ',%')
and ev.state <> ?2
""")
Streamable<ExtensionVersion> findByBundledExtensionsAndStateNot(String extensionId, ExtensionVersion.State state);

@Query("""
select ev
from ExtensionVersion ev
where concat(',', ev.dependencies, ',') like concat('%,', ?1, ',%')
and ev.state <> ?2
""")
Streamable<ExtensionVersion> findByDependenciesAndStateNot(String extensionId, ExtensionVersion.State state);

@Query("select min(ev.timestamp) from ExtensionVersion ev")
LocalDateTime getOldestTimestamp();
Expand All @@ -56,5 +90,18 @@ public interface ExtensionVersionRepository extends Repository<ExtensionVersion,

Page<ExtensionVersion> findByExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCase(String extension, String namespace, Pageable page);

Page<ExtensionVersion> findByExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCaseAndActiveTrue(
String extension,
String namespace,
Pageable page
);

Page<ExtensionVersion> findByTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCase(String targetPlatform, String extension, String namespace, Pageable page);

Page<ExtensionVersion> findByTargetPlatformAndExtensionNameIgnoreCaseAndExtensionNamespaceNameIgnoreCaseAndActiveTrue(
String targetPlatform,
String extension,
String namespace,
Pageable page
);
}
Loading