package org.fluxtream.core.services.impl; import org.apache.log4j.Logger; import org.fluxtream.core.auth.AuthHelper; import org.fluxtream.core.connectors.Connector; import org.fluxtream.core.connectors.SharedConnectorFilter; import org.fluxtream.core.domain.*; import org.fluxtream.core.services.BuddiesService; import org.fluxtream.core.services.GuestService; import org.fluxtream.core.utils.JPAUtils; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.Query; import java.util.ArrayList; import java.util.List; /** * * @author Candide Kemmler (candide@fluxtream.com) */ @Service @Transactional(readOnly=true) public class BuddiesServiceImpl implements BuddiesService { Logger logger = Logger.getLogger(BuddiesServiceImpl.class); @Autowired GuestService guestService; @PersistenceContext EntityManager em; @Autowired BeanFactory beanFactory; @Override @Transactional(readOnly=false) public void addTrustedBuddy(final long guestId, final String username) { final Guest buddyGuest = guestService.getGuest(username); if (getTrustedBuddy(guestId, username)==null) { TrustedBuddy buddy = new TrustedBuddy(); buddy.guestId = guestId; buddy.buddyId = buddyGuest.getId(); em.persist(buddy); } else { logger.warn("attempt to add a coach that's already in the guest's coaching buddies list"); } } @Override @Transactional(readOnly=false) public void removeTrustedBuddy(final long guestId, final String username) { final Guest buddyGuest = guestService.getGuest(username); if (buddyGuest==null) return; final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", guestId, buddyGuest.getId()); if (trustedBuddy ==null) return; Query nativeQuery = em.createNativeQuery(String.format("DELETE sc from SharedChannels sc JOIN TrustedBuddies tb on sc.buddy_id=tb.id WHERE tb.guestId=%s", guestId)); nativeQuery.executeUpdate(); nativeQuery = em.createNativeQuery(String.format("DELETE sc from SharedConnectors sc JOIN TrustedBuddies tb on sc.buddy_id=tb.id WHERE tb.guestId=%s", guestId)); nativeQuery.executeUpdate(); Guest buddy = guestService.getGuest(username); nativeQuery = em.createNativeQuery(String.format("DELETE tb FROM TrustedBuddies tb WHERE tb.guestId=%s AND tb.buddyId=%s", guestId, buddy.getId())); nativeQuery.executeUpdate(); } @Override @Transactional(readOnly=false) public SharedConnector addSharedConnector(final long guestId, final String username, final String connectorName, final String filterJson) { final Guest buddyGuest = guestService.getGuest(username); if (buddyGuest==null) throw new RuntimeException("No such guest: " + username); final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", guestId, buddyGuest.getId()); if (trustedBuddy ==null) throw new RuntimeException("Guest doesn't have a coaching buddy for this connector"); for(SharedConnector sharedConnector : trustedBuddy.sharedConnectors) { if (sharedConnector.connectorName.equals(connectorName)) return null; } SharedConnector sharedConnector = new SharedConnector(); sharedConnector.connectorName = connectorName; sharedConnector.filterJson = filterJson; trustedBuddy.sharedConnectors.add(sharedConnector); sharedConnector.buddy = trustedBuddy; em.persist(sharedConnector); em.merge(trustedBuddy); return sharedConnector; } @Override @Transactional(readOnly=false) public void removeSharedConnector(final long guestId, final String username, final String connectorName) { final Guest buddyGuest = guestService.getGuest(username); if (buddyGuest==null) return; final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", guestId, buddyGuest.getId()); if (trustedBuddy ==null) return; SharedConnector toRemove = null; for(SharedConnector sharedConnector : trustedBuddy.sharedConnectors) { if (sharedConnector.connectorName.equals(connectorName)) { toRemove = sharedConnector; break; } } if (toRemove!=null) { trustedBuddy.sharedConnectors.remove(toRemove); toRemove.buddy = null; em.remove(toRemove); em.merge(trustedBuddy); } } @Override @Transactional(readOnly=false) public void removeSharedConnectors(long apiKeyId) { ApiKey apiKey = guestService.getApiKey(apiKeyId); String connectorName = apiKey.getConnector().getName(); String queryString = String.format("DELETE sc from SharedConnectors sc JOIN TrustedBuddies tb " + "ON sc.buddy_id=tb.id WHERE sc.connectorName=\"%s\" AND tb.guestId=%s", connectorName, apiKey.getGuestId()); Query nativeQuery = em.createNativeQuery(queryString); nativeQuery.executeUpdate(); } @Override public boolean isViewingGranted(final long guestId, final long trustingBuddyId, final String connectorName) { final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", trustingBuddyId, guestId); boolean granted = trustedBuddy.hasAccessToConnector(connectorName); return granted; } @Override public List<Guest> getTrustedBuddies(final long guestId) { final List<TrustedBuddy> coachingBuddies = JPAUtils.find(em, TrustedBuddy.class, "trustedBuddies.byGuestId", guestId); final List<Guest> coaches = new ArrayList<Guest>(); for (TrustedBuddy sharingBuddy : coachingBuddies) { final Guest buddyGuest = guestService.getGuestById(sharingBuddy.buddyId); if (buddyGuest!=null) coaches.add(buddyGuest); } return coaches; } @Override public List<Guest> getTrustingBuddies(final long guestId) { final List<TrustedBuddy> trustedBuddies = JPAUtils.find(em, TrustedBuddy.class, "trustedBuddies.byBuddyId", guestId); final List<Guest> trustingBuddies = new ArrayList<Guest>(); for (TrustedBuddy sharingBuddy : trustedBuddies) { final Guest buddyGuest = guestService.getGuestById(sharingBuddy.guestId); trustingBuddies.add(buddyGuest); } return trustingBuddies; } @Override public TrustedBuddy getTrustedBuddy(final long guestId, final String username) { final Guest buddyGuest = guestService.getGuest(username); if (buddyGuest==null) return null; final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", guestId, buddyGuest.getId()); return trustedBuddy; } @Override public TrustedBuddy getTrustedBuddy(final long guestId, final long trustingBuddyId) { final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", trustingBuddyId, guestId); return trustedBuddy; } @Override public <T extends AbstractFacet> List<T> filterFacets(final long viewerId, final long apiKeyId, final List<T> facets) { final ApiKey apiKey = guestService.getApiKey(apiKeyId); final Connector connector = apiKey.getConnector(); final boolean ownFacets = viewerId == apiKey.getGuestId(); final boolean supportsFiltering = connector.supportsFiltering(); if (ownFacets ||!supportsFiltering) return facets; else { // retrieve SharedConnector instance; SharedConnector sharedConnector = getSharedConnector(apiKeyId, viewerId); if (sharedConnector!=null) { final SharedConnectorFilter sharedConnectorFilter; try { sharedConnectorFilter = beanFactory.getBean(connector.sharedConnectorFilterClass()); return sharedConnectorFilter.filterFacets(sharedConnector, facets); } catch (Exception e) { e.printStackTrace(); } } } return facets; } @Override public SharedConnector getSharedConnector(final long apiKeyId, final long viewerId) { ApiKey apiKey = guestService.getApiKey(apiKeyId); final SharedConnector sconn = JPAUtils.findUnique(em, SharedConnector.class, "sharedConnector.byConnectorNameAndViewerId", apiKey.getConnector().getName(), viewerId); return sconn; } @Override public List<SharedConnector> getSharedConnectors(long trustedBuddyId, long trustingBuddyId) { final List<SharedConnector> conns = JPAUtils.find(em, SharedConnector.class, "sharedConnector.byTrustedBuddyId", trustingBuddyId, trustedBuddyId); return conns; } @Override public List<SharedConnector> getSharedConnectors(final ApiKey apiKey) { final List<SharedConnector> conns = JPAUtils.find(em, SharedConnector.class, "sharedConnector.byConnectorNameAndVieweeId", apiKey.getConnector().getName(), apiKey.getGuestId()); return conns; } @Override @Transactional(readOnly=false) public void setSharedConnectorFilter(final long sharedConnectorId, final String filterJson) { final SharedConnector sharedConnector = em.find(SharedConnector.class, sharedConnectorId); sharedConnector.filterJson = filterJson; em.persist(sharedConnector); } @Override public List<SharedChannel> getSharedChannels(long trustedBuddyId, long trustingBuddyId) { List<SharedChannel> sharedChannels = JPAUtils.find(em, SharedChannel.class, "sharedChannel.byTrustedBuddyId", trustingBuddyId, trustedBuddyId); return sharedChannels; } @Override public List<SharedChannel> getSharedChannels(long trustedBuddyId, long trustingBuddyId, long apiKeyId) { List<SharedChannel> sharedChannels = JPAUtils.find(em, SharedChannel.class, "sharedChannel.byApiKeyId", trustingBuddyId, trustedBuddyId, apiKeyId); return sharedChannels; } @Override @Transactional(readOnly=false) public SharedChannel addSharedChannel(long trustedBuddyId, long trustingBuddyId, long channelMappingId) { ChannelMapping channelMapping = em.find(ChannelMapping.class, channelMappingId); final TrustedBuddy trustedBuddy = JPAUtils.findUnique(em, TrustedBuddy.class, "trustedBuddies.byGuestAndBuddyId", trustingBuddyId, trustedBuddyId); List<SharedChannel> alreadyShared = JPAUtils.find(em, SharedChannel.class, "sharedChannel.byBuddyAndChannelMapping", trustingBuddyId, trustedBuddyId, channelMappingId); if (alreadyShared==null||alreadyShared.size()>0) return null; SharedChannel sharedChannel = new SharedChannel(trustedBuddy, channelMapping); em.persist(sharedChannel); return sharedChannel; } @Override @Transactional(readOnly=false) public void removeSharedChannel(long trustedBuddyId, long trustingBuddyId, long channelMappingId) { SharedChannel sharedChannel = JPAUtils.findUnique(em, SharedChannel.class, "sharedChannel.byBuddyAndChannelMapping", trustingBuddyId, trustedBuddyId, channelMappingId); em.remove(sharedChannel); } @Override @Transactional(readOnly=false) public void removeSharedChannels(long apiKeyId) { Query nativeQuery = em.createNativeQuery("delete sc from SharedChannels sc JOIN ChannelMapping cm on sc.channelMapping_id=cm.id WHERE cm.apiKeyId=" + apiKeyId); nativeQuery.executeUpdate(); } @Override @Transactional(readOnly=false) public void removeAllSharedChannels(long guestId) { Query nativeQuery = em.createNativeQuery(String.format("DELETE sc from SharedChannels sc JOIN TrustedBuddies tb on sc.buddy_id=tb.id WHERE tb.buddyId=%s OR tb.guestId=%s", guestId, guestId)); nativeQuery.executeUpdate(); } @Override @Transactional(readOnly=false) public void removeAllSharedConnectors(long guestId) { Query nativeQuery = em.createNativeQuery(String.format("DELETE sc from SharedConnectors sc JOIN TrustedBuddies tb on sc.buddy_id=tb.id WHERE tb.buddyId=%s OR tb.guestId=%s", guestId, guestId)); nativeQuery.executeUpdate(); } }