Skip to content

Commit

Permalink
Add delete profile context menu
Browse files Browse the repository at this point in the history
And got rid of the profiles window as well.
  • Loading branch information
zapek committed Oct 15, 2024
1 parent a105f79 commit 0141d1f
Show file tree
Hide file tree
Showing 30 changed files with 286 additions and 416 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import io.xeres.app.database.model.gxs.GxsGroupItem;
import io.xeres.app.service.ForumMessageService;
import io.xeres.app.service.IdentityService;
import io.xeres.app.xrs.service.forum.ForumRsService;
import io.xeres.app.xrs.service.forum.item.ForumMessageItem;
import io.xeres.app.xrs.service.identity.IdentityRsService;
import io.xeres.common.dto.forum.ForumGroupDTO;
import io.xeres.common.dto.forum.ForumMessageDTO;
import io.xeres.common.id.MessageId;
Expand Down Expand Up @@ -58,13 +58,13 @@
public class ForumController
{
private final ForumRsService forumRsService;
private final IdentityRsService identityRsService;
private final IdentityService identityService;
private final ForumMessageService forumMessageService;

public ForumController(ForumRsService forumRsService, IdentityRsService identityRsService, ForumMessageService forumMessageService)
public ForumController(ForumRsService forumRsService, IdentityService identityService, ForumMessageService forumMessageService)
{
this.forumRsService = forumRsService;
this.identityRsService = identityRsService;
this.identityService = identityService;
this.forumMessageService = forumMessageService;
}

Expand All @@ -81,7 +81,7 @@ public List<ForumGroupDTO> getForumGroups()
@ApiResponse(responseCode = "201", description = "Forum created successfully", headers = @Header(name = "Forum", description = "The location of the created forum", schema = @Schema(type = "string")))
public ResponseEntity<Void> createForumGroup(@Valid @RequestBody CreateForumGroupRequest createForumGroupRequest)
{
var ownIdentity = identityRsService.getOwnIdentity();
var ownIdentity = identityService.getOwnIdentity();
var id = forumRsService.createForumGroup(ownIdentity.getGxsId(), createForumGroupRequest.name(), createForumGroupRequest.description());

var location = ServletUriComponentsBuilder.fromCurrentRequest().replacePath(FORUMS_PATH + "/groups/{id}").buildAndExpand(id).toUri();
Expand Down Expand Up @@ -131,7 +131,7 @@ public ForumMessageDTO getForumMessage(@PathVariable long messageId)
var forumMessage = forumRsService.findMessageById(messageId);
Objects.requireNonNull(forumMessage, "MessageId " + messageId + " not found");

var author = identityRsService.findByGxsId(forumMessage.getAuthorId());
var author = identityService.findByGxsId(forumMessage.getAuthorId());

HashSet<MessageId> messageSet = HashSet.newHashSet(2); // they can be null so no Set.of() possible
CollectionUtils.addIgnoreNull(messageSet, forumMessage.getOriginalMessageId());
Expand All @@ -153,7 +153,7 @@ public ForumMessageDTO getForumMessage(@PathVariable long messageId)
@ApiResponse(responseCode = "201", description = "Forum message created successfully", headers = @Header(name = "Message", description = "The location of the created message", schema = @Schema(type = "string")))
public ResponseEntity<Void> createForumMessage(@Valid @RequestBody CreateForumMessageRequest createMessageRequest)
{
var ownIdentity = identityRsService.getOwnIdentity();
var ownIdentity = identityService.getOwnIdentity();
var id = forumRsService.createForumMessage(
ownIdentity,
createMessageRequest.forumId(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.xeres.app.service.IdentityService;
import io.xeres.app.xrs.service.identity.IdentityRsService;
import io.xeres.common.dto.identity.IdentityDTO;
import io.xeres.common.id.GxsId;
Expand Down Expand Up @@ -55,10 +56,12 @@
@RequestMapping(value = IDENTITIES_PATH, produces = MediaType.APPLICATION_JSON_VALUE)
public class IdentityController
{
private final IdentityService identityService;
private final IdentityRsService identityRsService;

public IdentityController(IdentityRsService identityRsService)
public IdentityController(IdentityService identityService, IdentityRsService identityRsService)
{
this.identityService = identityService;
this.identityRsService = identityRsService;
}

Expand All @@ -68,7 +71,7 @@ public IdentityController(IdentityRsService identityRsService)
@ApiResponse(responseCode = "404", description = "Identity not found", content = @Content(schema = @Schema(implementation = Error.class)))
public IdentityDTO findIdentityById(@PathVariable long id)
{
return toDTO(identityRsService.findById(id).orElseThrow());
return toDTO(identityService.findById(id).orElseThrow());
}

@GetMapping(value = "/{id}/image", produces = MediaType.IMAGE_JPEG_VALUE)
Expand All @@ -78,7 +81,7 @@ public IdentityDTO findIdentityById(@PathVariable long id)
@ApiResponse(responseCode = "404", description = "Identity not found", content = @Content(schema = @Schema(implementation = Error.class)))
public ResponseEntity<InputStreamResource> downloadIdentityImage(@PathVariable long id)
{
var identity = identityRsService.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); // Bypass the global controller advice because it only knows about application/json mimetype
var identity = identityService.findById(id).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND)); // Bypass the global controller advice because it only knows about application/json mimetype
var imageType = ImageDetectionUtils.getImageMimeType(identity.getImage());
if (imageType == null)
{
Expand Down Expand Up @@ -122,17 +125,17 @@ public List<IdentityDTO> findIdentities(
{
if (isNotBlank(name))
{
return toDTOs(identityRsService.findAllByName(name));
return toDTOs(identityService.findAllByName(name));
}
else if (isNotBlank(gxsId))
{
var identity = identityRsService.findByGxsId(GxsId.fromString(gxsId));
var identity = identityService.findByGxsId(GxsId.fromString(gxsId));
return identity.map(id -> List.of(toDTO(id))).orElse(Collections.emptyList());
}
else if (type != null)
{
return toDTOs(identityRsService.findAllByType(type));
return toDTOs(identityService.findAllByType(type));
}
return toDTOs(identityRsService.getAll());
return toDTOs(identityService.getAll());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.xeres.app.crypto.rsid.RSId;
import io.xeres.app.database.model.profile.Profile;
import io.xeres.app.job.PeerConnectionJob;
import io.xeres.app.service.IdentityService;
import io.xeres.app.service.ProfileService;
import io.xeres.app.service.notification.status.StatusNotificationService;
import io.xeres.common.dto.profile.ProfileDTO;
Expand Down Expand Up @@ -58,13 +59,15 @@
public class ProfileController
{
private final ProfileService profileService;
private final IdentityService identityService;

private final PeerConnectionJob peerConnectionJob;
private final StatusNotificationService statusNotificationService;

public ProfileController(ProfileService profileService, PeerConnectionJob peerConnectionJob, StatusNotificationService statusNotificationService)
public ProfileController(ProfileService profileService, IdentityService identityService, PeerConnectionJob peerConnectionJob, StatusNotificationService statusNotificationService)
{
this.profileService = profileService;
this.identityService = identityService;
this.peerConnectionJob = peerConnectionJob;
this.statusNotificationService = statusNotificationService;
}
Expand Down Expand Up @@ -160,8 +163,9 @@ public void deleteProfile(@PathVariable long id)
{
throw new UnprocessableEntityException("The main profile cannot be deleted");
}
identityService.removeAllLinksToProfile(id);
profileService.deleteProfile(id);

statusNotificationService.decrementTotalUsers();
statusNotificationService.decrementTotalUsers(); // XXX: wrong, a profile can have many locations
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,6 @@ public interface GxsIdentityRepository extends JpaRepository<IdentityGroupItem,
List<IdentityGroupItem> findAllBySubscribedIsTrueAndPublishedAfter(Instant since);

List<IdentityGroupItem> findAllByNextValidationNotNullAndNextValidationBeforeOrderByNextValidationDesc(Instant now, Limit limit);

List<IdentityGroupItem> findAllByProfileId(long profileId);
}
9 changes: 4 additions & 5 deletions app/src/main/java/io/xeres/app/service/ContactService.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
package io.xeres.app.service;

import io.xeres.app.database.model.profile.Profile;
import io.xeres.app.xrs.service.identity.IdentityRsService;
import io.xeres.app.xrs.service.identity.IdentityServiceStorage;
import io.xeres.app.xrs.service.identity.item.IdentityGroupItem;
import io.xeres.common.rest.contact.Contact;
Expand All @@ -36,12 +35,12 @@
public class ContactService
{
private final ProfileService profileService;
private final IdentityRsService identityRsService;
private final IdentityService identityService;

public ContactService(@Lazy ProfileService profileService, @Lazy IdentityRsService identityRsService)
public ContactService(@Lazy ProfileService profileService, IdentityService identityService)
{
this.profileService = profileService;
this.identityRsService = identityRsService;
this.identityService = identityService;
}

@Transactional(readOnly = true)
Expand All @@ -50,7 +49,7 @@ public List<Contact> getContacts()
// XXX: this merges probably a bit too much (what if several identities point to the same profile? what if the identity name is different from the profile name?)
var profiles = profileService.getAllProfiles().stream()
.collect(Collectors.toMap(Profile::getId, profile -> profile));
var identities = identityRsService.getAll();
var identities = identityService.getAll();
var profilesIdsToRemove = identities.stream()
.filter(identity -> identity.getProfile() != null)
.map(identity -> identity.getProfile().getId())
Expand Down
11 changes: 5 additions & 6 deletions app/src/main/java/io/xeres/app/service/ForumMessageService.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import io.xeres.app.database.model.gxs.GxsGroupItem;
import io.xeres.app.xrs.service.forum.ForumRsService;
import io.xeres.app.xrs.service.forum.item.ForumMessageItem;
import io.xeres.app.xrs.service.identity.IdentityRsService;
import io.xeres.app.xrs.service.identity.item.IdentityGroupItem;
import io.xeres.common.id.GxsId;
import io.xeres.common.id.MessageId;
Expand All @@ -44,13 +43,13 @@
public class ForumMessageService
{
private final ForumRsService forumRsService;
private final IdentityRsService identityRsService;
private final IdentityService identityService;

// XXX: try to fix the circular dependency injection
public ForumMessageService(@Lazy ForumRsService forumRsService, IdentityRsService identityRsService)
public ForumMessageService(@Lazy ForumRsService forumRsService, IdentityService identityService)
{
this.forumRsService = forumRsService;
this.identityRsService = identityRsService;
this.identityService = identityService;
}

public Map<GxsId, IdentityGroupItem> getAuthorsMapFromSummaries(List<ForumMessageItemSummary> forumMessages)
Expand All @@ -59,7 +58,7 @@ public Map<GxsId, IdentityGroupItem> getAuthorsMapFromSummaries(List<ForumMessag
.map(ForumMessageItemSummary::getAuthorId)
.collect(Collectors.toSet());

return identityRsService.findAll(authors).stream()
return identityService.findAll(authors).stream()
.collect(Collectors.toMap(GxsGroupItem::getGxsId, Function.identity()));
}

Expand All @@ -69,7 +68,7 @@ public Map<GxsId, IdentityGroupItem> getAuthorsMapFromMessages(List<ForumMessage
.map(ForumMessageItem::getAuthorId)
.collect(Collectors.toSet());

return identityRsService.findAll(authors).stream()
return identityService.findAll(authors).stream()
.collect(Collectors.toMap(GxsGroupItem::getGxsId, Function.identity()));
}

Expand Down
123 changes: 123 additions & 0 deletions app/src/main/java/io/xeres/app/service/IdentityService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2024 by David Gerber - https://zapek.com
*
* This file is part of Xeres.
*
* Xeres is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Xeres is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Xeres. If not, see <http://www.gnu.org/licenses/>.
*/

package io.xeres.app.service;

import io.xeres.app.crypto.rsa.RSA;
import io.xeres.app.database.repository.GxsIdentityRepository;
import io.xeres.app.xrs.service.identity.item.IdentityGroupItem;
import io.xeres.common.dto.identity.IdentityConstants;
import io.xeres.common.id.GxsId;
import io.xeres.common.identity.Type;
import org.springframework.data.domain.Limit;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.List;
import java.util.Optional;
import java.util.Set;

@Service
public class IdentityService
{
private final GxsIdentityRepository gxsIdentityRepository;

public IdentityService(GxsIdentityRepository gxsIdentityRepository)
{
this.gxsIdentityRepository = gxsIdentityRepository;
}

public Optional<IdentityGroupItem> findById(long id)
{
return gxsIdentityRepository.findById(id);
}

public boolean hasOwnIdentity()
{
return gxsIdentityRepository.findById(IdentityConstants.OWN_IDENTITY_ID).isPresent();
}

public IdentityGroupItem getOwnIdentity()
{
return gxsIdentityRepository.findById(IdentityConstants.OWN_IDENTITY_ID).orElseThrow(() -> new IllegalStateException("Missing own gxsId"));
}

public List<IdentityGroupItem> findAllByName(String name)
{
return gxsIdentityRepository.findAllByName(name);
}

public Optional<IdentityGroupItem> findByGxsId(GxsId gxsId)
{
return gxsIdentityRepository.findByGxsId(gxsId);
}

public List<IdentityGroupItem> findAllByType(Type type)
{
return gxsIdentityRepository.findAllByType(type);
}

public List<IdentityGroupItem> getAll()
{
return gxsIdentityRepository.findAll();
}

public List<IdentityGroupItem> findAll(Set<GxsId> gxsIds)
{
return gxsIdentityRepository.findAllByGxsIdIn(gxsIds);
}

public List<IdentityGroupItem> findAllSubscribedAndPublishedSince(Instant since)
{
return gxsIdentityRepository.findAllBySubscribedIsTrueAndPublishedAfter(since);
}

@Transactional
public IdentityGroupItem save(IdentityGroupItem identityGroupItem)
{
return gxsIdentityRepository.save(identityGroupItem);
}

public List<IdentityGroupItem> findIdentitiesToValidate(int limit)
{
return gxsIdentityRepository.findAllByNextValidationNotNullAndNextValidationBeforeOrderByNextValidationDesc(Instant.now(), limit <= 0 ? Limit.unlimited() : Limit.of(limit));
}

public void delete(IdentityGroupItem identityGroupItem)
{
gxsIdentityRepository.delete(identityGroupItem);
}

@Transactional(propagation = Propagation.NEVER)
public byte[] signData(IdentityGroupItem identityGroupItem, byte[] data)
{
return RSA.sign(data, identityGroupItem.getAdminPrivateKey());
}

@Transactional
public void removeAllLinksToProfile(long profileId)
{
var allByProfileId = gxsIdentityRepository.findAllByProfileId(profileId);
allByProfileId.forEach(identityGroupItem -> identityGroupItem.setProfile(null));
// XXX: we should possibly refresh the list with contactNotificationService...
gxsIdentityRepository.saveAll(allByProfileId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ public void markAllConnectionsAsDisconnected()
locationRepository.putAllConnectedToFalse();
}

@Transactional
public void markAsAvailable()
{
var ownLocation = findOwnLocation().orElseThrow();
Expand Down
Loading

0 comments on commit 0141d1f

Please sign in to comment.