
-- drop dependend views
DROP VIEW IF EXISTS rhnOrgErrata;
DROP VIEW IF EXISTS rhnAvailableChannels;
DROP VIEW IF EXISTS rhnSharedChannelTreeView;
DROP VIEW IF EXISTS suseChannelUserRoleView;

-- drop the view we need to change
DROP VIEW IF EXISTS rhnSharedChannelView;

-- create the view again
CREATE OR REPLACE VIEW RHNSHAREDCHANNELVIEW
AS
SELECT 
   CH.ID,
   CH.PARENT_CHANNEL,
   CH.ORG_ID,
   CH.CHANNEL_ARCH_ID,
   CH.LABEL,
   CH.BASEDIR,
   CH.NAME,
   CH.SUMMARY,
   CH.DESCRIPTION,
   CH.PRODUCT_NAME_ID,
   CH.GPG_KEY_URL,
   CH.GPG_KEY_ID,
   CH.GPG_KEY_FP,
   CH.END_OF_LIFE,
   CH.LAST_MODIFIED,
   CH.CHANNEL_PRODUCT_ID,
   CH.CREATED,
   CH.MODIFIED,
   CH.CHANNEL_ACCESS,
   TR.ORG_TRUST_ID
FROM RHNCHANNEL CH,
     RHNTRUSTEDORGS TR
WHERE CH.ORG_ID = TR.ORG_ID AND
      CH.CHANNEL_ACCESS = 'public'
UNION
SELECT
   CH.ID,
   CH.PARENT_CHANNEL,
   CH.ORG_ID,
   CH.CHANNEL_ARCH_ID,
   CH.LABEL,
   CH.BASEDIR,
   CH.NAME,
   CH.SUMMARY,
   CH.DESCRIPTION,
   CH.PRODUCT_NAME_ID,
   CH.GPG_KEY_URL,
   CH.GPG_KEY_ID,
   CH.GPG_KEY_FP,
   CH.END_OF_LIFE,
   CH.LAST_MODIFIED,
   CH.CHANNEL_PRODUCT_ID,
   CH.CREATED,
   CH.MODIFIED,
   CH.CHANNEL_ACCESS,
   TR.ORG_TRUST_ID
FROM RHNCHANNEL CH,
     RHNCHANNELTRUST TR
WHERE CH.ID = TR.CHANNEL_ID AND
      CH.CHANNEL_ACCESS = 'protected'
;

-- create the dependend view again
CREATE OR REPLACE VIEW
suseChannelUserRoleView
AS
  SELECT
    combination.channel_id,
    combination.user_id,
    combination.role,
    combination.user_org_id AS org_id,
    combination.parent_channel_id,
    CASE
      -- if channel is in an org trusted by the user's org, and if the channel itself is shared between the two, then user can subscribe it
      WHEN combination.role = 'subscribe' AND sharedChannels.is_shared_channel IS NOT NULL
        THEN NULL
      -- otherwise, if channel is not in user's org, then user can't manage it
      WHEN combination.role = 'manage' AND combination.channel_org_id IS NULL OR combination.channel_org_id <> combination.user_org_id
        THEN 'channel_not_owned'
      -- otherwise, if channel is in a family without permissions for the user's org, then user can't subscribe it
      WHEN combination.role = 'subscribe' AND channelPermissions.is_channel_available IS NULL
        THEN 'channel_not_available'
      -- otherwise, if channel is in a family without permissions for the user's org, then user can't subscribe it
      WHEN adminUsers.is_admin_user IS NOT NULL
        THEN NULL
      WHEN channelAdmins.is_channel_admin IS NOT NULL
        THEN NULL
      -- otherwise, if channel does not have the "not_globally_subscribable" bit set, user can subscribe it
      WHEN combination.role = 'subscribe' AND notGloballySubscribableChannels.is_not_globally_subscribable IS NULL
        THEN NULL
      -- otherwise, user might have an explicit permission on this channel
      WHEN explicitPermissions.has_explicit_permission IS NOT NULL
        THEN NULL
        -- otherwise, user can't either manage nor subscribe the channel
        ELSE 'direct_permission'
    END AS deny_reason
    FROM
      (SELECT
          c.id AS channel_id,
          c.org_id AS channel_org_id,
          c.parent_channel AS parent_channel_id,
          u.id AS user_id,
          u.org_id AS user_org_id,
          r.label AS role
          FROM rhnChannel c, web_contact u, rhnChannelPermissionRole r
      ) combination
     LEFT JOIN
       (SELECT DISTINCT s.org_trust_id, s.id, 1 AS is_shared_channel
        FROM rhnSharedChannelView s) sharedChannels
     ON (sharedChannels.id = combination.channel_id AND sharedChannels.org_trust_id = combination.user_org_id)
     LEFT JOIN
       (SELECT DISTINCT cfp.org_id, cfm.channel_id, 1 AS is_channel_available
        FROM rhnChannelFamilyMembers cfm
          JOIN rhnOrgChannelFamilyPermissions cfp ON cfp.channel_family_id = cfm.channel_family_id) channelPermissions
     ON (combination.user_org_id = channelPermissions.org_id AND channelPermissions.channel_id = combination.channel_id)
     LEFT JOIN
       (SELECT DISTINCT m.user_id, 1 AS is_admin_user
        FROM rhnUserGroupMembers m
          JOIN rhnUserGroup g ON g.id = m.user_group_id
          JOIN rhnUserGroupType t ON t.id = g.group_type
        WHERE t.label = 'org_admin') adminUsers
     ON (adminUsers.user_id = combination.user_id)
     LEFT JOIN
       (SELECT DISTINCT uag.user_id, 1 AS is_channel_admin
        FROM access.userAccessGroup uag
          JOIN access.accessGroup ag ON ag.id = uag.group_id
        WHERE ag.label = 'channel_admin' AND ag.org_id IS NULL) channelAdmins
     ON (channelAdmins.user_id = combination.user_id)
     LEFT JOIN
       (SELECT DISTINCT ocs.channel_id, ocs.org_id, 1 AS is_not_globally_subscribable
        FROM rhnOrgChannelSettings ocs
          JOIN rhnOrgChannelSettingsType ocst ON ocst.id = ocs.setting_id
        WHERE ocst.label = 'not_globally_subscribable') notGloballySubscribableChannels
     ON (notGloballySubscribableChannels.channel_id = combination.channel_id AND notGloballySubscribableChannels.org_id = combination.user_org_id)
     LEFT JOIN
       (SELECT cpr.label, cp.channel_id, cp.user_id, 1 AS has_explicit_permission
        FROM rhnChannelPermission cp
          JOIN rhnChannelPermissionRole cpr ON cpr.id = cp.role_id) explicitPermissions
     ON (explicitPermissions.channel_id = combination.channel_id AND explicitPermissions.user_id = combination.user_id AND explicitPermissions.label = combination.role)
    -- ORDER BY channel_id, user_id, role, result
;

CREATE OR REPLACE VIEW RHNSHAREDCHANNELTREEVIEW
(
  ORG_ID,
  ID,
  DEPTH,
  NAME,
  PADDED_NAME,
  CHANNEL_ARCH_ID,
  LAST_MODIFIED,
  LABEL,
  PARENT_OR_SELF_LABEL,
  PARENT_OR_SELF_ID,
  END_OF_LIFE
)
AS
SELECT * FROM (
  SELECT
    C.ORG_TRUST_ID AS ORG_ID,
    C.ID,
    1 AS DEPTH,
    C.NAME,
    '  '||C.NAME AS PADDED_NAME,
    C.CHANNEL_ARCH_ID,
    C.LAST_MODIFIED,
    C.LABEL,
    C.LABEL AS PARENT_OR_SELF_LABEL,
    C.ID AS PARENT_OR_SELF_ID,
    C.END_OF_LIFE
  FROM RHNSHAREDCHANNELVIEW C
  WHERE C.PARENT_CHANNEL IS NULL
  UNION
  SELECT
    C.ORG_TRUST_ID AS ORG_ID,
    C.ID,
    2 AS DEPTH,
    c.name,
    ''||C.NAME AS PADDED_NAME,
    C.CHANNEL_ARCH_ID,
    C.LAST_MODIFIED,
    C.LABEL,
    PC.LABEL AS PARENT_OR_SELF_LABEL,
    PC.ID AS PARENT_OR_SELF_ID,
    C.END_OF_LIFE
  FROM RHNCHANNEL PC,
       RHNSHAREDCHANNELVIEW C
  WHERE C.PARENT_CHANNEL = PC.ID
) SHARRED
ORDER BY PARENT_OR_SELF_LABEL, PARENT_OR_SELF_ID;


create or replace view
rhnAvailableChannels
(
	org_id,
	channel_id,
	channel_depth,
	channel_name,
	channel_arch_id,
	padded_name,
        last_modified,
        channel_label,
	parent_or_self_label,
	parent_or_self_id
)
as
select
     ct.org_id,
     ct.id,
     CT.depth,
     CT.name,
     CT.channel_arch_id,
     CT.padded_name,
     CT.last_modified,
     CT.label,
     CT.parent_or_self_label,
     CT.parent_or_self_id
from
     rhnOrgChannelTreeView CT
UNION ALL
select
     ct.org_id,
     ct.id,
     CT.depth,
     CT.name,
     CT.channel_arch_id,
     CT.padded_name,
     CT.last_modified,
     CT.label,
     CT.parent_or_self_label,
     CT.parent_or_self_id
from
     rhnSharedChannelTreeView CT
;

create or replace view
rhnOrgErrata
(
	org_id,
	errata_id,
	channel_id
)
as
select
    ac.org_id,
    ce.errata_id,
    ac.channel_id
from
    rhnChannelErrata ce,
    rhnAvailableChannels ac
where
    ce.channel_id = ac.channel_id
;
