/** * Copyright (c) 2009--2016 Red Hat, Inc. * * This software is licensed to you under the GNU General Public License, * version 2 (GPLv2). There is NO WARRANTY for this software, express or * implied, including the implied warranties of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 * along with this software; if not, see * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. * * Red Hat trademarks are not licensed under GPLv2. No permission is * granted to use or replicate Red Hat trademarks that are incorporated * in this software or its documentation. */ package com.redhat.rhn.frontend.xmlrpc.channel.software; import com.redhat.rhn.FaultException; import com.redhat.rhn.common.client.InvalidCertificateException; import com.redhat.rhn.common.db.datasource.DataResult; import com.redhat.rhn.common.db.datasource.ModeFactory; import com.redhat.rhn.common.db.datasource.SelectMode; import com.redhat.rhn.common.db.datasource.WriteMode; import com.redhat.rhn.common.hibernate.LookupException; import com.redhat.rhn.common.messaging.MessageQueue; import com.redhat.rhn.common.security.PermissionException; import com.redhat.rhn.domain.channel.Channel; import com.redhat.rhn.domain.channel.ChannelArch; import com.redhat.rhn.domain.channel.ChannelFactory; import com.redhat.rhn.domain.channel.ContentSource; import com.redhat.rhn.domain.channel.ContentSourceFilter; import com.redhat.rhn.domain.channel.InvalidChannelRoleException; import com.redhat.rhn.domain.errata.Errata; import com.redhat.rhn.domain.errata.ErrataFactory; import com.redhat.rhn.domain.errata.impl.PublishedClonedErrata; import com.redhat.rhn.domain.kickstart.KickstartFactory; import com.redhat.rhn.domain.kickstart.crypto.CryptoKey; import com.redhat.rhn.domain.org.Org; import com.redhat.rhn.domain.rhnpackage.Package; import com.redhat.rhn.domain.rhnpackage.PackageFactory; import com.redhat.rhn.domain.role.Role; import com.redhat.rhn.domain.role.RoleFactory; import com.redhat.rhn.domain.server.Server; import com.redhat.rhn.domain.server.ServerFactory; import com.redhat.rhn.domain.user.User; import com.redhat.rhn.frontend.dto.ErrataOverview; import com.redhat.rhn.frontend.dto.PackageDto; import com.redhat.rhn.frontend.dto.PackageOverview; import com.redhat.rhn.frontend.events.UpdateErrataCacheEvent; import com.redhat.rhn.frontend.xmlrpc.BaseHandler; import com.redhat.rhn.frontend.xmlrpc.DuplicateChannelLabelException; import com.redhat.rhn.frontend.xmlrpc.InvalidChannelArchException; import com.redhat.rhn.frontend.xmlrpc.InvalidChannelException; import com.redhat.rhn.frontend.xmlrpc.InvalidChannelLabelException; import com.redhat.rhn.frontend.xmlrpc.InvalidChannelNameException; import com.redhat.rhn.frontend.xmlrpc.InvalidParameterException; import com.redhat.rhn.frontend.xmlrpc.InvalidParentChannelException; import com.redhat.rhn.frontend.xmlrpc.MultipleBaseChannelException; import com.redhat.rhn.frontend.xmlrpc.NoSuchChannelException; import com.redhat.rhn.frontend.xmlrpc.NoSuchContentSourceException; import com.redhat.rhn.frontend.xmlrpc.NoSuchPackageException; import com.redhat.rhn.frontend.xmlrpc.PermissionCheckFailureException; import com.redhat.rhn.frontend.xmlrpc.channel.repo.InvalidRepoLabelException; import com.redhat.rhn.frontend.xmlrpc.channel.repo.InvalidRepoUrlException; import com.redhat.rhn.frontend.xmlrpc.system.SystemHandler; import com.redhat.rhn.frontend.xmlrpc.system.XmlRpcSystemHelper; import com.redhat.rhn.frontend.xmlrpc.user.XmlRpcUserHelper; import com.redhat.rhn.manager.channel.ChannelEditor; import com.redhat.rhn.manager.channel.ChannelManager; import com.redhat.rhn.manager.channel.CloneChannelCommand; import com.redhat.rhn.manager.channel.CreateChannelCommand; import com.redhat.rhn.manager.channel.UpdateChannelCommand; import com.redhat.rhn.manager.channel.repo.BaseRepoCommand; import com.redhat.rhn.manager.channel.repo.CreateRepoCommand; import com.redhat.rhn.manager.channel.repo.EditRepoCommand; import com.redhat.rhn.manager.errata.ErrataManager; import com.redhat.rhn.manager.errata.cache.ErrataCacheManager; import com.redhat.rhn.manager.kickstart.crypto.NoSuchCryptoKeyException; import com.redhat.rhn.manager.system.SystemManager; import com.redhat.rhn.manager.user.UserManager; import com.redhat.rhn.taskomatic.TaskomaticApi; import com.redhat.rhn.taskomatic.task.TaskConstants; import com.redhat.rhn.taskomatic.task.errata.ErrataCacheWorker; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.time.StopWatch; import org.apache.log4j.Logger; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * ChannelSoftwareHandler * @version $Rev$ * @xmlrpc.namespace channel.software * @xmlrpc.doc Provides methods to access and modify many aspects of a channel. */ public class ChannelSoftwareHandler extends BaseHandler { private static Logger log = Logger.getLogger(ChannelSoftwareHandler.class); /** * If you have satellite-synced a new channel then Red Hat Errata * will have been updated with the packages that are in the newly synced * channel. A cloned erratum will not have been automatically updated * however. If you cloned a channel that includes those cloned errata and * should include the new packages, they will not be included when they * should. This method lists the errata that will be updated if you run the * syncErrata method. * @param loggedInUser The current user * @param channelLabel Label of cloned channel to check * @return List of errata that are missing packages * * @xmlrpc.doc If you have satellite-synced a new channel then Red Hat * Errata will have been updated with the packages that are in the newly * synced channel. A cloned erratum will not have been automatically updated * however. If you cloned a channel that includes those cloned errata and * should include the new packages, they will not be included when they * should. This method lists the errata that will be updated if you run the * syncErrata method. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to update") * @xmlrpc.returntype * #array() * $ErrataOverviewSerializer * #array_end() */ public List<ErrataOverview> listErrataNeedingSync(User loggedInUser, String channelLabel) { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelManager.listErrataNeedingResync(channel, loggedInUser); } /** * If you have satellite-synced a new channel then Red Hat Errata * will have been updated with the packages that are in the newly synced * channel. A cloned erratum will not have been automatically updated * however. If you cloned a channel that includes those cloned errata and * should include the new packages, they will not be included when they * should. This method updates all the errata in the given cloned channel * with packages that have recently been added, and ensures that all the * packages you expect are in the channel. * @param loggedInUser The current user * @param channelLabel Label of cloned channel to update * @return Returns 1 if successfull, FaultException otherwise * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc If you have satellite-synced a new channel then Red Hat * Errata will have been updated with the packages that are in the newly * synced channel. A cloned erratum will not have been automatically updated * however. If you cloned a channel that includes those cloned errata and * should include the new packages, they will not be included when they * should. This method updates all the errata in the given cloned channel * with packages that have recently been added, and ensures that all the * packages you expect are in the channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to update") * @xmlrpc.returntype #return_int_success() */ public Integer syncErrata(User loggedInUser, String channelLabel) { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); //Verify permissions if (!(UserManager.verifyChannelAdmin(loggedInUser, channel) || loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN))) { throw new PermissionCheckFailureException(); } List<ErrataOverview> errata = ChannelManager.listErrataNeedingResync(channel, loggedInUser); List<Long> eids = new ArrayList<Long>(); for (ErrataOverview e : errata) { eids.add(e.getId()); } List<PackageOverview> packages = ChannelManager .listErrataPackagesForResync(channel, loggedInUser); List<Long> pids = new ArrayList<Long>(); for (PackageOverview p : packages) { pids.add(p.getId()); } ChannelEditor.getInstance().addPackages(loggedInUser, channel, pids); for (Long eid : eids) { Errata e = ErrataManager.lookupErrata(eid, loggedInUser); if (e.isPublished() && e.isCloned()) { ErrataFactory.syncErrataDetails((PublishedClonedErrata) e); } else { log.fatal("Tried to sync errata with id " + eid + " But it was not published or was not cloned"); } } return 1; } /** * Lists the packages with the latest version (including release and epoch) * for the unique package names * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @return Lists the packages with the largest version (including release * and epoch) for the unique package names * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc Lists the packages with the latest version (including release and * epoch) for the given channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * #array() * #struct("package") * #prop("string", "name") * #prop("string", "version") * #prop("string", "release") * #prop("string", "epoch") * #prop("int", "id") * #prop("string", "arch_label") * #struct_end() * #array_end() */ public Object[] listLatestPackages(User loggedInUser, String channelLabel) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); List<Map<String, Object>> pkgs = ChannelManager.latestPackagesInChannel(channel); return pkgs.toArray(); } /** * Lists all packages in the channel, regardless of version, between the * given dates. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @param endDate last modified end date (as a string) * @return all packages in the channel, regardless of version between the * given dates. * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc Lists all packages in the channel, regardless of package version, * between the given dates. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param($date, "startDate") * @xmlrpc.param #param($date, "endDate") * @xmlrpc.returntype * #array() * $PackageDtoSerializer * #array_end() */ public List<PackageDto> listAllPackages(User loggedInUser, String channelLabel, Date startDate, Date endDate) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelManager.listAllPackages(channel, startDate, endDate); } /** * Lists all packages in the channel, regardless of version whose last * modified date is greater than given date. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @return all packages in the channel, regardless of version whose last * modified date is greater than given date. * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc Lists all packages in the channel, regardless of version whose last * modified date is greater than given date. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param($date, "startDate") * @xmlrpc.returntype * #array() * $PackageDtoSerializer * #array_end() */ public List<PackageDto> listAllPackages(User loggedInUser, String channelLabel, Date startDate) throws NoSuchChannelException { return listAllPackages(loggedInUser, channelLabel, startDate, null); } /** * Lists all packages in the channel, regardless of version * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @return all packages in the channel, regardless of version * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc Lists all packages in the channel, regardless of the package version * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * #array() * $PackageDtoSerializer * #array_end() */ public List<PackageDto> listAllPackages(User loggedInUser, String channelLabel) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelManager.listAllPackages(channel); } /** * Lists all packages in the channel, regardless of version, between the * given dates. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @param endDate last modified end date (as a string) * @return all packages in the channel, regardless of version between the * given dates. * @throws NoSuchChannelException thrown if no channel is found. * @deprecated being replaced by listAllPackages(string sessionKey, * string channelLabel, dateTime.iso8601 startDate, dateTime.iso8601 endDate) * * @xmlrpc.doc Lists all packages in the channel, regardless of package version, * between the given dates. * Example Date: '2008-08-20 08:00:00' * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.param #param("string", "endDate") * @xmlrpc.returntype * #array() * $PackageDtoSerializer * #array_end() */ @Deprecated public List<PackageDto> listAllPackages(User loggedInUser, String channelLabel, String startDate, String endDate) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelManager.listAllPackages(channel, startDate, endDate); } /** * Lists all packages in the channel, regardless of version whose last * modified date is greater than given date. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @return all packages in the channel, regardless of version whose last * modified date is greater than given date. * @throws NoSuchChannelException thrown if no channel is found. * @deprecated being replaced by listAllPackages(string sessionKey, * string channelLabel, dateTime.iso8601 startDate) * * @xmlrpc.doc Lists all packages in the channel, regardless of version whose last * modified date is greater than given date. Example Date: '2008-08-20 08:00:00' * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.returntype * #array() * $PackageDtoSerializer * #array_end() */ @Deprecated public List<PackageDto> listAllPackages(User loggedInUser, String channelLabel, String startDate) throws NoSuchChannelException { return listAllPackages(loggedInUser, channelLabel, startDate, null); } /** * Lists all packages in the channel, regardless of version, between the * given dates. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @param endDate last modified end date (as a string) * @return all packages in the channel, regardless of version between the * given dates. * @throws NoSuchChannelException thrown if there is the channel is not * found. * @deprecated being replaced by listAllPackages(string sessionKey, * string channelLabel, dateTime.iso8601 startDate, dateTime.iso8601 endDate) * * @xmlrpc.doc Lists all packages in the channel, regardless of the package version, * between the given dates. Example Date: '2008-08-20 08:00:00' * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.param #param("string", "endDate") * @xmlrpc.returntype * #array() * #struct("package") * #prop("string", "name") * #prop("string", "version") * #prop("string", "release") * #prop("string", "epoch") * #prop("string", "id") * #prop("string", "arch_label") * #prop("string", "last_modified") * #struct_end() * #array_end() */ @Deprecated public Object[] listAllPackagesByDate(User loggedInUser, String channelLabel, String startDate, String endDate) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); List<Map<String, Object>> pkgs = ChannelManager.listAllPackagesByDate(channel, startDate, endDate); return pkgs.toArray(); } /** * Lists all packages in the channel, regardless of version, whose last * modified date is greater than given date. * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @param startDate last modified begin date (as a string) * @return all packages in the channel, regardless of version whose last * modified date is greater than given date. * @throws NoSuchChannelException thrown if no channel is found. * @deprecated being replaced by listAllPackages(string sessionKey, * string channelLabel, dateTime.iso8601 startDate) * * @xmlrpc.doc Lists all packages in the channel, regardless of the package version, * whose last modified date is greater than given date. * Example Date: '2008-08-20 08:00:00' * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.returntype * #array() * #struct("package") * #prop("string", "name") * #prop("string", "version") * #prop("string", "release") * #prop("string", "epoch") * #prop("string", "id") * #prop("string", "arch_label") * #prop("string", "last_modified") * #struct_end() * #array_end() */ @Deprecated public Object[] listAllPackagesByDate(User loggedInUser, String channelLabel, String startDate) throws NoSuchChannelException { return listAllPackagesByDate(loggedInUser, channelLabel, startDate, null); } /** * Lists all packages in the channel, regardless of version * @param loggedInUser The current user * @param channelLabel Label of channel whose package are sought. * @return all packages in the channel, regardless of version between the * given dates. * @throws NoSuchChannelException thrown if no channel is found. * @deprecated being replaced by listAllPackages(string sessionKey, * string channelLabel) * * @xmlrpc.doc Lists all packages in the channel, regardless of the package version * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * #array() * #struct("package") * #prop("string", "name") * #prop("string", "version") * #prop("string", "release") * #prop("string", "epoch") * #prop("string", "id") * #prop("string", "arch_label") * #prop("string", "last_modified") * #struct_end() * #array_end() */ @Deprecated public Object[] listAllPackagesByDate(User loggedInUser, String channelLabel) throws NoSuchChannelException { return listAllPackagesByDate(loggedInUser, channelLabel, null, null); } /** * Return Lists potential software channel arches that can be created * @param loggedInUser The current user * @return Lists potential software channel arches that can be created * @throws PermissionCheckFailureException thrown if the user is not a * channel admin * * @xmlrpc.doc Lists the potential software channel architectures that can be created * @xmlrpc.param #session_key() * @xmlrpc.returntype * #array() * $ChannelArchSerializer * #array_end() */ public List<ChannelArch> listArches(User loggedInUser) throws PermissionCheckFailureException { if (!loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN)) { throw new PermissionCheckFailureException(); } return ChannelManager.getChannelArchitectures(); } /** * Deletes a software channel * @param loggedInUser The current user * @param channelLabel Label of channel to be deleted. * @return 1 if Channel was successfully deleted. * @throws PermissionCheckFailureException thrown if User has no access to * delete channel. * @throws NoSuchChannelException thrown if label is invalid. * * @xmlrpc.doc Deletes a custom software channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to delete") * @xmlrpc.returntype #return_int_success() */ public int delete(User loggedInUser, String channelLabel) throws PermissionCheckFailureException, NoSuchChannelException { try { ChannelManager.deleteChannel(loggedInUser, channelLabel); } catch (InvalidChannelRoleException e) { throw new PermissionCheckFailureException(e); } catch (PermissionException e) { throw new FaultException(1234, "permissions", e.getMessage(), new String[] {}); } return 1; } /** * Returns whether the channel is subscribable by any user in the * organization. * @param loggedInUser The current user * @param channelLabel Label of channel to be deleted. * @return 1 if the Channel is globally subscribable, 0 otherwise. * * @xmlrpc.doc Returns whether the channel is subscribable by any user * in the organization * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype int - 1 if true, 0 otherwise */ public int isGloballySubscribable(User loggedInUser, String channelLabel) { // TODO: this should return a boolean NOT an int // Make sure the channel exists: lookupChannelByLabel(loggedInUser, channelLabel); return ChannelManager.isGloballySubscribable(loggedInUser, channelLabel) ? 1 : 0; } /** * Returns the details of the given channel as a map with the following * keys: * @param loggedInUser The current user * @param channelLabel Label of channel whose details are sought. * @throws NoSuchChannelException thrown if no channel is found. * @return the channel requested. * * @xmlrpc.doc Returns details of the given channel as a map * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * $ChannelSerializer */ public Channel getDetails(User loggedInUser, String channelLabel) throws NoSuchChannelException { return lookupChannelByLabel(loggedInUser, channelLabel); } /** * Returns the requested channel * @param loggedInUser The current user * @param id - id of channel wanted * @throws NoSuchChannelException thrown if no channel is found. * @return the channel requested. * * @xmlrpc.doc Returns details of the given channel as a map * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "channel to query") * @xmlrpc.returntype * $ChannelSerializer */ public Channel getDetails(User loggedInUser, Integer id) throws NoSuchChannelException { return lookupChannelById(loggedInUser, id.longValue()); } /** * Allows to modify channel attributes * @param loggedInUser The current user * @param channelId id of channel to be modified * @param details map of channel attributes to be changed * @return 1 if edit was successful, exception thrown otherwise * * @xmlrpc.doc Allows to modify channel attributes * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "channelId", "channel id") * @xmlrpc.param * #struct("channel_map") * #prop_desc("string", "checksum_label", "new channel repository checksum label * (optional)") * #prop_desc("string", "name", "new channel name (optional)") * #prop_desc("string", "summary", "new channel summary (optional)") * #prop_desc("string", "description", "new channel description (optional)") * #prop_desc("string", "maintainer_name", "new channel maintainer name * (optional)") * #prop_desc("string", "maintainer_email", "new channel email address * (optional)") * #prop_desc("string", "maintainer_phone", "new channel phone number (optional)") * #prop_desc("string", "gpg_key_url", "new channel gpg key url (optional)") * #prop_desc("string", "gpg_key_id", "new channel gpg key id (optional)") * #prop_desc("string", "gpg_key_fp", "new channel gpg key fingerprint * (optional)") * #struct_end() *@xmlrpc.returntype #return_int_success() */ public int setDetails(User loggedInUser, Integer channelId, Map<String, String> details) { Channel channel = lookupChannelById(loggedInUser, channelId.longValue()); Set<String> validKeys = new HashSet<String>(); validKeys.add("checksum_label"); validKeys.add("name"); validKeys.add("summary"); validKeys.add("description"); validKeys.add("maintainer_name"); validKeys.add("maintainer_email"); validKeys.add("maintainer_phone"); validKeys.add("gpg_key_url"); validKeys.add("gpg_key_id"); validKeys.add("gpg_key_fp"); validateMap(validKeys, details); UpdateChannelCommand ucc = new UpdateChannelCommand(loggedInUser, channel); if (details.containsKey("checksum_label")) { ucc.setChecksumLabel(details.get("checksum_label")); } if (details.containsKey("name")) { ucc.setName(details.get("name")); } if (details.containsKey("summary")) { ucc.setSummary(details.get("summary")); } if (details.containsKey("description")) { ucc.setDescription(details.get("description")); } if (details.containsKey("maintainer_name")) { ucc.setMaintainerName(details.get("maintainer_name")); } if (details.containsKey("maintainer_email")) { ucc.setMaintainerEmail(details.get("maintainer_email")); } if (details.containsKey("maintainer_phone")) { ucc.setMaintainerPhone(details.get("maintainer_phone")); } if (details.containsKey("gpg_key_url")) { ucc.setGpgKeyUrl(details.get("gpg_key_url")); } if (details.containsKey("gpg_key_id")) { ucc.setGpgKeyId(details.get("gpg_key_id")); } if (details.containsKey("gpg_key_fp")) { ucc.setGpgKeyFp(details.get("gpg_key_fp")); } ucc.update(channelId.longValue()); return 1; } /** * Creates a software channel, parent_channel_label can be empty string * @param loggedInUser The current user * @param label Channel label to be created * @param name Name of Channel * @param summary Channel Summary * @param archLabel Architecture label * @param parentLabel Parent Channel label (may be null) * @param checksumType checksum type for this channel * @param gpgKey a map consisting of * <li>string url</li> * <li>string id</li> * <li>string fingerprint</li> * @return 1 if creation of channel succeeds. * @since 10.9 * @throws PermissionCheckFailureException thrown if user does not have * permission to create the channel. * @throws InvalidChannelNameException thrown if given name is in use or * otherwise, invalid. * @throws InvalidChannelLabelException throw if given label is in use or * otherwise, invalid. * @throws InvalidParentChannelException thrown if parent label is for a * channel that is not a base channel. * * @xmlrpc.doc Creates a software channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "label of the new channel") * @xmlrpc.param #param_desc("string", "name", "name of the new channel") * @xmlrpc.param #param_desc("string", "summary" "summary of the channel") * @xmlrpc.param #param_desc("string", "archLabel", * "the label of the architecture the channel corresponds to, * see channel.software.listArches API for complete listing") * @xmlrpc.param #param_desc("string", "parentLabel", "label of the parent of this * channel, an empty string if it does not have one") * @xmlrpc.param #param_desc("string", "checksumType", "checksum type for this channel, * used for yum repository metadata generation") * #options() * #item_desc ("sha1", "Offers widest compatibility with clients") * #item_desc ("sha256", "Offers highest security, but is compatible * only with newer clients: Fedora 11 and newer, * or Enterprise Linux 6 and newer.") * #options_end() * @xmlrpc.param * #struct("gpgKey") * #prop_desc("string", "url", "GPG key URL") * #prop_desc("string", "id", "GPG key ID") * #prop_desc("string", "fingerprint", "GPG key Fingerprint") * #struct_end() * @xmlrpc.returntype int - 1 if the creation operation succeeded, 0 otherwise */ public int create(User loggedInUser, String label, String name, String summary, String archLabel, String parentLabel, String checksumType, Map<String, String> gpgKey) throws PermissionCheckFailureException, InvalidChannelLabelException, InvalidChannelNameException, InvalidParentChannelException { if (!loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN)) { throw new PermissionCheckFailureException(); } CreateChannelCommand ccc = new CreateChannelCommand(); ccc.setArchLabel(archLabel); ccc.setLabel(label); ccc.setName(name); ccc.setSummary(summary); ccc.setParentLabel(parentLabel); ccc.setUser(loggedInUser); ccc.setChecksumLabel(checksumType); ccc.setGpgKeyUrl(gpgKey.get("url")); ccc.setGpgKeyId(gpgKey.get("id")); ccc.setGpgKeyFp(gpgKey.get("fingerprint")); return (ccc.create() != null) ? 1 : 0; } /** * Creates a software channel, parent_channel_label can be empty string * @param loggedInUser The current user * @param label Channel label to be created * @param name Name of Channel * @param summary Channel Summary * @param archLabel Architecture label * @param parentLabel Parent Channel label (may be null) * @param checksumType checksum type for this channel * @return 1 if creation of channel succeeds. * @since 10.9 * @throws PermissionCheckFailureException thrown if user does not have * permission to create the channel. * @throws InvalidChannelNameException thrown if given name is in use or * otherwise, invalid. * @throws InvalidChannelLabelException throw if given label is in use or * otherwise, invalid. * @throws InvalidParentChannelException thrown if parent label is for a * channel that is not a base channel. * * @xmlrpc.doc Creates a software channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "label of the new channel") * @xmlrpc.param #param_desc("string", "name", "name of the new channel") * @xmlrpc.param #param_desc("string", "summary" "summary of the channel") * @xmlrpc.param #param_desc("string", "archLabel", * "the label of the architecture the channel corresponds to, * see channel.software.listArches API for complete listing") * @xmlrpc.param #param_desc("string", "parentLabel", "label of the parent of this * channel, an empty string if it does not have one") * @xmlrpc.param #param_desc("string", "checksumType", "checksum type for this channel, * used for yum repository metadata generation") * #options() * #item_desc ("sha1", "Offers widest compatibility with clients") * #item_desc ("sha256", "Offers highest security, but is compatible * only with newer clients: Fedora 11 and newer, * or Enterprise Linux 6 and newer.") * #options_end() * @xmlrpc.returntype int - 1 if the creation operation succeeded, 0 otherwise */ public int create(User loggedInUser, String label, String name, String summary, String archLabel, String parentLabel, String checksumType) throws PermissionCheckFailureException, InvalidChannelLabelException, InvalidChannelNameException, InvalidParentChannelException { return create(loggedInUser, label, name, summary, archLabel, parentLabel, checksumType, new HashMap<String, String>()); } /** * Creates a software channel, parent_channel_label can be empty string * @param loggedInUser The current user * @param label Channel label to be created * @param name Name of Channel * @param summary Channel Summary * @param archLabel Architecture label * @param parentLabel Parent Channel label (may be null) * @return 1 if creation of channel succeeds. * @throws PermissionCheckFailureException thrown if user does not have * permission to create the channel. * @throws InvalidChannelNameException thrown if given name is in use or * otherwise, invalid. * @throws InvalidChannelLabelException throw if given label is in use or * otherwise, invalid. * @throws InvalidParentChannelException thrown if parent label is for a * channel that is not a base channel. * * @xmlrpc.doc Creates a software channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "label of the new channel") * @xmlrpc.param #param_desc("string", "name", "name of the new channel") * @xmlrpc.param #param_desc("string", "summary" "summary of the channel") * @xmlrpc.param #param_desc("string", "archLabel", * "the label of the architecture the channel corresponds to, * see channel.software.listArches API for complete listing") * @xmlrpc.param #param_desc("string", "parentLabel", "label of the parent of this * channel, an empty string if it does not have one") * @xmlrpc.returntype int - 1 if the creation operation succeeded, 0 otherwise */ public int create(User loggedInUser, String label, String name, String summary, String archLabel, String parentLabel) throws PermissionCheckFailureException, InvalidChannelLabelException, InvalidChannelNameException, InvalidParentChannelException { return create(loggedInUser, label, name, summary, archLabel, parentLabel, "sha1"); } /** * Set the contact/support information for given channel. * @param loggedInUser The current user * @param channelLabel The label for the channel to change * @param maintainerName The name of the channel maintainer * @param maintainerEmail The email address of the channel maintainer * @param maintainerPhone The phone number of the channel maintainer * @param supportPolicy The channel support polity * @return Returns 1 if successful, exception otherwise * @throws FaultException A FaultException is thrown if: * - The sessionKey is invalid * - The channelLabel is invalid * - The user doesn't have channel admin permissions * * @xmlrpc.doc Set contact/support information for given channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("string", "maintainerName", "name of the channel * maintainer") * @xmlrpc.param #param_desc("string", "maintainerEmail", "email of the channel * maintainer") * @xmlrpc.param #param_desc("string", "maintainerPhone", "phone number of the channel * maintainer") * @xmlrpc.param #param_desc("string", "supportPolicy", "channel support policy") * @xmlrpc.returntype #return_int_success() */ public int setContactDetails(User loggedInUser, String channelLabel, String maintainerName, String maintainerEmail, String maintainerPhone, String supportPolicy) throws FaultException { if (!loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN)) { throw new PermissionCheckFailureException(); } Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); channel.setMaintainerName(maintainerName); channel.setMaintainerEmail(maintainerEmail); channel.setMaintainerPhone(maintainerPhone); channel.setSupportPolicy(supportPolicy); ChannelFactory.save(channel); return 1; } /** * Returns list of subscribed systems for the given channel label. * @param loggedInUser The current user * @param label Label of the channel in question. * @return Returns an array of maps representing a system. Contains system id and * system name for each system subscribed to this channel. * @throws FaultException A FaultException is thrown if: * - Logged in user is not a channel admin. * - Channel does not exist. * * @xmlrpc.doc Returns list of subscribed systems for the given channel label * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * #array() * #struct("system") * #prop("int", "id") * #prop("string", "name") * #struct_end() * #array_end() */ public Object[] listSubscribedSystems(User loggedInUser, String label) throws FaultException { // Make sure user has access to the orgs channels if (!loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN)) { throw new PermissionCheckFailureException(); } // Get the channel. Channel channel = lookupChannelByLabel(loggedInUser, label); DataResult<Map<String, Object>> dr = SystemManager.systemsSubscribedToChannel(channel, loggedInUser); for (Map<String, Object> sys : dr) { sys.remove("selectable"); } return dr.toArray(); } /** * Retrieve the channels for a given system id. * @param loggedInUser The current user * @param sid The id of the system in question. * @return Returns an array of maps representing the channels this system is * subscribed to. * @throws FaultException A FaultException is thrown if: * - sessionKey is invalid * - Server does not exist * - User does not have access to system * * @xmlrpc.doc Returns a list of channels that a system is subscribed to for the * given system id * @xmlrpc.param #session_key() * @xmlrpc.param #param("int", "serverId") * @xmlrpc.returntype * #array() * #struct("channel") * #prop("string", "id") * #prop("string", "label") * #prop("string", "name") * #struct_end() * #array_end() */ public Object[] listSystemChannels(User loggedInUser, Integer sid) throws FaultException { Server server = XmlRpcSystemHelper.getInstance().lookupServer(loggedInUser, sid); DataResult<Map<String, Object>> dr = SystemManager.channelsForServer(server); return dr.toArray(); } /** * Change a systems subscribed channels to the list of channels passed in. * @param loggedInUser The current user * @param sid The id for the system in question * @param channelLabels The list of labels to subscribe the system to * @return Returns 1 on success, Exception otherwise. * @throws FaultException A FaultException is thrown if: * - sessionKey is invalid * - server doesn't exist * - channel doesn't exist * - user can't subscribe server to channel * - a base channel is not specified * - multiple base channels are specified * @deprecated being replaced by system.setBaseChannel(string sessionKey, * int serverId, string channelLabel) and system.setChildChannels(string sessionKey, * int serverId, array[string channelLabel]) * * @xmlrpc.doc Change a systems subscribed channels to the list of channels passed in. * @xmlrpc.param #session_key() * @xmlrpc.param #param("int", "serverId") * @xmlrpc.param #array_single("string", "channelLabel - labels of the channels to * subscribe the system to.") * @xmlrpc.returntype #return_int_success() */ @Deprecated public int setSystemChannels(User loggedInUser, Integer sid, List<String> channelLabels) throws FaultException { Server server = XmlRpcSystemHelper.getInstance().lookupServer(loggedInUser, sid); List<Channel> channels = new ArrayList<Channel>(); log.debug("setSystemChannels()"); // Verify that each channel label we were passed corresponds to a valid channel // and store in a list. Channel baseChannel = null; log.debug("Incoming channels:"); for (String label : channelLabels) { Channel channel = lookupChannelByLabel(loggedInUser, label); log.debug(" " + channel.getLabel()); if (!ChannelManager.verifyChannelSubscribe(loggedInUser, channel.getId())) { throw new PermissionCheckFailureException(); } // let's save ourselves some time and check the arches here if (!channel.getChannelArch().isCompatible(server.getServerArch())) { throw new InvalidChannelException(); } if (baseChannel == null && channel.isBaseChannel()) { baseChannel = channel; // need to make sure the base channel is the first // item in the list because subscribeToServer can't subscribe // to a child channel unless the server is subscribed to a base // channel. channels.add(0, channel); } else if (baseChannel != null && channel.isBaseChannel()) { throw new MultipleBaseChannelException(baseChannel.getLabel(), label); } else { channels.add(channel); } } // if we can't find a base channel in the list, we need to leave // the system alone and punt. if (baseChannel == null) { throw new InvalidChannelException("No base channel specified"); } // Unsubscribe the server from it's current channels (if any) Set<Channel> currentlySubscribed = server.getChannels(); Channel oldBase = server.getBaseChannel(); log.debug("Unsubscribing from:"); for (Channel channel : currentlySubscribed) { if (channel.isBaseChannel()) { continue; // must leave base for now } server = SystemManager.unsubscribeServerFromChannel(server, channel); log.debug(" " + channel.getLabel()); } // We must unsubscribe from the old Base channel last, so no child channels // are still subscribed if (!channels.contains(oldBase)) { server = SystemManager.unsubscribeServerFromChannel(server, oldBase); } else { // Base is the same, no need to resubscribe: channels.remove(oldBase); } // Subscribe the server to channels in channels list log.debug("Subscribing to:"); for (Channel channel : channels) { server = SystemManager.subscribeServerToChannel(loggedInUser, server, channel, true); log.debug(" " + channel.getName()); } //Update errata cache publishUpdateErrataCacheEvent(loggedInUser.getOrg()); return 1; } /** * Set the subscribable flag for a given channel and user. If value is set to 'true', * this method will give the user subscribe permissions to the channel. Otherwise, this * method revokes that privilege. * @param loggedInUser The current user * @param channelLabel The label for the channel in question * @param login The login for the user in question * @param value The boolean value telling us whether to grant subscribe permission or * revoke it. * @return Returns 1 on success, FaultException otherwise * @throws FaultException A FaultException is thrown if: * - The loggedInUser doesn't have permission to perform this action * - The login, sessionKey, or channelLabel is invalid * * @xmlrpc.doc Set the subscribable flag for a given channel and user. * If value is set to 'true', this method will give the user * subscribe permissions to the channel. Otherwise, that privilege is revoked. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("string", "login", "login of the target user") * @xmlrpc.param #param_desc("boolean", "value", "value of the flag to set") * @xmlrpc.returntype #return_int_success() */ public int setUserSubscribable(User loggedInUser, String channelLabel, String login, Boolean value) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); //Verify permissions if (!(UserManager.verifyChannelAdmin(loggedInUser, channel) || loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN))) { throw new PermissionCheckFailureException(); } if (value) { // Add the 'subscribe' role for the target user to the channel ChannelManager.addSubscribeRole(target, channel); } else { // Remove the 'subscribe' role for the target user to the channel ChannelManager.removeSubscribeRole(target, channel); } return 1; } /** * Set the manageable flag for a given channel and user. If value is set to 'true', * this method will give the user manage permissions to the channel. Otherwise, this * method revokes that privilege. * @param loggedInUser The current user * @param channelLabel The label for the channel in question * @param login The login for the user in question * @param value The boolean value telling us whether to grant manage permission or * revoke it. * @return Returns 1 on success, FaultException otherwise * @throws FaultException A FaultException is thrown if: * - The loggedInUser doesn't have permission to perform this action * - The login, sessionKey, or channelLabel is invalid * * @xmlrpc.doc Set the manageable flag for a given channel and user. * If value is set to 'true', this method will give the user * manage permissions to the channel. Otherwise, that privilege is revoked. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("string", "login", "login of the target user") * @xmlrpc.param #param_desc("boolean", "value", "value of the flag to set") * @xmlrpc.returntype #return_int_success() */ public int setUserManageable(User loggedInUser, String channelLabel, String login, Boolean value) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser(loggedInUser, login); Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); if (!channel.isCustom()) { throw new InvalidChannelException( "Manageable flag is relevant for custom channels only."); } //Verify permissions if (!(UserManager.verifyChannelAdmin(loggedInUser, channel) || loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN))) { throw new PermissionCheckFailureException(); } if (value) { // Add the 'manage' role for the target user to the channel ChannelManager.addManageRole(target, channel); } else { // Remove the 'manage' role for the target user to the channel ChannelManager.removeManageRole(target, channel); } return 1; } /** * Returns whether the channel may be subscribed to by the given user. * @param loggedInUser The current user * @param channelLabel The label for the channel in question * @param login The login for the user in question * @return whether the channel may be subscribed to by the given user. * @throws FaultException thrown if * - The loggedInUser doesn't have permission to perform this action * - The login, sessionKey, or channelLabel is invalid * * @xmlrpc.doc Returns whether the channel may be subscribed to by the given user. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("string", "login", "login of the target user") * @xmlrpc.returntype int - 1 if subscribable, 0 if not */ public int isUserSubscribable(User loggedInUser, String channelLabel, String login) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), channelLabel); //Verify permissions if (!(UserManager.verifyChannelAdmin(loggedInUser, channel) || loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN))) { throw new PermissionCheckFailureException(); } boolean flag = ChannelManager.verifyChannelSubscribe(target, channel.getId()); return BooleanUtils.toInteger(flag); } /** * Returns whether the channel may be managed by the given user. * @param loggedInUser The current user * @param channelLabel The label for the channel in question * @param login The login for the user in question * @return whether the channel may be managed by the given user. * @throws FaultException thrown if * - The loggedInUser doesn't have permission to perform this action * - The login, sessionKey, or channelLabel is invalid * * @xmlrpc.doc Returns whether the channel may be managed by the given user. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("string", "login", "login of the target user") * @xmlrpc.returntype int - 1 if manageable, 0 if not */ public int isUserManageable(User loggedInUser, String channelLabel, String login) throws FaultException { User target = XmlRpcUserHelper.getInstance().lookupTargetUser( loggedInUser, login); Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), channelLabel); if (!channel.isCustom()) { throw new InvalidChannelException( "Manageable flag is relevant for custom channels only."); } //Verify permissions if (!(UserManager.verifyChannelAdmin(loggedInUser, channel) || loggedInUser.hasRole(RoleFactory.CHANNEL_ADMIN))) { throw new PermissionCheckFailureException(); } boolean flag = ChannelManager.verifyChannelManage(target, channel.getId()); return BooleanUtils.toInteger(flag); } /** * Set globally subscribable attribute for given channel. * @param loggedInUser The current user * @param channelLabel The label for the channel to change * @param value The boolean value to set globally subscribable to. * @return Returns 1 if successful, exception otherwise * @throws FaultException A FaultException is thrown if: * - The sessionkey is invalid * - The channel is invalid * - The logged in user isn't a channel admin * * @xmlrpc.doc Set globally subscribable attribute for given channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "label of the channel") * @xmlrpc.param #param_desc("boolean", "subscribable", "true if the channel is to be * globally subscribable. False otherwise.") * @xmlrpc.returntype #return_int_success() */ public int setGloballySubscribable(User loggedInUser, String channelLabel, boolean value) throws FaultException { Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), channelLabel); try { if (!ChannelManager.verifyChannelAdmin(loggedInUser, channel.getId())) { throw new PermissionCheckFailureException(); } } catch (InvalidChannelRoleException e) { throw new PermissionCheckFailureException(); } if (value) { channel.setGloballySubscribable(true, loggedInUser.getOrg()); } else { channel.setGloballySubscribable(false, loggedInUser.getOrg()); } return 1; } /** * Adds a given list of packages to the given channel. * @param loggedInUser The current user * @param channelLabel The label for the channel * @param packageIds A list containing the ids of the packages to be added * @return Returns 1 if successfull, FaultException otherwise * @throws FaultException A FaultException is thrown if: * - The user is not a channel admin for the channel * - The channel is invalid * - A package id is invalid * - The user doesn't have access to one of the channels in the list * * @xmlrpc.doc Adds a given list of packages to the given channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "target channel.") * @xmlrpc.param #array_single("int", "packageId - id of a package to * add to the channel.") * @xmlrpc.returntype #return_int_success() */ public int addPackages(User loggedInUser, String channelLabel, List<Long> packageIds) throws FaultException { Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), channelLabel); // Try to add the list of packages to the channel. Catch any exceptions and // convert to FaultExceptions try { ChannelEditor.getInstance().addPackages(loggedInUser, channel, packageIds); } catch (PermissionException e) { throw new PermissionCheckFailureException(e.getMessage()); } catch (LookupException le) { //This shouldn't happen, but if it does, it is because one of the packages //doesn't exist. throw new NoSuchPackageException(le); } //refresh channel with newest packages ChannelManager.refreshWithNewestPackages(channel, "api"); /* Bugzilla # 177673 */ scheduleErrataCacheUpdate(loggedInUser.getOrg(), channel, 3600000); //if we made it this far, the operation was a success! return 1; } /** * Removes a given list of errata from the given channel. * @param loggedInUser The current user * @param channelLabel The label for the channel * @param errataNames A list containing the advisory names of errata to remove * @param removePackages Boolean to remove packages from the channel also * @return Returns 1 if successfull, Exception otherwise * - The user is not a channel admin for the channel * - The channel is invalid * - The user doesn't have access to one of the channels in the list * * @xmlrpc.doc Removes a given list of errata from the given channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "target channel.") * @xmlrpc.param #array_single("string", "advisoryName - name of an erratum to remove") * @xmlrpc.param #param_desc("boolean", "removePackages", * "True to remove packages from the channel") * @xmlrpc.returntype #return_int_success() */ public int removeErrata(User loggedInUser, String channelLabel, List<String> errataNames, boolean removePackages) { channelAdminPermCheck(loggedInUser); Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); if (!UserManager.verifyChannelAdmin(loggedInUser, channel)) { throw new PermissionCheckFailureException(); } HashSet<Errata> errataToRemove = new HashSet<Errata>(); for (String erratumName : errataNames) { Errata erratum = ErrataManager.lookupByAdvisory(erratumName); if (erratum != null) { errataToRemove.add(erratum); ErrataManager.removeErratumFromChannel(erratum, channel, loggedInUser); } } // remove packages from the channel if requested if (removePackages) { List<Long> packagesToRemove = new ArrayList<Long>(); List<Long> channelPkgs = ChannelFactory.getPackageIds(channel.getId()); for (Errata erratum : errataToRemove) { Set<Package> erratumPackageList = erratum.getPackages(); for (Package pkg : erratumPackageList) { // if the package is in the channel, remove it if (channelPkgs.contains(pkg.getId())) { packagesToRemove.add(pkg.getId()); } } } // remove the packages from the channel ChannelManager.removePackages(channel, packagesToRemove, loggedInUser); // refresh the channel ChannelManager.refreshWithNewestPackages(channel, "java::removeErrata"); List<Long> cids = new ArrayList<Long>(); cids.add(channel.getId()); ErrataCacheManager.insertCacheForChannelPackagesAsync(cids, packagesToRemove); } return 1; } /** * Removes a given list of packages from the given channel. * @param loggedInUser The current user * @param channelLabel The label for the channel * @param packageIds A list containing the ids of the packages to be removed * @return Returns 1 if successfull, FaultException otherwise * @throws FaultException A FaultException is thrown if: * - The user is not a channel admin for the channel * - The channel is invalid * - A package id is invalid * - The user doesn't have access to one of the channels in the list * * @xmlrpc.doc Removes a given list of packages from the given channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "target channel.") * @xmlrpc.param #array_single("int", "packageId - id of a package to * remove from the channel.") * @xmlrpc.returntype #return_int_success() */ public int removePackages(User loggedInUser, String channelLabel, List<Long> packageIds) throws FaultException { Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), channelLabel); //Make sure the user is a channel admin for the given channel. if (!UserManager.verifyChannelAdmin(loggedInUser, channel)) { throw new PermissionCheckFailureException(); } // Try to remove the list of packages from the channel. Catch any exceptions and // convert to FaultExceptions try { ChannelEditor.getInstance().removePackages(loggedInUser, channel, packageIds); } catch (PermissionException e) { throw new PermissionCheckFailureException(); } catch (LookupException le) { //This shouldn't happen, but if it does, it is because one of the packages //doesn't exist. throw new NoSuchPackageException(le); } //refresh channel with newest packages ChannelManager.refreshWithNewestPackages(channel, "api"); /* Bugzilla # 177673 */ scheduleErrataCacheUpdate(loggedInUser.getOrg(), channel, 3600000); //if we made it this far, the operation was a success! return 1; } /** * Private helper method to create a new UpdateErrataCacheEvent and publish it to the * MessageQueue. * @param orgIn The org we're updating. */ private void publishUpdateErrataCacheEvent(Org orgIn) { StopWatch sw = new StopWatch(); if (log.isDebugEnabled()) { log.debug("Updating errata cache"); sw.start(); } UpdateErrataCacheEvent uece = new UpdateErrataCacheEvent(UpdateErrataCacheEvent.TYPE_ORG); uece.setOrgId(orgIn.getId()); MessageQueue.publish(uece); if (log.isDebugEnabled()) { sw.stop(); log.debug("Finished Updating errata cache. Took [" + sw.getTime() + "]"); } } /** * List the errata applicable to a channel after given startDate * @param loggedInUser The current user * @param channelLabel The label for the channel * @param startDate begin date * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * * @xmlrpc.doc List the errata applicable to a channel after given startDate * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param($date, "startDate") * @xmlrpc.returntype * #array() * $ErrataOverviewSerializer * #array_end() */ public List<ErrataOverview> listErrata(User loggedInUser, String channelLabel, Date startDate) throws NoSuchChannelException { return listErrata(loggedInUser, channelLabel, startDate, null); } /** * List the errata applicable to a channel between startDate and endDate. * @param loggedInUser The current user * @param channelLabel The label for the channel * @param startDate begin date * @param endDate end date * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * * @xmlrpc.doc List the errata applicable to a channel between startDate and endDate. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param($date, "startDate") * @xmlrpc.param #param($date, "endDate") * @xmlrpc.returntype * #array() * $ErrataOverviewSerializer * #array_end() */ public List<ErrataOverview> listErrata(User loggedInUser, String channelLabel, Date startDate, Date endDate) throws NoSuchChannelException { return listErrata(loggedInUser, channelLabel, startDate, endDate, false); } /** * List the errata applicable to a channel between startDate and endDate. * Allow to select errata by last modified date. * Support behaviour available in old versions. (needed for Dumper) * @param loggedInUser The current user * @param channelLabel The label for the channel * @param startDate begin date * @param endDate end date * @param lastModified select by last modified timestamp or not * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * * @xmlrpc.doc List the errata applicable to a channel between startDate and endDate. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param($date, "startDate") * @xmlrpc.param #param($date, "endDate") * @xmlrpc.param #param_desc("boolean", "lastModified", * "select by last modified or not") * @xmlrpc.returntype * #array() * $ErrataOverviewSerializer * #array_end() */ public List<ErrataOverview> listErrata(User loggedInUser, String channelLabel, Date startDate, Date endDate, boolean lastModified) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); DataResult<ErrataOverview> errata = ChannelManager.listErrata(channel, startDate, endDate, lastModified, loggedInUser); errata.elaborate(); return errata; } /** * List the errata applicable to a channel * @param loggedInUser The current user * @param channelLabel The label for the channel * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * * When removing deprecation, swtich this method over to using * listErrata(sessionKey, null, null) after deleting * listErrata(String, String, String, String), then update docs * to use $ErrataOverviewSerializer * * * @xmlrpc.doc List the errata applicable to a channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.returntype * #array() * #struct("errata") * #prop_desc("int", "id", "Errata Id") * #prop_desc("string", "advisory_synopsis", "Summary of the erratum.") * #prop_desc("string", "advisory_type", "Type label such as Security, Bug Fix") * #prop_desc("string", "advisory_name", "Name such as RHSA, etc") * #prop_desc("string","advisory", "name of the advisory (Deprecated)") * #prop_desc("string","issue_date", * "date format follows YYYY-MM-DD HH24:MI:SS (Deprecated)") * #prop_desc("string","update_date", * "date format follows YYYY-MM-DD HH24:MI:SS (Deprecated)") * #prop("string","synopsis (Deprecated)") * #prop_desc("string","last_modified_date", * "date format follows YYYY-MM-DD HH24:MI:SS (Deprecated)") * #struct_end() * #array_end() */ public List<Map<String, Object>> listErrata(User loggedInUser, String channelLabel) throws NoSuchChannelException { List<Map<String, Object>> list = listErrata(loggedInUser, channelLabel, "", ""); return list; } /** * List the errata applicable to a channel after given startDate * @param loggedInUser The current user * @param channelLabel The label for the channel * @param startDate begin date * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * @deprecated being replaced by listErrata(string sessionKey, * string channelLabel, dateTime.iso8601 startDate) * * @xmlrpc.doc List the errata applicable to a channel after given startDate * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.returntype * #array() * #struct("errata") * #prop_desc("string","advisory", "name of the advisory") * #prop_desc("string","issue_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop_desc("string","update_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop("string","synopsis") * #prop("string","advisory_type") * #prop_desc("string","last_modified_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #struct_end() * #array_end() */ @Deprecated public List<Map<String, Object>> listErrata(User loggedInUser, String channelLabel, String startDate) throws NoSuchChannelException { return listErrata(loggedInUser, channelLabel, startDate, null); } /** * List the errata applicable to a channel between startDate and endDate. * @param loggedInUser The current user * @param channelLabel The label for the channel * @param startDate begin date * @param endDate end date * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * @deprecated being replaced by listErrata(string sessionKey, * string channelLabel, dateTime.iso8601 startDate, dateTime.iso8601) * * @xmlrpc.doc List the errata applicable to a channel between startDate and endDate. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.param #param("string", "endDate") * @xmlrpc.returntype * #array() * #struct("errata") * #prop_desc("string","advisory", "name of the advisory") * #prop_desc("string","issue_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop_desc("string","update_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop("string","synopsis") * #prop("string","advisory_type") * #prop_desc("string","last_modified_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #struct_end() * #array_end() */ @Deprecated public List<Map<String, Object>> listErrata(User loggedInUser, String channelLabel, String startDate, String endDate) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); List<Map<String, Object>> errata = ChannelManager.listErrataForDates(channel, startDate, endDate); return errata; } /** * List the errata of a specific type that are applicable to a channel * @param loggedInUser The current user * @param channelLabel The label for the channel * @param advisoryType The type of advisory (one of the following: * "Security Advisory", "Product Enhancement Advisory", * "Bug Fix Advisory") * @return the errata applicable to a channel * @throws NoSuchChannelException thrown if there is no channel matching * channelLabel. * * @xmlrpc.doc List the errata of a specific type that are applicable to a channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel to query") * @xmlrpc.param #param_desc("string", "advisoryType", "type of advisory (one of * of the following: 'Security Advisory', 'Product Enhancement Advisory', * 'Bug Fix Advisory'") * @xmlrpc.returntype * #array() * #struct("errata") * #prop_desc("string","advisory", "name of the advisory") * #prop_desc("string","issue_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop_desc("string","update_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #prop("string","synopsis") * #prop("string","advisory_type") * #prop_desc("string","last_modified_date", * "date format follows YYYY-MM-DD HH24:MI:SS") * #struct_end() * #array_end() */ public Object[] listErrataByType(User loggedInUser, String channelLabel, String advisoryType) throws NoSuchChannelException { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); List<Map<String, Object>> errata = ChannelManager.listErrataByType(channel, advisoryType); return errata.toArray(); } private void scheduleErrataCacheUpdate(Org org, Channel channel, long delay) { SelectMode m = ModeFactory.getMode(TaskConstants.MODE_NAME, "find_channel_in_task_queue"); Map<String, Object> inParams = new HashMap<String, Object>(); inParams.put("cid", channel.getId()); DataResult dr = m.execute(inParams); delay /= (24 * 60 * 60); if (dr.isEmpty()) { WriteMode w = ModeFactory.getWriteMode(TaskConstants.MODE_NAME, "insert_into_task_queue"); inParams = new HashMap<String, Object>(); inParams.put("org_id", org.getId()); inParams.put("task_name", ErrataCacheWorker.BY_CHANNEL); inParams.put("task_data", channel.getId()); inParams.put("earliest", new Timestamp(System.currentTimeMillis() + delay)); w.executeUpdate(inParams); } else { WriteMode w = ModeFactory.getWriteMode(TaskConstants.MODE_NAME, "update_task_queue"); inParams = new HashMap<String, Object>(); inParams.put("earliest", new Timestamp(System.currentTimeMillis() + delay)); inParams.put("cid", channel.getId()); w.executeUpdate(inParams); } } private Channel lookupChannelByLabel(User user, String label) throws NoSuchChannelException { Channel channel = ChannelFactory.lookupByLabelAndUser(label, user); if (channel == null) { throw new NoSuchChannelException(label); } return channel; } private Channel lookupChannelByLabel(Org org, String label) throws NoSuchChannelException { Channel channel = ChannelManager.lookupByLabel( org, label); if (channel == null) { throw new NoSuchChannelException(label); } return channel; } private Channel lookupChannelById(User user, Long id) throws NoSuchChannelException { Channel channel = ChannelManager.lookupByIdAndUser(new Long(id), user); if (channel == null) { throw new NoSuchChannelException(id); } return channel; } /** * Lists all packages for an Org that are not contained within any channel * @param loggedInUser The current user * @return list of Package objects not associated with a channel * @throws NoSuchChannelException thrown if no channel is found. * * @xmlrpc.doc Lists all packages that are not associated with a channel. Typically * these are custom packages. * @xmlrpc.param #session_key() * @xmlrpc.returntype * #array() * $PackageSerializer * #array_end() */ public Object[] listPackagesWithoutChannel(User loggedInUser) { ensureUserRole(loggedInUser, RoleFactory.CHANNEL_ADMIN); return PackageFactory.lookupOrphanPackages(loggedInUser.getOrg()).toArray(); } /** * Subscribe a system to a list of channels * @param loggedInUser The current user * @param labels a list of channel labels to subscribe the system to * @param sid the serverId of the system in question * @return 1 for success * @deprecated being replaced by system.setBaseChannel(string sessionKey, * int serverId, string channelLabel) and system.setChildChannels(string sessionKey, * int serverId, array[string channelLabel]) * * @xmlrpc.doc Subscribes a system to a list of channels. If a base channel is * included, that is set before setting child channels. When setting child * channels the current child channel subscriptions are cleared. To fully * unsubscribe the system from all channels, simply provide an empty list of * channel labels. * @xmlrpc.param #session_key() * @xmlrpc.param #param("int", "serverId") * @xmlrpc.param #array_single("string", "label - channel label to subscribe * the system to.") * @xmlrpc.returntype #return_int_success() */ @Deprecated public int subscribeSystem(User loggedInUser, Integer sid, List<String> labels) { Server server = SystemManager.lookupByIdAndUser(new Long(sid.longValue()), loggedInUser); if (labels.size() == 0) { ServerFactory.unsubscribeFromAllChannels(loggedInUser, server); return 1; } Channel base = null; List<Integer> childChannelIds = new ArrayList<Integer>(); for (String label : labels) { Channel channel = lookupChannelByLabel(loggedInUser.getOrg(), label); if (base == null && channel.isBaseChannel()) { base = channel; } else if (base != null && channel.isBaseChannel()) { throw new MultipleBaseChannelException(base.getLabel(), label); } else { childChannelIds.add(new Integer(channel.getId().intValue())); } } SystemHandler sysHandler = new SystemHandler(); if (base != null) { sysHandler.setBaseChannel(loggedInUser, sid, new Integer(base.getId().intValue())); } sysHandler.setChildChannels(loggedInUser, sid, childChannelIds); return 1; } /** * Clone a channel * @param loggedInUser The current user * @param originalLabel the label of the channel to clone * @param channelDetails a map consisting of * string name * string label * string summary * string parent_label (optional) * string arch_label (optional) * string gpg_key_url (optional), gpg_url left for historical reasons * string gpg_key_id (optional), gpg_id left for historical reasons * string gpg_key_fp (optional), gpg_fingerprint left for historical reasons * string description (optional) * @param originalState if true, only the original packages of the channel to clone * will be cloned. Any updates will not be. * @return int id of clone channel * * @xmlrpc.doc Clone a channel. If arch_label is omitted, the arch label of the * original channel will be used. If parent_label is omitted, the clone will be * a base channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param("string", "original_label") * @xmlrpc.param * #struct("channel details") * #prop("string", "name") * #prop("string", "label") * #prop("string", "summary") * #prop_desc("string", "parent_label", "(optional)") * #prop_desc("string", "arch_label", "(optional)") * #prop_desc("string", "gpg_key_url", "(optional), * gpg_url might be used as well") * #prop_desc("string", "gpg_key_id", "(optional), * gpg_id might be used as well") * #prop_desc("string", "gpg_key_fp", "(optional), * gpg_fingerprint might be used as well") * #prop_desc("string", "description", "(optional)") * #prop_desc("string", "checksum", "either sha1 or sha256") * #struct_end() * @xmlrpc.param #param("boolean", "original_state") * @xmlrpc.returntype int the cloned channel ID */ public int clone(User loggedInUser, String originalLabel, Map<String, String> channelDetails, Boolean originalState) { // confirm that the user only provided valid keys in the map Set<String> validKeys = new HashSet<String>(); validKeys.add("name"); validKeys.add("label"); validKeys.add("summary"); validKeys.add("parent_label"); validKeys.add("arch_label"); validKeys.add("gpg_url"); // deprecated, left for compatibility reasons validKeys.add("gpg_id"); // deprecated, left for compatibility reasons validKeys.add("gpg_fingerprint"); // deprecated, left for compatibility reasons validKeys.add("gpg_key_url"); validKeys.add("gpg_key_id"); validKeys.add("gpg_key_fp"); validKeys.add("description"); validKeys.add("checksum"); validateMap(validKeys, channelDetails); channelAdminPermCheck(loggedInUser); String name = channelDetails.get("name"); String label = channelDetails.get("label"); String parentLabel = channelDetails.get("parent_label"); String archLabel = channelDetails.get("arch_label"); String summary = channelDetails.get("summary"); String description = channelDetails.get("description"); String checksum = channelDetails.get("checksum"); if (ChannelFactory.lookupByLabel(loggedInUser.getOrg(), label) != null) { throw new DuplicateChannelLabelException(label); } Channel originalChan = lookupChannelByLabel(loggedInUser.getOrg(), originalLabel); ChannelArch arch = null; if (archLabel != null && archLabel.length() > 0) { arch = ChannelFactory.lookupArchByName(archLabel); if (arch == null) { throw new InvalidChannelArchException(archLabel); } } else { arch = originalChan.getChannelArch(); } if (checksum == null) { checksum = originalChan.getChecksumTypeLabel(); } String gpgUrl, gpgId, gpgFingerprint; if (channelDetails.containsKey("gpg_key_url") || channelDetails.containsKey("gpg_url") || channelDetails.containsKey("gpg_key_id") || channelDetails.containsKey("gpg_id") || channelDetails.containsKey("gpg_key_fp") || channelDetails.containsKey("gpg_fingerprint")) { // if one of the GPG information was set, use it if (channelDetails.get("gpg_key_url") == null) { gpgUrl = channelDetails.get("gpg_url"); } else { gpgUrl = channelDetails.get("gpg_key_url"); } if (channelDetails.get("gpg_key_id") == null) { gpgId = channelDetails.get("gpg_id"); } else { gpgId = channelDetails.get("gpg_key_id"); } if (channelDetails.get("gpg_key_fp") == null) { gpgFingerprint = channelDetails.get("gpg_fingerprint"); } else { gpgFingerprint = channelDetails.get("gpg_key_fp"); } } else { // copy GPG info from the original channel gpgUrl = originalChan.getGPGKeyUrl(); gpgId = originalChan.getGPGKeyId(); gpgFingerprint = originalChan.getGPGKeyFp(); } CloneChannelCommand helper = new CloneChannelCommand(originalState.booleanValue(), originalChan); helper.setName(name); helper.setArchLabel(arch.getLabel()); helper.setDescription(description); helper.setGpgKeyFp(gpgFingerprint); helper.setGpgKeyId(gpgId); helper.setGpgKeyUrl(gpgUrl); helper.setLabel(label); if (parentLabel != null) { helper.setParentLabel(parentLabel); } helper.setUser(loggedInUser); helper.setSummary(summary); helper.setChecksumLabel(checksum); Channel clone = helper.create(); return clone.getId().intValue(); } /** * Checks whether a user is an org admin or channnel admin (and thus can admin * a channel) * @param loggedInUser the user to check */ private void channelAdminPermCheck(User loggedInUser) { Role channelRole = RoleFactory.lookupByLabel("channel_admin"); Role orgAdminRole = RoleFactory.lookupByLabel("org_admin"); if (!loggedInUser.hasRole(channelRole) && !loggedInUser.hasRole(orgAdminRole)) { throw new PermissionException("Only Org Admins and Channel Admins can clone " + "channels."); } } /** * Merge a channel's errata into another channel. * @param loggedInUser The current user * @param mergeFromLabel the label of the channel to pull the errata from * @param mergeToLabel the label of the channel to push errata into * @return A list of errata that were merged. * * @xmlrpc.doc Merges all errata from one channel into another * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "mergeFromLabel", "the label of the * channel to pull errata from") * @xmlrpc.param #param_desc("string", "mergeToLabel", "the label to push the * errata into") * @xmlrpc.returntype * #array() * $ErrataSerializer * #array_end() */ public Object[] mergeErrata(User loggedInUser, String mergeFromLabel, String mergeToLabel) { channelAdminPermCheck(loggedInUser); Channel mergeFrom = lookupChannelByLabel(loggedInUser, mergeFromLabel); Channel mergeTo = lookupChannelByLabel(loggedInUser, mergeToLabel); if (!UserManager.verifyChannelAdmin(loggedInUser, mergeTo)) { throw new PermissionCheckFailureException(); } Set<Errata> mergedErrata = mergeErrataToChannel(loggedInUser, mergeFrom .getErratas(), mergeTo, mergeFrom); return mergedErrata.toArray(); } /** * Merge a channel's errata into another channel based upon a given start/end date. * @param loggedInUser The current user * @param mergeFromLabel the label of the channel to pull the errata from * @param mergeToLabel the label of the channel to push errata into * @param startDate begin date * @param endDate end date * @return A list of errata that were merged. * * @xmlrpc.doc Merges all errata from one channel into another based upon a * given start/end date. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "mergeFromLabel", "the label of the * channel to pull errata from") * @xmlrpc.param #param_desc("string", "mergeToLabel", "the label to push the * errata into") * @xmlrpc.param #param("string", "startDate") * @xmlrpc.param #param("string", "endDate") * @xmlrpc.returntype * #array() * $ErrataSerializer * #array_end() */ public Object[] mergeErrata(User loggedInUser, String mergeFromLabel, String mergeToLabel, String startDate, String endDate) { channelAdminPermCheck(loggedInUser); Channel mergeFrom = lookupChannelByLabel(loggedInUser, mergeFromLabel); Channel mergeTo = lookupChannelByLabel(loggedInUser, mergeToLabel); if (!UserManager.verifyChannelAdmin(loggedInUser, mergeTo)) { throw new PermissionCheckFailureException(); } List<Errata> fromErrata = ErrataFactory.lookupByChannelBetweenDates( loggedInUser.getOrg(), mergeFrom, startDate, endDate); Set<Errata> mergedErrata = mergeErrataToChannel(loggedInUser, new HashSet<Errata>(fromErrata), mergeTo, mergeFrom); return mergedErrata.toArray(); } /** * Merge a list of errata from one channel into another channel * @param loggedInUser The current user * @param mergeFromLabel the label of the channel to pull the errata from * @param mergeToLabel the label of the channel to push errata into * @param errataNames the list of errata to merge * @return A list of errata that were merged. * * @xmlrpc.doc Merges a list of errata from one channel into another * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "mergeFromLabel", "the label of the * channel to pull errata from") * @xmlrpc.param #param_desc("string", "mergeToLabel", "the label to push the * errata into") * @xmlrpc.param * #array_single("string", " advisory - The advisory name of the errata to merge") * @xmlrpc.returntype * #array() * $ErrataSerializer * #array_end() */ public Object[] mergeErrata(User loggedInUser, String mergeFromLabel, String mergeToLabel, List<String> errataNames) { channelAdminPermCheck(loggedInUser); Channel mergeFrom = lookupChannelByLabel(loggedInUser, mergeFromLabel); Channel mergeTo = lookupChannelByLabel(loggedInUser, mergeToLabel); if (!UserManager.verifyChannelAdmin(loggedInUser, mergeTo)) { throw new PermissionCheckFailureException(); } Set<Errata> sourceErrata = mergeFrom.getErratas(); Set<Errata> errataToMerge = new HashSet<Errata>(); // make sure our errata exist in the "from" channel for (String erratumName : errataNames) { Errata toMerge = ErrataManager.lookupByAdvisory(erratumName); for (Errata erratum : sourceErrata) { if (erratum.getAdvisoryName() == toMerge.getAdvisoryName()) { errataToMerge.add(toMerge); break; } } } Set<Errata> mergedErrata = mergeErrataToChannel(loggedInUser, errataToMerge, mergeTo, mergeFrom); return mergedErrata.toArray(); } private Set<Errata> mergeErrataToChannel(User user, Set<Errata> errataToMerge, Channel toChannel, Channel fromChannel) { // find errata that we do not need to merge List<Errata> same = ErrataManager.listSamePublishedInChannels( user, fromChannel, toChannel); List<Errata> brothers = ErrataManager.listPublishedBrothersInChannels( user, fromChannel, toChannel); List<Errata> clones = ErrataManager.listPublishedClonesInChannels( user, fromChannel, toChannel); // and remove them errataToMerge.removeAll(same); errataToMerge.removeAll(brothers); errataToMerge.removeAll(clones); ErrataManager.publishErrataToChannelAsync(toChannel, getErrataIds(errataToMerge), user); // no need to regenerate errata cache, because we didn't touch any packages return errataToMerge; } private Set<Long> getErrataIds(Set<Errata> errata) { Set<Long> ids = new HashSet<Long>(); for (Errata erratum : errata) { ids.add(erratum.getId()); } return ids; } /** * Merge a channel's packages into another channel. * @param loggedInUser The current user * @param mergeFromLabel the label of the channel to pull the packages from * @param mergeToLabel the label of the channel to push packages into * @return A list of packages that were merged. * * @xmlrpc.doc Merges all packages from one channel into another * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "mergeFromLabel", "the label of the * channel to pull packages from") * @xmlrpc.param #param_desc("string", "mergeToLabel", "the label to push the * packages into") * @xmlrpc.returntype * #array() * $PackageSerializer * #array_end() */ public Object[] mergePackages(User loggedInUser, String mergeFromLabel, String mergeToLabel) { Channel mergeFrom = lookupChannelByLabel(loggedInUser, mergeFromLabel); Channel mergeTo = lookupChannelByLabel(loggedInUser, mergeToLabel); if (!UserManager.verifyChannelAdmin(loggedInUser, mergeTo)) { throw new PermissionCheckFailureException(); } List<Package> differentPackages = new ArrayList<Package>(); Set<Package> toPacks = mergeTo.getPackages(); Set<Package> fromPacks = mergeFrom.getPackages(); List<Long> pids = new ArrayList<Long>(); for (Package pack : fromPacks) { if (!toPacks.contains(pack)) { pids.add(pack.getId()); differentPackages.add(pack); } } mergeTo.getPackages().addAll(differentPackages); ChannelFactory.save(mergeTo); ChannelManager.refreshWithNewestPackages(mergeTo, "java::mergePackages"); List<Long> cids = new ArrayList<Long>(); cids.add(mergeTo.getId()); ErrataCacheManager.insertCacheForChannelPackagesAsync(cids, pids); return differentPackages.toArray(); } /** * Regenerate the errata cache for all the systems subscribed to a particular channel * @param loggedInUser The current user * @param channelLabel the channel label * @return int - 1 on success! * * @xmlrpc.doc Completely clear and regenerate the needed Errata and Package * cache for all systems subscribed to the specified channel. This should * be used only if you believe your cache is incorrect for all the systems * in a given channel. This will schedule an asynchronous action to actually * do the processing. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "the label of the * channel") * @xmlrpc.returntype #return_int_success() * */ public int regenerateNeededCache(User loggedInUser, String channelLabel) { channelAdminPermCheck(loggedInUser); Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); List<Long> chanList = new ArrayList<Long>(); chanList.add(chan.getId()); ErrataCacheManager.updateCacheForChannelsAsync(chanList); return 1; } /** * Regenerate the errata cache for all the systems subscribed to the satellite * @param loggedInUser The current user * @return int - 1 on success! * * @xmlrpc.doc Completely clear and regenerate the needed Errata and Package * cache for all systems subscribed. You must be a Satellite Admin to * perform this action. This will schedule an asynchronous action to * actually do the processing. * @xmlrpc.param #session_key() * @xmlrpc.returntype #return_int_success() * */ public int regenerateNeededCache(User loggedInUser) { if (loggedInUser.hasRole(RoleFactory.SAT_ADMIN)) { Set<Channel> set = new HashSet<Channel>(); set.addAll(ChannelFactory.listAllBaseChannels()); ErrataCacheManager.updateCacheForChannelsAsync(set); } else { throw new PermissionException(RoleFactory.SAT_ADMIN); } return 1; } /** * Regenerate the yum cache for a specific channel. * @param loggedInUser The current user * @param channelLabel the channel label * @return int - 1 on success! * * @xmlrpc.doc Regenerate yum cache for the specified channel. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "the label of the * channel") * @xmlrpc.returntype #return_int_success() * */ public int regenerateYumCache(User loggedInUser, String channelLabel) { channelAdminPermCheck(loggedInUser); lookupChannelByLabel(loggedInUser, channelLabel); ChannelManager.queueChannelChange(channelLabel, "api: regenerateYumCache", "api called"); return 1; } /** * List the children of a channel * @param loggedInUser The current user * @param channelLabel the channel label * @return list of channel id's and labels * * @xmlrpc.doc List the children of a channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "the label of the channel") * @xmlrpc.returntype * #array() * $ChannelSerializer * #array_end() */ public Object[] listChildren(User loggedInUser, String channelLabel) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelFactory.getAccessibleChildChannels(chan, loggedInUser).toArray(); } /** * Returns the last build date on the repodata for a channel * @param loggedInUser The current user * @param id - id of channel wanted * @throws NoSuchChannelException thrown if no channel is found. * @return the build date on the repodata of the channel requested * * @xmlrpc.doc Returns the last build date of the repomd.xml file * for the given channel as a localised string. * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "id of channel wanted") * @xmlrpc.returntype the last build date of the repomd.xml file * as a localised string */ public String getChannelLastBuildById(User loggedInUser, Integer id) throws NoSuchChannelException { String repoLastBuild = ChannelManager.getRepoLastBuild(lookupChannelById(loggedInUser, id.longValue())); if (repoLastBuild == null) { return ""; } return repoLastBuild; } /** Returns a list of ContentSource (repos) that the user can see * @param loggedInUser The current user * @return Lists the repos visible to the user * @xmlrpc.doc Returns a list of ContentSource (repos) that the user can see * @xmlrpc.param #session_key() * @xmlrpc.returntype * #array() * #struct("map") * #prop_desc("long","id", "ID of the repo") * #prop_desc("string","label", "label of the repo") * #prop_desc("string","sourceUrl", "URL of the repo") * #struct_end() * #array_end() **/ public List<Map<String, Object>> listUserRepos(User loggedInUser) { List<ContentSource> result = ChannelFactory .lookupContentSources(loggedInUser.getOrg()); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); for (ContentSource cs : result) { Map<String, Object> map = new HashMap<String, Object>(); map.put("id", cs.getId()); map.put("label", cs.getLabel()); map.put("sourceUrl", cs.getSourceUrl()); list.add(map); } return list; } /** * Creates a repository * @param loggedInUser The current user * @param label of the repo to be created * @param type of the repo * @param url of the repo * @return new ContentSource * * @xmlrpc.doc Creates a repository * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param #param_desc("string", "type", "repository type (yum, uln...)") * @xmlrpc.param #param_desc("string", "url", "repository url") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource createRepo(User loggedInUser, String label, String type, String url) { // empty strings for SSL-certificates descriptions String sslCaCert = ""; String sslCliCert = ""; String sslCliKey = ""; return createRepo(loggedInUser, label, type, url, sslCaCert, sslCliCert, sslCliKey); } /** * Creates a repository * @param loggedInUser The current user * @param label of the repo to be created * @param type of the repo * @param url of the repo * @param sslCaCert CA certificate description * @param sslCliCert Client certificate description * @param sslCliKey Client key description * @return new ContentSource * * @xmlrpc.doc Creates a repository * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param #param_desc("string", "type", * "repository type (yum, uln...)") * @xmlrpc.param #param_desc("string", "url", "repository url") * @xmlrpc.param #param_desc("string", "sslCaCert", "SSL CA cert description") * @xmlrpc.param #param_desc("string", "sslCliCert", "SSL Client cert description") * @xmlrpc.param #param_desc("string", "sslCliKey", "SSL Client key description") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource createRepo(User loggedInUser, String label, String type, String url, String sslCaCert, String sslCliCert, String sslCliKey) { if (StringUtils.isEmpty(label)) { throw new InvalidParameterException("label might not be empty"); } if (StringUtils.isEmpty(url)) { throw new InvalidParameterException("url might not be empty"); } type = type.toLowerCase(); BaseRepoCommand repoCmd = new CreateRepoCommand(loggedInUser.getOrg()); repoCmd.setLabel(label); repoCmd.setUrl(url); repoCmd.setType(type); // check SSL-certificates parameters if (!StringUtils.isEmpty(sslCaCert)) { try { // FIXME: Allow to set multiple SSL sets per custom repo - new API calls? repoCmd.addSslSet(getKeyId(loggedInUser, sslCaCert), getKeyId(loggedInUser, sslCliCert), getKeyId(loggedInUser, sslCliKey)); } catch (InvalidCertificateException e) { throw new NoSuchCryptoKeyException(e.getMessage()); } } else if (!StringUtils.isEmpty(sslCliCert) || !StringUtils.isEmpty(sslCliKey)) { log.warn("SSL CA Certificate is missing, ignoring other SSL Certs/Keys"); } repoCmd.store(); ContentSource repo = ChannelFactory.lookupContentSourceByOrgAndLabel( loggedInUser.getOrg(), label); return repo; } /** * Removes a repository * @param loggedInUser The current user * @param id of the repo to be removed * @return Integer 1 on success * * @xmlrpc.doc Removes a repository * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("long", "id", "ID of repo to be removed") * @xmlrpc.returntype #return_int_success() **/ public Integer removeRepo(User loggedInUser, Integer id) { ContentSource repo = lookupContentSourceById(id.longValue(), loggedInUser.getOrg()); ChannelFactory.remove(repo); return 1; } /** * Removes a repository * @param loggedInUser The current user * @param label of the repo to be removed * @return Integer 1 on success * * @xmlrpc.doc Removes a repository * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "label of repo to be removed") * @xmlrpc.returntype #return_int_success() **/ public Integer removeRepo(User loggedInUser, String label) { ContentSource repo = lookupContentSourceByLabel(label, loggedInUser.getOrg()); ChannelFactory.clearContentSourceFilters(repo.getId()); ChannelFactory.remove(repo); return 1; } /** * Associates a repository with a channel * @param loggedInUser The current user * @param chanLabel of the channel to use * @param repoLabel of the repo to associate * @return the channel with the newly associated repo * * @xmlrpc.doc Associates a repository with a channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.param #param_desc("string", "repoLabel", "repository label") * @xmlrpc.returntype $ChannelSerializer **/ public Channel associateRepo(User loggedInUser, String chanLabel, String repoLabel) { Channel channel = lookupChannelByLabel(loggedInUser, chanLabel); ContentSource repo = lookupContentSourceByLabel(repoLabel, loggedInUser.getOrg()); Set<ContentSource> set = channel.getSources(); set.add(repo); ChannelFactory.save(channel); return channel; } /** * Disassociates a repository from a channel * @param loggedInUser The current user * @param chanLabel of the channel to use * @param repoLabel of the repo to disassociate * @return the channel minus the disassociated repo * * @xmlrpc.doc Disassociates a repository from a channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.param #param_desc("string", "repoLabel", "repository label") * @xmlrpc.returntype $ChannelSerializer **/ public Channel disassociateRepo(User loggedInUser, String chanLabel, String repoLabel) { Channel channel = lookupChannelByLabel(loggedInUser, chanLabel); ContentSource repo = lookupContentSourceByLabel(repoLabel, loggedInUser.getOrg()); Set<ContentSource> set = channel.getSources(); set.remove(repo); channel.setSources(set); ChannelFactory.save(channel); return channel; } /** * Updates repository source URL * @param loggedInUser The current user * @param id ID of the repo * @param url new URL to use * @return the updated repo * * @xmlrpc.doc Updates repository source URL * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "repository id") * @xmlrpc.param #param_desc("string", "url", "new repository url") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoUrl(User loggedInUser, Integer id, String url) { ContentSource repo = lookupContentSourceById(id.longValue(), loggedInUser.getOrg()); setRepoUrl(repo, url); ChannelFactory.save(repo); return repo; } /** * Updates repository source URL * @param loggedInUser The current user * @param label of the repo to use * @param url new URL to use * @return the updated repo * * @xmlrpc.doc Updates repository source URL * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param #param_desc("string", "url", "new repository url") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoUrl(User loggedInUser, String label, String url) { ContentSource repo = lookupContentSourceByLabel(label, loggedInUser.getOrg()); setRepoUrl(repo, url); ChannelFactory.save(repo); return repo; } /** * Updates repository SSL certificates * @param loggedInUser The current user * @param id ID of the repository * @param sslCaCert new CA certificate description * @param sslCliCert new Client certificate description * @param sslCliKey new Client key description * @return the updated repository * * @xmlrpc.doc Updates repository SSL certificates * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "repository id") * @xmlrpc.param #param_desc("string", "sslCaCert", "SSL CA cert description") * @xmlrpc.param #param_desc("string", "sslCliCert", "SSL Client cert description") * @xmlrpc.param #param_desc("string", "sslCliKey", "SSL Client key description") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoSsl(User loggedInUser, Integer id, String sslCaCert, String sslCliCert, String sslCliKey) { ContentSource repo = ChannelFactory.lookupContentSource(id.longValue(), loggedInUser.getOrg()); return updateRepoSsl(loggedInUser, repo.getLabel(), sslCaCert, sslCliCert, sslCliKey); } /** * Updates repository SSL certificates * @param loggedInUser The current user * @param label repository label * @param sslCaCert new CA certificate description * @param sslCliCert new Client certificate description * @param sslCliKey new Client key description * @return the updated repository * * @xmlrpc.doc Updates repository SSL certificates * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param #param_desc("string", "sslCaCert", "SSL CA cert description") * @xmlrpc.param #param_desc("string", "sslCliCert", "SSL Client cert description") * @xmlrpc.param #param_desc("string", "sslCliKey", "SSL Client key description") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoSsl(User loggedInUser, String label, String sslCaCert, String sslCliCert, String sslCliKey) { if (StringUtils.isEmpty(label)) { throw new InvalidParameterException("label might not be empty"); } ContentSource repo = ChannelFactory.lookupContentSourceByOrgAndLabel( loggedInUser.getOrg(), label); if (repo == null) { throw new InvalidParameterException("no repo with label " + label); } EditRepoCommand repoEditor = new EditRepoCommand(loggedInUser, repo.getId()); // set new SSL Certificates for the repository if (!StringUtils.isEmpty(sslCaCert)) { try { // FIXME: Allow to set multiple SSL sets per custom repo - new API calls? repoEditor.deleteAllSslSets(); repoEditor.addSslSet(getKeyId(loggedInUser, sslCaCert), getKeyId(loggedInUser, sslCliCert), getKeyId(loggedInUser, sslCliKey)); } catch (InvalidCertificateException e) { throw new NoSuchCryptoKeyException(e.getMessage()); } } else if (!StringUtils.isEmpty(sslCliCert) || !StringUtils.isEmpty(sslCliKey)) { log.warn("SSL CA Certificate is missing, ignoring other SSL Certs/Keys"); } // Store Repo repoEditor.store(); repo = ChannelFactory.lookupContentSourceByOrgAndLabel(loggedInUser.getOrg(), label); return repo; } /** * Updates repository label * @param loggedInUser The current user * @param id ID of the repo * @param label new label * @return the updated repo * * @xmlrpc.doc Updates repository label * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "repository id") * @xmlrpc.param #param_desc("string", "label", "new repository label") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoLabel(User loggedInUser, Integer id, String label) { ContentSource repo = lookupContentSourceById(id.longValue(), loggedInUser.getOrg()); setRepoLabel(repo, label); ChannelFactory.save(repo); return repo; } /** * Updates repository label * @param loggedInUser The current user * @param label of the repo * @param newLabel new label * @return the updated repo * * @xmlrpc.doc Updates repository label * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param #param_desc("string", "newLabel", "new repository label") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepoLabel(User loggedInUser, String label, String newLabel) { ContentSource repo = lookupContentSourceByLabel(label, loggedInUser.getOrg()); setRepoLabel(repo, newLabel); ChannelFactory.save(repo); return repo; } /** * Updates a repository * @param loggedInUser The current user * @param id ID of the repo * @param label new label * @param url new URL * @return the updated repo * * @xmlrpc.doc Updates a ContentSource (repo) * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("int", "id", "repository id") * @xmlrpc.param #param_desc("string", "label", "new repository label") * @xmlrpc.param #param_desc("string", "url", "new repository URL") * @xmlrpc.returntype $ContentSourceSerializer **/ public ContentSource updateRepo(User loggedInUser, Integer id, String label, String url) { ContentSource repo = lookupContentSourceById(id.longValue(), loggedInUser.getOrg()); setRepoLabel(repo, label); setRepoUrl(repo, url); ChannelFactory.save(repo); return repo; } /** * Returns the details of the given repo * @param loggedInUser The current user * @param repoLabel Label of repo whose details are sought. * @return the repo requested. * * @xmlrpc.doc Returns details of the given repository * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "repoLabel", "repo to query") * @xmlrpc.returntype * $ContentSourceSerializer */ public ContentSource getRepoDetails(User loggedInUser, String repoLabel) { return lookupContentSourceByLabel(repoLabel, loggedInUser.getOrg()); } /** * Returns the details of the given repo * @param loggedInUser The current user * @param id ID of repo whose details are sought. * @return the repo requested. * * @xmlrpc.doc Returns details of the given repo * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "repoLabel", "repo to query") * @xmlrpc.returntype * $ContentSourceSerializer */ public ContentSource getRepoDetails(User loggedInUser, Integer id) { return lookupContentSourceById(id.longValue(), loggedInUser.getOrg()); } /** * Lists associated repos with the given channel * @param loggedInUser The current user * @param channelLabel channel label * @return list of associates repos * * @xmlrpc.doc Lists associated repos with the given channel * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.returntype * #array() * $ContentSourceSerializer * #array_end() */ public List<ContentSource> listChannelRepos(User loggedInUser, String channelLabel) { Channel channel = lookupChannelByLabel(loggedInUser, channelLabel); return ChannelFactory.lookupContentSources(loggedInUser.getOrg(), channel); } /** * Trigger immediate repo synchronization * @param loggedInUser The current user * @param channelLabel channel label * @return 1 on success * * @xmlrpc.doc Trigger immediate repo synchronization * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.returntype #return_int_success() */ public int syncRepo(User loggedInUser, String channelLabel) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); new TaskomaticApi().scheduleSingleRepoSync(chan, loggedInUser); return 1; } /** * Trigger immediate repo synchronization * @param loggedInUser The current user * @param channelLabel channel label * @param params parameters * @return 1 on success * * @xmlrpc.doc Trigger immediate repo synchronization * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.param * #struct("params_map") * #prop_desc("Boolean", "sync-kickstart", "Create kickstartable tree - Optional") * #prop_desc("Boolean", "no-errata", "Do not sync errata - Optional") * #prop_desc("Boolean", "fail", "Terminate upon any error - Optional") * #struct_end() * @xmlrpc.returntype #return_int_success() */ public int syncRepo(User loggedInUser, String channelLabel, Map <String, String> params) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); new TaskomaticApi().scheduleSingleRepoSync(chan, loggedInUser, params); return 1; } /** * Schedule periodic repo synchronization * @param loggedInUser The current user * @param channelLabel channel label * @param cronExpr cron expression, if empty all periodic schedules will be disabled * @return 1 on success * * @xmlrpc.doc Schedule periodic repo synchronization * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.param #param_desc("string", "cron expression", * "if empty all periodic schedules will be disabled") * @xmlrpc.returntype #return_int_success() */ public int syncRepo(User loggedInUser, String channelLabel, String cronExpr) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); if (StringUtils.isEmpty(cronExpr)) { new TaskomaticApi().unscheduleRepoSync(chan, loggedInUser); } else { new TaskomaticApi().scheduleRepoSync(chan, loggedInUser, cronExpr); } return 1; } /** * Schedule periodic repo synchronization * @param loggedInUser The current user * @param channelLabel channel label * @param cronExpr cron expression, if empty all periodic schedules will be disabled * @param params parameters * @return 1 on success * * @xmlrpc.doc Schedule periodic repo synchronization * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.param #param_desc("string", "cron expression", * "if empty all periodic schedules will be disabled") * @xmlrpc.param * #struct("params_map") * #prop_desc("Boolean", "sync-kickstart", "Create kickstartable tree - Optional") * #prop_desc("Boolean", "no-errata", "Do not sync errata - Optional") * #prop_desc("Boolean", "fail", "Terminate upon any error - Optional") * #struct_end() * @xmlrpc.returntype #return_int_success() */ public int syncRepo(User loggedInUser, String channelLabel, String cronExpr, Map <String, String> params) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); if (StringUtils.isEmpty(cronExpr)) { new TaskomaticApi().unscheduleRepoSync(chan, loggedInUser); } else { new TaskomaticApi().scheduleRepoSync(chan, loggedInUser, cronExpr, params); } return 1; } /** * Returns repo synchronization quartz expression * @param loggedInUser The current user * @param channelLabel channel label * @return quartz expression * * @xmlrpc.doc Returns repo synchronization cron expression * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "channelLabel", "channel label") * @xmlrpc.returntype string quartz expression */ public String getRepoSyncCronExpression(User loggedInUser, String channelLabel) { Channel chan = lookupChannelByLabel(loggedInUser, channelLabel); String cronExpr = new TaskomaticApi().getRepoSyncSchedule(chan, loggedInUser); if (StringUtils.isEmpty(cronExpr)) { return new String(""); } return cronExpr; } /** * Lists the filters for a repo * @param loggedInUser The current user * @param label of the repo to use * @return list of filters * * @xmlrpc.doc Lists the filters for a repo * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.returntype * #array() * $ContentSourceFilterSerializer * #array_end() * **/ public List<ContentSourceFilter> listRepoFilters(User loggedInUser, String label) { ContentSource cs = lookupContentSourceByLabel(label, loggedInUser.getOrg()); List<ContentSourceFilter> result = ChannelFactory.lookupContentSourceFiltersById(cs.getId()); return result; } /** * adds a filter for a given repo. * @param loggedInUser The current user * @param label of the repo to use * @param filterIn list of filters * @return sort order for the new filter * * @xmlrpc.doc Adds a filter for a given repo. * @xmlrpc.param #param("string", "sessionKey ") * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param * #struct("filter_map") * #prop_desc("string", "filter", "string to filter on") * #prop_desc("string", "flag", "+ for include, - for exclude") * #struct_end() * @xmlrpc.returntype int sort order for new filter */ public int addRepoFilter(User loggedInUser, String label, Map<String, String> filterIn) { Role orgAdminRole = RoleFactory.lookupByLabel("org_admin"); if (!loggedInUser.hasRole(orgAdminRole)) { throw new PermissionException("Only Org Admins can add repo filters."); } ContentSource cs = lookupContentSourceByLabel(label, loggedInUser.getOrg()); String flag = filterIn.get("flag"); String filter = filterIn.get("filter"); if (!(flag.equals("+") || flag.equals("-"))) { throw new InvalidParameterException("flag must be + or -"); } // determine the highest sort order of existing filters int sortOrder = 0; for (ContentSourceFilter f : listRepoFilters(loggedInUser, label)) { sortOrder = Math.max(sortOrder, f.getSortOrder()); } ContentSourceFilter newFilter = new ContentSourceFilter(); newFilter.setSourceId(cs.getId()); newFilter.setFlag(flag); newFilter.setFilter(filter); newFilter.setSortOrder(sortOrder + 1); ChannelFactory.save(newFilter); return sortOrder; } /** * Removes a filter for a given repo. * @param loggedInUser The current user * @param label of the repo to use * @param filterIn list of filters * @return 1 on success * * @xmlrpc.doc Removes a filter for a given repo. * @xmlrpc.param #param("string", "sessionKey ") * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param * #struct("filter_map") * #prop_desc("string", "filter", "string to filter on") * #prop_desc("string", "flag", "+ for include, - for exclude") * #struct_end() * @xmlrpc.returntype #return_int_success() */ public int removeRepoFilter(User loggedInUser, String label, Map<String, String> filterIn) { Role orgAdminRole = RoleFactory.lookupByLabel("org_admin"); if (!loggedInUser.hasRole(orgAdminRole)) { throw new PermissionException("Only Org Admins can remove repo filters."); } //TODO is this necessary? lookupContentSourceByLabel(label, loggedInUser.getOrg()); String flag = filterIn.get("flag"); String filter = filterIn.get("filter"); if (!(flag.equals("+") || flag.equals("-"))) { throw new InvalidParameterException("flag must be + or -"); } // find the existing filter ContentSourceFilter oldFilter = null; for (ContentSourceFilter f : listRepoFilters(loggedInUser, label)) { if (flag.equals(f.getFlag()) && filter.equals(f.getFilter())) { oldFilter = f; break; } } if (oldFilter == null) { throw new InvalidParameterException("filter does not exist"); } ChannelFactory.remove(oldFilter); return 1; } /** * replaces the existing set of filters for a given repo. * filters are ranked by their order in the array. * @param loggedInUser The current user * @param label of the repo to use * @param filtersIn list of filters * @return 1 on success * * @xmlrpc.doc Replaces the existing set of filters for a given repo. * Filters are ranked by their order in the array. * @xmlrpc.param #param("string", "sessionKey ") * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.param * #array() * #struct("filter_map") * #prop_desc("string", "filter", "string to filter on") * #prop_desc("string", "flag", "+ for include, - for exclude") * #struct_end() * #array_end() * @xmlrpc.returntype #return_int_success() */ public int setRepoFilters(User loggedInUser, String label, List<Map<String, String>> filtersIn) { Role orgAdminRole = RoleFactory.lookupByLabel("org_admin"); if (!loggedInUser.hasRole(orgAdminRole)) { throw new PermissionException("Only Org Admins can set repo filters."); } ContentSource cs = lookupContentSourceByLabel(label, loggedInUser.getOrg()); List<ContentSourceFilter> filters = new ArrayList<ContentSourceFilter>(); int i = 1; for (Map<String, String> filterIn : filtersIn) { String flag = filterIn.get("flag"); String filter = filterIn.get("filter"); if (!(flag.equals("+") || flag.equals("-"))) { throw new InvalidParameterException("flag must be + or -"); } ContentSourceFilter f = new ContentSourceFilter(); f.setSourceId(cs.getId()); f.setFlag(flag); f.setFilter(filter); f.setSortOrder(i); filters.add(f); i++; } ChannelFactory.clearContentSourceFilters(cs.getId()); for (ContentSourceFilter filter : filters) { ChannelFactory.save(filter); } return 1; } /** * Clears the filters for a repo * @param loggedInUser The current user * @param label of the repo to use * @return 1 on success * * @xmlrpc.doc Removes the filters for a repo * @xmlrpc.param #session_key() * @xmlrpc.param #param_desc("string", "label", "repository label") * @xmlrpc.returntype #return_int_success() **/ public int clearRepoFilters(User loggedInUser, String label) { Role orgAdminRole = RoleFactory.lookupByLabel("org_admin"); if (!loggedInUser.hasRole(orgAdminRole)) { throw new PermissionException("Only Org Admins can remove repo filters."); } ContentSource cs = lookupContentSourceByLabel(label, loggedInUser.getOrg()); ChannelFactory.clearContentSourceFilters(cs.getId()); return 1; } private ContentSource lookupContentSourceById(Long repoId, Org org) { ContentSource cs = ChannelFactory.lookupContentSource(repoId, org); if (cs == null) { throw new NoSuchContentSourceException(repoId); } return cs; } private ContentSource lookupContentSourceByLabel(String repoLabel, Org org) { ContentSource cs = ChannelFactory.lookupContentSourceByOrgAndLabel(org, repoLabel); if (cs == null) { throw new NoSuchContentSourceException(repoLabel); } return cs; } private void setRepoLabel(ContentSource cs, String repoLabel) { if (StringUtils.isEmpty(repoLabel)) { throw new InvalidParameterException("label might not be empty"); } if (ChannelFactory.lookupContentSourceByOrgAndLabel(cs.getOrg(), repoLabel) != null) { throw new InvalidRepoLabelException(repoLabel); } cs.setLabel(repoLabel); } private void setRepoUrl(ContentSource cs, String repoUrl) { if (StringUtils.isEmpty(repoUrl)) { throw new InvalidParameterException("url might not be empty"); } if (!ChannelFactory.lookupContentSourceByOrgAndRepo(cs.getOrg(), cs.getType(), repoUrl).isEmpty()) { throw new InvalidRepoUrlException(repoUrl); } cs.setSourceUrl(repoUrl); } private Long getKeyId(User loggedInUser, String keyDescription) { if (StringUtils.isEmpty(keyDescription)) { return null; } CryptoKey key = KickstartFactory.lookupCryptoKey(keyDescription, loggedInUser.getOrg()); if (key == null) { throw new NoSuchCryptoKeyException("no key with such description - " + keyDescription); } return key.getId(); } }