I'm not sure if there's a patch review procedure for FAS, so rather than
dumping this in a ticket I've elected to post it here.  If a ticket
would be better, please let me know.

After wishing for some time that we could make the packager group closed
to applications by users, I went ahead and (with help from Ricky and
Toshio) set up a local FAS instance and hacked up the following patch.
All it does is provide an additional group property, invite_only, with
the necessary interface to view and change it, along with a help
string.  When set, the "Apply" links and buttons are hidden.

This is just a first-pass hack from someone who doesn't know what
they're doing.  It might not be enough to just hide the links, but it's
a start.  I'm not really satisfied with how long the extra conditionals
make some of the bits in the templates, and I'm not sure it's good
interface policy to leave the position in the group list completely
blank when the user is not a member and the group is invite only.  (I
don't know how to do nested conditionals in genshi, if that's even
possible, so....)

I included a change to the README file which would have smoothed the
setup process a bit for me, but I did not delete the sqlalchemy section.
An error in the fas2.sql file was also fixed (an index was being created
on a column that didn't exist).

Suggestions welcome.  Commit if you like.  None of this warrants
copyright on any of the files.  I removed my local fas.cfg changes so
the diffstat is wrong.

 - J<

 README                           |    4 ++--
 fas.cfg                          |   14 +++++++-------
 fas/group.py                     |    5 +++--
 fas/help.py                      |    1 +
 fas/templates/group/edit.html    |    6 ++++++
 fas/templates/group/list.html    |    4 ++--
 fas/templates/group/members.html |    2 +-
 fas/templates/group/view.html    |    6 +++++-
 fas2.sql                         |    2 +-
 9 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/README b/README
index db648e7..da61da3 100644
--- a/README
+++ b/README
@@ -82,14 +82,14 @@ Before you can get started, make sure to have the following 
packages installed
   yum install git-core postgresql-plpython postgresql-server postgresql-python 
\
   python-TurboMail TurboGears pygpgme python-sqlalchemy python-genshi \
   python-psycopg2 pytz python-babel babel python-GeoIP python-openid \
-  python-fedora python-migrate python-memcached python-tgcaptcha
+  python-fedora python-migrate python-memcached python-tgcaptcha pyOpenSSL 
gettext
 
   # Note: on RHEL5 you need postgresql-pl instead of postgresql-plpython
 
   yum install git-core postgresql-pl postgresql-server postgresql-python \
   python-TurboMail TurboGears pygpgme python-sqlalchemy python-genshi \
   python-psycopg2 pytz python-babel babel python-GeoIP python-openid \
-  python-fedora python-migrate python-memcached python-tgcaptcha
+  python-fedora python-migrate python-memcached python-tgcaptcha pyOpenSSL 
gettext
 
 At present, the database needs to be a postgres database since we use triggers
 to manage some of the data (like syncing accounts with bugzilla).
diff --git a/fas/group.py b/fas/group.py
index cda2265..6c6cd52 100644
--- a/fas/group.py
+++ b/fas/group.py
@@ -290,8 +290,8 @@ class Group(controllers.Controller):
     @expose(template="fas.templates.group.edit")
     def save(self, groupname, display_name, owner, group_type, 
              needs_sponsor=0, user_can_remove=1, prerequisite='', 
-             url='', mailing_list='', mailing_list_url='', irc_channel='', 
-             irc_network='', joinmsg='', apply_rules="None"):
+             url='', mailing_list='', mailing_list_url='', invite_only=0,
+             irc_channel='', irc_network='', joinmsg='', apply_rules="None"):
         '''Edit a group'''
         username = turbogears.identity.current.user_name
         person = People.by_username(username)
@@ -316,6 +316,7 @@ class Group(controllers.Controller):
                 group.url = url
                 group.mailing_list = mailing_list
                 group.mailing_list_url = mailing_list_url
+                group.invite_only = invite_only
                 group.irc_channel = irc_channel
                 group.irc_network = irc_network
                 group.joinmsg = joinmsg
diff --git a/fas/help.py b/fas/help.py
index 41acde2..09b88c1 100644
--- a/fas/help.py
+++ b/fas/help.py
@@ -54,6 +54,7 @@ class Help(controllers.Controller):
             'group_url':            [_('Group URL (Optional)'), _('''<p>A URL 
or wiki page for the group (for example, <a 
href="https://fedoraproject.org/wiki/Infrastructure";>https://fedoraproject.org/wiki/Infrastructure</a>).</p>''')],
             'group_mailing_list':     [_('Group Mailing List (Optional)'), 
_('''<p>A mailing list for the group (for example, 
[email protected]).</p>''')],
             'group_mailing_list_url': [_('Group Mailing List URL (Optional)'), 
_('''<p>A URL for the group's mailing list (for example, <a 
href="http://www.redhat.com/mailman/listinfo/fedora-infrastructure-list";>http://www.redhat.com/mailman/listinfo/fedora-infrastructure-list</a>).</p>''')],
+            'group_invite_only': [_('Invite Only'), _('''<p>If users should 
not normally be able to apply to the group, setting this will hide the usual 
"Apply!" links and buttons.  Users can still be added to a group directly by an 
admin or sponsor.</p>''')],
             'group_irc_channel': [_('Group IRC Channel (Optional)'), 
_('''<p>An IRC channel for the group (for example, #fedora-admin).</p>''')],
             'group_irc_network': [_('Group IRC Network (Optional)'), 
_('''<p>The IRC Network for the group's IRC channel (for example, 
Freenode).</p>''')],
             'group_needs_sponsor':  [_('Needs Sponsor'), _('''<p>If your group 
requires sponsorship (recommended), this means that when a user is approved by 
a sponsor.  That relationship is recorded in the account system.  If user A 
sponsors user N, then in viewing the members of this group, people will know to 
contact user A about user N if something goes wrong.  If this box is unchecked, 
this means that only approval is needed and no relationship is recorded about 
who did the approving</p>''')],
diff --git a/fas/templates/group/edit.html b/fas/templates/group/edit.html
index 2ab9b33..2dcbcc4 100644
--- a/fas/templates/group/edit.html
+++ b/fas/templates/group/edit.html
@@ -50,6 +50,12 @@
         <script type="text/javascript">var group_owner = new 
HelpBalloon({dataURL: '${tg.url('/help/get_help/group_owner')}'});</script>
       </div>
       <div class="field">
+        <label for="invite_only">${_('Invite Only:')}</label>
+        <input py:if="group.invite_only" type="checkbox" id="invite_only" 
name="invite_only" value="1" checked="checked" />
+        <input py:if="not group.invite_only" type="checkbox" id="invite_only" 
name="invite_only" value="1" />
+        <script type="text/javascript">var group_invite_only = new 
HelpBalloon({dataURL: 
'${tg.url('/help/get_help/group_invite_only')}'});</script>
+      </div>
+      <div class="field">
         <label for="needs_sponsor">${_('Needs Sponsor:')}</label>
         <input py:if="group.needs_sponsor" type="checkbox" id="needs_sponsor" 
name="needs_sponsor" value="1" checked="checked" />
         <input py:if="not group.needs_sponsor" type="checkbox" 
id="needs_sponsor" name="needs_sponsor" value="1" />
diff --git a/fas/templates/group/list.html b/fas/templates/group/list.html
index 9c45055..99f1e18 100644
--- a/fas/templates/group/list.html
+++ b/fas/templates/group/list.html
@@ -40,8 +40,8 @@
               <span class="approved" py:if="group in 
person.approved_memberships">${_('Approved')}</span>
               <span class="unapproved" py:if="group in 
person.unapproved_memberships">${_('Unapproved')}</span>
             </a>
-            <a py:if="group not in person.memberships" 
href="${tg.url('/group/application_screen/%s/%s' % (group.name, 
person.username))}"><span>${_('Apply')}</span></a>
-            <script py:if="group not in person.memberships" 
type="text/javascript">var hb1 = new HelpBalloon({dataURL: 
'${tg.url('/help/get_help/group_apply')}'});</script>
+            <a py:if="not group.invite_only and group not in 
person.memberships" href="${tg.url('/group/application_screen/%s/%s' % 
(group.name, person.username))}"><span>${_('Apply')}</span></a>
+            <script py:if="not group.invite_only and group not in 
person.memberships" type="text/javascript">var hb1 = new HelpBalloon({dataURL: 
'${tg.url('/help/get_help/group_apply')}'});</script>
           </td>
         </tr>
       </tbody>
diff --git a/fas/templates/group/members.html b/fas/templates/group/members.html
index 0339ebb..d13b41d 100644
--- a/fas/templates/group/members.html
+++ b/fas/templates/group/members.html
@@ -25,7 +25,7 @@
       <span py:if="group in person.memberships and not group in 
person.approved_memberships" class="unapproved">${_('Unapproved')}</span>
       <span py:if="not group in person.memberships">${_('Not a Member')}</span>
     </h3>
-    <form py:if="not group in person.memberships" 
action="${tg.url('/group/application_screen/%s/%s' % (group.name, 
person.username))}">
+    <form py:if="not group.invite_only and not group in person.memberships" 
action="${tg.url('/group/application_screen/%s/%s' % (group.name, 
person.username))}">
       <div>
         <!--<input type="text" name="requestField" value="${_('Please let me 
join...')}" />-->
         <input type="submit" value="${('Apply!')}" />
diff --git a/fas/templates/group/view.html b/fas/templates/group/view.html
index 62f7f22..17629af 100644
--- a/fas/templates/group/view.html
+++ b/fas/templates/group/view.html
@@ -23,7 +23,7 @@
       <span py:if="group in person.memberships and not group in 
person.approved_memberships" class="unapproved">${_('Unapproved')}</span>
       <span py:if="not group in person.memberships">${_('Not a Member')}</span>
     </h3>
-    <form py:if="not group in person.memberships" 
action="${tg.url('/group/application_screen/%s/%s' % (group.name, 
person.username))}">
+    <form py:if="not group.invite_only and not group in person.memberships" 
action="${tg.url('/group/application_screen/%s/%s' % (group.name, 
person.username))}">
       <div>
         <!--<input type="text" name="requestField" value="${_('Please let me 
join...')}" />-->
         <input type="submit" value="${('Apply!')}" />
@@ -61,6 +61,10 @@
         </dd>
         </py:if>
 
+        <dt>${_('Invite Only:')}</dt><dd>
+        <py:if test="group.invite_only">${_('Yes')}</py:if>
+        <py:if test="not group.invite_only">${_('No')}</py:if>
+        &nbsp;</dd>
         <dt>${_('Needs Sponsor:')}</dt><dd>
         <py:if test="group.needs_sponsor">${_('Yes')}</py:if>
         <py:if test="not group.needs_sponsor">${_('No')}</py:if>
diff --git a/fas2.sql b/fas2.sql
index c91cb19..d55be60 100644
--- a/fas2.sql
+++ b/fas2.sql
@@ -110,6 +110,7 @@ CREATE TABLE groups (
     group_type VARCHAR(16),
     needs_sponsor BOOLEAN DEFAULT FALSE,
     user_can_remove BOOLEAN DEFAULT TRUE,
+    invite_only BOOLEAN DEFAULT FALSE,
     prerequisite_id INTEGER REFERENCES groups(id),
     joinmsg TEXT NULL DEFAULT '',
     apply_rules TEXT,
@@ -120,7 +121,6 @@ CREATE TABLE groups (
 );
 
 create index groups_group_type_idx on groups(group_type);
-create index groups_email_idx on groups(email);
 cluster groups_group_type_idx on groups;
 
 CREATE TABLE person_roles (
_______________________________________________
infrastructure mailing list
[email protected]
https://admin.fedoraproject.org/mailman/listinfo/infrastructure

Reply via email to