You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by st...@apache.org on 2013/03/11 21:55:08 UTC

git commit: organization neighborhood and project

Updated Branches:
  refs/heads/sg/5566 f7cc73d4e -> c4e7da6ec


organization neighborhood and project

Signed-off-by: Stefano Invernizzi <st...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/incubator-allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-allura/commit/c4e7da6e
Tree: http://git-wip-us.apache.org/repos/asf/incubator-allura/tree/c4e7da6e
Diff: http://git-wip-us.apache.org/repos/asf/incubator-allura/diff/c4e7da6e

Branch: refs/heads/sg/5566
Commit: c4e7da6ec3601989690be78cbab779ad0cb581cb
Parents: f7cc73d
Author: Simone Gatti <si...@gmail.com>
Authored: Sun Mar 10 21:49:19 2013 +0100
Committer: Stefano Invernizzi <st...@apache.org>
Committed: Mon Mar 11 21:42:50 2013 +0100

----------------------------------------------------------------------
 Allura/allura/controllers/root.py                  |    4 +-
 Allura/allura/lib/app_globals.py                   |    2 +-
 Allura/allura/model/project.py                     |   28 ++-
 Allura/allura/nf/allura/css/allura.css             |   13 +
 Allura/allura/websetup/bootstrap.py                |    7 +
 .../organization/controller/organization.py        |  271 +--------------
 .../organization/model/organization.py             |   26 +-
 .../organization/templates/edit_profile.html       |  118 ------
 .../templates/organization_profile.html            |  185 ----------
 .../organization/templates/user_memberships.html   |    3 +-
 .../organization/widgets/forms.py                  |   42 +--
 .../organization_profile/__init__.py               |    1 +
 .../organization_profile/organization_main.py      |  277 +++++++++++++++
 .../templates/edit_profile.html                    |  111 ++++++
 .../templates/organization_index.html              |  206 +++++++++++
 .../forgeorganization/tests/test_organizations.py  |  123 ++-----
 .../tool/controller/organizationtool.py            |    6 +-
 ForgeOrganization/setup.py                         |    2 +-
 18 files changed, 704 insertions(+), 721 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/Allura/allura/controllers/root.py
----------------------------------------------------------------------
diff --git a/Allura/allura/controllers/root.py b/Allura/allura/controllers/root.py
index 9c2b2ba..d286437 100644
--- a/Allura/allura/controllers/root.py
+++ b/Allura/allura/controllers/root.py
@@ -70,8 +70,8 @@ class RootController(WsgiDispatchController):
             n.bind_controller(self)
         self.browse = ProjectBrowseController()
 
-        ep = g.entry_points["organizations"].get('organization')
-        if ep and g.show_organizations:
+        if g.show_organizations:
+            ep = g.entry_points["organizations"].get('organization')
             self.organization = ep().root
 
         super(RootController, self).__init__()

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/Allura/allura/lib/app_globals.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/app_globals.py b/Allura/allura/lib/app_globals.py
index ad1f62b..845832a 100644
--- a/Allura/allura/lib/app_globals.py
+++ b/Allura/allura/lib/app_globals.py
@@ -171,7 +171,7 @@ class Globals(object):
         # Zarkov logger
         self._zarkov = None
 
-        self.show_organizations = config.get('organizations.enable')=='true'
+        self.show_organizations = 'organization' in self.entry_points['organizations']
 
     @LazyProperty
     def spam_checker(self):

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/Allura/allura/model/project.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/project.py b/Allura/allura/model/project.py
index 9b24036..0a279c8 100644
--- a/Allura/allura/model/project.py
+++ b/Allura/allura/model/project.py
@@ -290,6 +290,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
     def is_user_project(self):
         return self.shortname.startswith('u/')
 
+    @property
+    def is_organization_project(self):
+        return self.shortname.startswith('o/')
+
     @LazyProperty
     def user_project_of(self):
         '''
@@ -301,6 +305,17 @@ class Project(MappedClass, ActivityNode, ActivityObject):
         return user
 
     @LazyProperty
+    def organization_project_of(self):
+        '''
+        If this is a organization-project, return the Organization, else None
+        '''
+        user = None
+        if self.is_organization_project:
+            from forgeorganization.organization.model import Organization
+            organization = Organization.query.get(shortname=self.shortname[2:])
+        return organization
+
+    @LazyProperty
     def root_project(self):
         if self.is_root: return self
         return self.parent_project.root_project
@@ -407,6 +422,11 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             max_ordinal = delta_ordinal
             delta_ordinal = delta_ordinal + 1
 
+        if self.is_organization_project:
+            entries.append({'ordinal': delta_ordinal, 'entry':SitemapEntry('Profile', "%sorganizationprofile/" % self.url(), ui_icon="tool-home")})
+            max_ordinal = delta_ordinal
+            delta_ordinal = delta_ordinal + 1
+
         for sub in self.direct_subprojects:
             ordinal = sub.ordinal + delta_ordinal
             if ordinal > max_ordinal:
@@ -629,6 +649,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
             for mount in mounts:
                 if 'ac' in mount and mount['ac'].tool_name == 'profile':
                     return mount
+        if self.is_organization_project:
+            for mount in mounts:
+                if 'ac' in mount and mount['ac'].tool_name == 'organizationprofile':
+                    return mount
         if mounts and required_access is None:
             return mounts[0]
         for mount in mounts:
@@ -720,8 +744,10 @@ class Project(MappedClass, ActivityNode, ActivityObject):
                 apps = [('admin', 'admin', 'Admin'),
                         ('search', 'search', 'Search'),
                         ('activity', 'activity', 'Activity')]
-        if g.show_organizations:
+        if g.show_organizations and not (self.is_organization_project or is_user_project):
             apps+=[('organizationstool', 'organizationstool', 'Organizations')]
+        if self.is_organization_project:
+            apps=[('organizationprofile', 'organizationprofile', 'Profile')]+apps
         with h.push_config(c, project=self, user=users[0]):
             # Install default named roles (#78)
             root_project_id=self.root_project._id

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/Allura/allura/nf/allura/css/allura.css
----------------------------------------------------------------------
diff --git a/Allura/allura/nf/allura/css/allura.css b/Allura/allura/nf/allura/css/allura.css
index 224ad0a..3edeb03 100644
--- a/Allura/allura/nf/allura/css/allura.css
+++ b/Allura/allura/nf/allura/css/allura.css
@@ -41,6 +41,11 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
   background-repeat: no-repeat;
 }
 
+.ui-icon-tool-organizationprofile {
+  background-image: url("../images/home_24.png");
+  background-repeat: no-repeat;
+}
+
 .ui-icon-tool-wiki {
   background-image: url("../images/wiki_24.png");
   background-repeat: no-repeat;
@@ -120,6 +125,11 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
 {
   background-image: url("../images/code_32.png");
 }
+
+.ui-icon-tool-organizationprofile{
+  background-image: url("../images/home_32.png");
+  background-repeat: no-repeat;
+}
 #top_nav .ui-icon-tool-stats {
   background-image: url("../images/stats_32.png");
 }
@@ -153,6 +163,9 @@ b.ico.ico-vote-down { background-image: url('../images/vote_down.png'); }
 .big_icon.ui-icon-tool-home {
   background-image: url("../images/home_48.png");
 }
+.big_icon.ui-icon-tool-organizationprofile {
+  background-image: url("../images/home_48.png");
+}
 .big_icon.ui-icon-tool-wiki {
   background-image: url("../images/wiki_48.png");
 }

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/Allura/allura/websetup/bootstrap.py
----------------------------------------------------------------------
diff --git a/Allura/allura/websetup/bootstrap.py b/Allura/allura/websetup/bootstrap.py
index 59d240d..75150ba 100644
--- a/Allura/allura/websetup/bootstrap.py
+++ b/Allura/allura/websetup/bootstrap.py
@@ -93,6 +93,12 @@ def bootstrap(command, conf, vars):
                                            max_projects = None,
                                            css = 'none',
                                            google_analytics = False))
+    n_organizations = M.Neighborhood(name='Organizations', url_prefix='/o/',
+                             shortname_prefix='o/',
+                             features=dict(private_projects = True,
+                                           max_projects = None,
+                                           css = 'none',
+                                           google_analytics = False))
     n_adobe = M.Neighborhood(name='Adobe', url_prefix='/adobe/', project_list_url='/adobe/',
                              features=dict(private_projects = True,
                                            max_projects = None,
@@ -103,6 +109,7 @@ def bootstrap(command, conf, vars):
     p_projects = project_reg.register_neighborhood_project(n_projects, [root], allow_register=True)
     p_users = project_reg.register_neighborhood_project(n_users, [root])
     p_adobe = project_reg.register_neighborhood_project(n_adobe, [root])
+    p_organizations = project_reg.register_neighborhood_project(n_organizations, [root])
     ThreadLocalORMSession.flush_all()
     ThreadLocalORMSession.close_all()
 

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/controller/organization.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/controller/organization.py b/ForgeOrganization/forgeorganization/organization/controller/organization.py
index f9f4213..1e2bada 100644
--- a/ForgeOrganization/forgeorganization/organization/controller/organization.py
+++ b/ForgeOrganization/forgeorganization/organization/controller/organization.py
@@ -19,10 +19,6 @@ from pkg_resources import get_entry_info
 class Forms(object):
     registration_form = forms.RegistrationForm(action='/organization/save_new')
     search_form = forms.SearchForm(action='/organization/search')
-    update_profile = forms.UpdateProfile()
-    add_work_field = forms.AddWorkField()
-    remove_work_field = forms.RemoveWorkField()
-    invite_user_form = forms.InviteUser()
     admission_request_form = forms.RequestAdmissionForm()
     request_collaboration_form = forms.RequestCollaborationForm()
 
@@ -38,14 +34,6 @@ class Forms(object):
 F = Forms()
 
 class OrganizationController(object):
-    @expose()
-    def _lookup(self, shortname, *remainder):
-        org = Organization.query.get(shortname=shortname)
-        if not org:
-            return OrganizationController(), remainder
-        else:
-            return OrganizationProfileController(organization=org), remainder
-
     @expose('jinja:forgeorganization:organization/templates/user_memberships.html')
     def index(self, **kw):
         require_authenticated()
@@ -74,169 +62,31 @@ class OrganizationController(object):
     @require_post()
     @validate(F.registration_form, error_handler=register)
     def save_new(self, fullname, shortname, orgtype, role, **kw):
-        o = Organization.register(shortname, fullname, orgtype)
+        o = Organization.register(shortname, fullname, orgtype, c.user)
         if o is None: 
             flash(
                 'The short name "%s" has been taken by another organization.' \
                 % shortname, 'error')
             redirect('/organization/register')
-        m = Membership.insert('admin', role, 'active', o._id, c.user._id)
+        m = Membership.insert(role, 'active', o._id, c.user._id)
         flash('Organization "%s" correctly created!' % fullname)
-        redirect('/organization/%s/edit_profile' % shortname)
-
-class OrganizationProfileController(BaseController):
-    def __init__(self, organization):
-        self.organization = organization
-        super(OrganizationProfileController, self).__init__()
-
-    @with_trailing_slash
-    @expose('jinja:forgeorganization:organization/templates/organization_profile.html')
-    def index(self, **kw):        
-        activecoll=[coll for coll in self.organization.project_involvements
-                    if coll.status=='active']
-        closedcoll=[p for p in self.organization.project_involvements 
-                    if p.status=='closed']
-
-        role = self.organization.userPermissions(c.user)
-        mlist=[m for m in self.organization.memberships if m.status=='active']
-        plist=[m for m in self.organization.memberships if m.status=='closed']
-
-        is_admin = (role == 'admin')
-        
-        return dict(
-            workfields = WorkFields.query.find(),
-            members = mlist,
-            past_members=plist,
-            active_collaborations=activecoll,
-            closed_collaborations=closedcoll,
-            organization = self.organization,
-            is_member = (role is not None),
-            is_admin = (role =='admin'),
-            forms = F)
-        
-    @expose('jinja:forgeorganization:organization/templates/edit_profile.html')
-    def edit_profile(self, **kw):
-        require_authenticated()
-        
-        mlist=[m for m in self.organization.memberships if m.status!='closed']
-        clist=[el for el in self.organization.project_involvements 
-               if el.status!='closed']
-
-        return dict(
-            permissions = self.organization.userPermissions(c.user),
-            organization = self.organization,
-            members = mlist,
-            collaborations= clist,
-            forms = F)
-
-    @expose()
-    @require_post()
-    @validate(F.update_profile, error_handler=edit_profile)
-    def change_data(self, **kw):
-        require_authenticated()
-        if self.organization.userPermissions(c.user) != 'admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect(self.organization.url())
-        self.organization.organization_type = kw['organization_type']
-        self.organization.fullname = kw['fullname']
-        self.organization.description = kw['description']
-        self.organization.headquarters = kw['headquarters']
-        self.organization.dimension = kw['dimension']
-        self.organization.website = kw['website']
-
-        flash('The organization profile has been successfully updated.')
-        redirect(self.organization.url()+'edit_profile')
-
-    @expose()
-    @require_post()
-    @validate(F.remove_work_field, error_handler=edit_profile)
-    def remove_work_field(self, **kw):
-        require_authenticated()
-        if self.organization.userPermissions(c.user) != 'admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect(self.organization.url())
-        self.organization.removeWorkField(kw['workfield'])
-        flash('The organization profile has been successfully updated.')
-        redirect(self.organization.url()+'edit_profile')
-
-    @expose()
-    @require_post()
-    @validate(V.NullValidator(), error_handler=edit_profile)
-    def add_work_field(self, workfield, **kw):
-        require_authenticated()
-        workfield = WorkFields.getById(workfield)
-
-        if workfield is None:
-            flash("Invalid workfield. Select a valid value.", "error")
-            redirect(self.organization.url()+'edit_profile')
-
-        if self.organization.userPermissions(c.user)!='admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect(self.organization.url())
-        self.organization.addWorkField(workfield)
-        flash('The organization profile has been successfully updated.')
-        redirect(self.organization.url()+'edit_profile')
-
-    @expose()
-    @require_post()
-    @validate(F.invite_user_form, error_handler=edit_profile)
-    def invite_user(self, **kw):
-        require_authenticated()
-        username = kw['username']
-        if self.organization.userPermissions(c.user) != 'admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect(self.organization.url())
-        user = M.User.query.get(username=kw['username'])
-        if not user:
-            flash(
-                '''The username "%s" doesn't belong to any user on the forge'''\
-                % username, "error")
-            redirect(self.organization.url() + 'edit_profile')
-
-        invitation = Membership.insert('member', kw['role'], 'invitation', 
-            self.organization._id, user._id)
-        if invitation:
-            flash(
-                'The user '+ username +' has been successfully invited to '+ \
-                'become a member of the organization.')
-        else:
-            flash(
-                username+' is already a member of the organization.', 'error')
-
-        redirect(self.organization.url()+'edit_profile')
+        redirect('%sadmin/organizationprofile' % o.url())
 
     @expose()
     @require_post()
     @validate(V.NullValidator(), error_handler=index)
-    def change_membership(self, **kw):
-        require_authenticated()
-        
+    def change_membership(self, **kw):        
         membershipid = kw['membershipid']
         memb = Membership.getById(membershipid)
         status = kw['status']
-        new_permission = kw['permission']
-        
-        if memb:
-            user_permission = memb.organization.userPermissions(c.user)
-        if memb is None or (memb.member!=c.user and user_permission!='admin'):
+
+        return_url = '/organization'
+
+        if c.user != memb.member:
             flash(
                 "You don't have the permission to perform this action.", 
                 "error")
-            redirect('/organization')
-            return
-
-        if kw.get('requestfrom') == 'user':
-           return_url = '/organization'
-        else:
-           return_url = memb.organization.url() + 'edit_profile'
+            redirect(return_url)
 
         if status == 'remove':
             old_status = memb.status
@@ -252,117 +102,16 @@ class OrganizationProfileController(BaseController):
                 redirect(return_url)
                 return
 
-        if status == 'closed' and memb.membertype == 'admin':
-            if len(memb.organization.getAdministrators())==1:
-                flash(
-                    'This user is the only administrator of the organization, '+\
-                    'therefore, before closing this enrollment, another '+\
-                    'administrator has to be set.', 'error')
-                redirect(return_url)
-                return                
-
-        if status == 'closed':
-            new_permission = memb.membertype
-
         allowed=True
         if memb.status=='closed' and status!='closed':
             allowed=False
-        if memb.status=='request' and status=='active' and user_permission!='admin':
-            allowed=False
-        if memb.status=='invitation' and status=='active' and memb.member!=c.user:
+        if memb.status=='request' and status=='active':
             allowed=False
-        if new_permission != memb.membertype:
-            if user_permission!='admin' and memb.member != c.user:
-                allowed = False
-            admins = memb.organization.getAdministrators()
-            if new_permission == 'member' and len(admins)==1:
-                flash(
-                    'This user is the only administrator of the organization, '+\
-                    'therefore, before changing his permission level, another '+\
-                    'administrator has to be set.', 'error')
-                redirect(return_url)
-                return
 
         if allowed:
             memb.setStatus(status)
-            memb.membertype = new_permission
             memb.role = kw.get('role')
-            if new_permission=='member' and memb.member == c.user:
-                return_url = '/organization'
             flash('The membership has been successfully updated.')
         else:
             flash("You are not allowed to perform this action.")
         redirect(return_url)
-
-    @expose()
-    @require_post()
-    @validate(F.admission_request_form, error_handler=index)
-    def admission_request(self, role, **kw):
-        require_authenticated()
-        m=Membership.insert(
-            'member', role, 'request', self.organization._id, c.user._id)
-        flash('Request sent')
-        redirect('/organization/')
-
-    @expose()
-    @require_post()
-    @validate(F.request_collaboration_form, error_handler=edit_profile)
-    def send_collaboration_request(self, project_url_name, collaboration_type, **kw):
-        require_authenticated()
-        user_permission = self.organization.userPermissions(c.user)
-        if user_permission != 'admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect('/organization')
-            return
-        project=M.Project.query.get(shortname=project_url_name)
-        if not project:
-            flash(
-                "Invalid URL name. Please, insert the URL name of an existing "+\
-                "project.", "error")
-        else:
-            ProjectInvolvement.insert('request', collaboration_type, 
-                self.organization._id, project._id)
-            flash("Collaboration request successfully sent.")
-        redirect('%sedit_profile' % self.organization.url())
-            
-    @expose()
-    @require_post()
-    @validate(V.NullValidator(), error_handler=edit_profile)
-    def update_collaboration_status(self, collaborationid, collaborationtype, status, **kw):
-        require_authenticated()
-
-        coll = ProjectInvolvement.getById(collaborationid)
-        user_permission = coll.organization.userPermissions(c.user)
-        if user_permission != 'admin':
-            flash(
-                "You don't have the permission to perform this action.", 
-                "error")
-            redirect('/organization')
-            return
-
-        allowed = True
-        if coll.status != status:
-            if coll.status=='invitation' and status not in ['active','remove']:
-                allowed=False
-            elif coll.status=='closed':
-                allowed=False
-            elif coll.status=='active' and status!='closed':
-                allowed=False
-            elif coll.status=='request' and status !='remove':
-                allowed=False
-
-        if allowed:
-            if status=='closed':
-                collaborationtype=coll.collaborationtype
-
-            if status=='remove':
-                ProjectInvolvement.delete(coll._id)
-            else:
-                coll.collaborationtype=collaborationtype
-                coll.setStatus(status)
-            flash('The information about this collaboration has been updated')
-        else:
-            flash("You are not allowed to perform this action", "error")
-        redirect('%sedit_profile' % coll.organization.url())

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/model/organization.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/model/organization.py b/ForgeOrganization/forgeorganization/organization/model/organization.py
index 104f198..907f07a 100644
--- a/ForgeOrganization/forgeorganization/organization/model/organization.py
+++ b/ForgeOrganization/forgeorganization/organization/model/organization.py
@@ -49,10 +49,14 @@ class Organization(MappedClass):
     project_involvements=RelationProperty('ProjectInvolvement')
 
     def url(self):
-        return '/organization/' + self.shortname.replace('_', '-') + '/'
+        return ('/o/' + self.shortname.replace('_', '-') + '/').encode('ascii','ignore')
+
+    def project(self):
+        return M.Project.query.get(
+            shortname='o/'+self.shortname.replace('_', '-'))
 
     @classmethod
-    def register(cls, shortname, fullname, orgtype):
+    def register(cls, shortname, fullname, orgtype, user):
         o=cls.query.get(shortname=shortname)
         if o is not None: return None
         try:
@@ -64,7 +68,9 @@ class Organization(MappedClass):
         except pymongo.errors.DuplicateKeyError:
             session(o).expunge(o)
             return None
-
+        if o is not None:
+            n = M.Neighborhood.query.get(name='Organizations')
+            n.register_project('o/'+shortname, user=user, user_project=False)
         return o
 
     @classmethod
@@ -97,12 +103,6 @@ class Organization(MappedClass):
         if wfid in self.workfields:
             del self.workfields[self.workfields.index(wfid)]
 
-    def userPermissions(self, user):
-        for rel in self.memberships: 
-            if rel.member_id == user._id and rel.status=='active': 
-                return rel.membertype
-        return None
-
     def getActiveCooperations(self):
         return [c for c in self.project_involvements if c.status=='active' and
             c.collaborationtype == 'cooperation']
@@ -119,10 +119,6 @@ class Organization(MappedClass):
         return [c for c in self.project_involvements if c.status=='closed' and 
             c.collaborationtype == 'participation']
 
-    def getAdministrators(self):
-        return [m for m in self.memberships 
-            if m.membertype=='admin' and m.status =='active']
-
     def getEnrolledUsers(self):
         return [m for m in self.memberships if m.status=='active']
 
@@ -160,7 +156,6 @@ class Membership(MappedClass):
         name='organization_membership'
 
     _id=FieldProperty(S.ObjectId)
-    membertype=FieldProperty(S.OneOf('admin', 'member'))
     status=FieldProperty(S.OneOf('active', 'closed', 'invitation', 'request'))
     role=FieldProperty(str)
     organization_id=ForeignIdProperty('Organization')
@@ -172,7 +167,7 @@ class Membership(MappedClass):
     member = RelationProperty('User')
 
     @classmethod
-    def insert(cls, membertype, role, status, organization_id, member_id):
+    def insert(cls, role, status, organization_id, member_id):
         m = cls.query.find(dict(organization_id=organization_id, member_id=member_id))
         for el in m:
             if el.status!='closed':
@@ -181,7 +176,6 @@ class Membership(MappedClass):
             m = cls(
                 organization_id=organization_id, 
                 member_id=member_id,
-                membertype=membertype, 
                 role=role,
                 startdate=None,
                 status=status)

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html b/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html
deleted file mode 100644
index df90567..0000000
--- a/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html
+++ /dev/null
@@ -1,118 +0,0 @@
-{% set hide_left_bar = True %}
-{% extends g.theme.master %}
-
-{% block title %}Change organization data{% endblock %}
-
-{% block header %}Change organization data{% endblock %}
-
-{% block content %}
-
-{% if permissions == 'admin' %}
-
-  <ul><li><a href="{{organization.url()}}">Click here</a> to check your public profile.</ul>
-  <div class="grid-20">
-    <h2>Data to be included in {{organization.fullname}}'s profile</h2>
-    {{forms.update_profile.display(organization=organization, action=organization.url()+'change_data') }}
-  </div>
-
-  <div class="grid-20" style="clear:both;">
-    <h2>Work Fields</h2>
-    {% if organization.workfields %}
-      <table>
-        <tr>
-          <thead>
-            <th>Work field</th>
-            <th>Description</th>
-            <th>Actions</th>
-          </thead>
-        </tr>
-        {% for wf in organization.getWorkfields() %}
-          {{forms.remove_work_field.display(workfield=wf, action=organization.url()+'remove_work_field')}} 
-        {%endfor%}
-      </table>
-    {% else %}
-      <p>At the moment, there are no working fields set for this organization.</p>
-    {% endif %}
-    <h3>Add a new work field</h3>
-    <div class="grid-20" style="margin:0;">
-      {{forms.add_work_field.display(organization=organization, action=organization.url()+'add_work_field') }}
-    </div>
-  </div>
-
-  <div class="grid-20">
-    <h2>Members</h2>
-
-    {% if members %}
-      <table>
-        <thead>
-          <tr>
-            <th>Name</th>
-            <th>Permission level</th>
-            <th>Role</th>
-            <th>Status</th>
-            <th>Actions</th>
-          </tr>
-        </thead>
-        <tbody>
-          {% for membership in members %}
-            <tr>
-              {{forms.new_change_membership_from_organization().display(
-                  membership=membership,
-                  action=membership.organization.url()+'change_membership')}}
-            </tr>
-          {% endfor %}
-        </tbody>
-      </table>
-    {% else %}
-      <p>This organization doesn't have any enrolled member.</p>
-    {% endif %}
-    <h3>Add a new user</h3>
-    <p>
-      You can add a member of your organization to the above list by filling the following form with his or her 
-      username and the user's role within the organization.
-    </p>
-    {{forms.invite_user_form.display(action=organization.url()+'invite_user')}}
-
-  </div>
-
-  <div class="grid-20">
-    <h2>Collaborations</h2>
-
-    {% if collaborations %}
-      <h3>Edit existing collaborations</h3>
-      <table>
-        <thead>
-          <tr>
-            <th>Project</th>
-            <th>Collaboration type</th>
-            <th>Status</th>
-            <th>Actions</th>
-          </tr>
-        </thead>
-        <tbody>
-          {% for org in collaborations %}
-            <tr>
-              {{forms.new_change_collaboration_status().display(
-                    collaboration=org,
-                    action=org.organization.url()+'update_collaboration_status')}}
-            </tr>
-          {% endfor %}
-        </tbody>
-      </table>
-    {% else %}
-      <p>At the moment, this organization doesn't collaborate in any project.</p>
-    {% endif %}
-
-    <h3>Add a new collaboration</h3>
-    <p>
-      If you want to include a new collaboration in your profile, you can look for the project and send an admission request.
-      Otherwise, you can add it using the following form.
-    </p>
-    {{forms.request_collaboration_form.display(action=organization.url()+'send_collaboration_request')}}
-  </div>
-
-{% else %}
-  <div class="grid-20">You don't have the permissions to edit the profile of this organization.</div>
-{% endif %}
-
-{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html b/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html
deleted file mode 100644
index c825113..0000000
--- a/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html
+++ /dev/null
@@ -1,185 +0,0 @@
-{% set hide_left_bar = True %}
-{% extends g.theme.master %}
-{% block title %}Organization profile{% endblock %}
-{% block header %}Organization profile{% endblock %}
-
-{% block content %}
-
-  {% if not organization %}
-    <div class="grid-20">
-      This organization doesn't exists.
-    </div>
-  {% else %}
-    {% if is_admin %}
-      <ul><li><a href="{{organization.url()+'edit_profile'}}">Click here</a> to update this profile</li></ul>
-    {% endif %}
-    <h2>{{organization.fullname}} – General data</h2>
-
-    <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-      <label class="grid-4">Organization Type:</label>
-      <label class="grid-14">{{organization.organization_type}}</label>
-    </div>
-    {% if organization.description %}
-      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-        <label class="grid-4">Description:</label>
-        <label class="grid-14">{{organization.description}}</label>
-      </div>
-    {% endif %}
-    {% if organization.dimension and organization.dimension != 'Unknown' %}
-      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-        <label class="grid-4">Dimension:</label>
-        <label class="grid-14">
-          {% if organization.dimension == 'Small' %}Small – No more than 50 members{% endif %}
-          {% if organization.dimension == 'Medium' %}Medium – Between 51 and 250 members{% endif %}
-          {% if organization.dimension == 'Large' %}Big – More than 250 members{% endif %}
-        </label>
-      </div>
-    {% endif %}
-    {% if organization.headquarters %}
-      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-        <label class="grid-4">Headquarters:</label>
-        <label class="grid-14">{{organization.headquarters}}</label>
-      </div>
-    {% endif %}
-    {% if organization.website %}
-      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-        <label class="grid-4">Website:</label>
-        <label class="grid-14"><a href="{{organization.website}}">{{organization.website}}</a></label>
-      </div>
-    {% endif %}
-    {% if organization.getWorkfields() %}
-      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
-        <label class="grid-4">Workfields:</label>
-        <div class="grid-14">
-          <ul>
-            {% for wf in organization.getWorkfields() %}
-              <li>{{wf.name}} – {{wf.description}}</li>
-            {% endfor %}
-          </ul>
-        </div>
-      </div>
-    {% endif %}
-
-    <h2 style="clear:both;">Members</h2>
-    <div class="grid-20">
-      {% if members %}
-        <h3>Currently enrolled members</h3>
-        <table>
-          <thead>
-            <tr>
-              <th>Name</th>
-              <th>Role</th>
-              <th>Admission date on the forge</th>
-            </tr>
-          </thead>
-          <tbody>
-            {% for member in members -%}
-              <tr>
-                <td><a href="{{member.member.url()}}">{{member.member.display_name}}</a></td>
-                <td>{{member.role}}</td>
-                <td>{{member.startdate.strftime("%d %B %Y")}}</td>
-              </tr>
-            {% endfor %}
-          </tbody>
-        </table>
-      {% else %}
-        <p>Currently, this organization doesn't have any member.</p>
-      {% endif %}
-    </div>
-
-    <div class="grid-20">
-      {% if past_members %}
-        <h3>Past members of the organization</h3>
-        <table>
-          <thead>
-            <tr>
-              <th>Name</th>
-              <th>Role</th>
-              <th>Admission date on the forge</th>
-              <th>Closing membership date</th>
-            </tr>
-          </thead>
-          <tbody>
-            {% for member in past_members -%}
-              <tr>
-                <td><a href="{{member.member.url()}}">{{member.member.display_name}}</a></td>
-                <td>{{member.role}}</td>
-                <td>{{member.startdate.strftime("%d %B %Y")}}</td>
-                <td>{{member.closeddate.strftime("%d %B %Y")}}</td>
-              </tr>
-            {% endfor %}
-          </tbody>
-        </table>
-      {% endif %}
-    </div>
-
-    {% if not is_member %}
-      <div class="grid-20" style="clear:both;">
-        <h3>Are you a member of this organization?</h3>
-        <p>
-          If you are a member of this organization, you can send a request to appear in the list above. Before being admitted
-          to the organization, an administrator of the organization profile has to confirm your enrollment.
-        </p>
-        <div class="grid-20" style="margin:0;clear:both;">
-          {{forms.admission_request_form.display(action=organization.url()+'admission_request')}}
-        </div>
-      </div>
-    {% endif %}
-  
-    <h2 style="clear:both;">Projects and collaborations</h2>
-    {%if active_collaborations %}
-      <div class="grid-20">
-        <h3>Active collaborations</h3>
-      </div>
-      <div class="grid-20">
-        <table>
-          <thead>
-            <th>Project</th>
-            <th>Collaboration type</th>
-            <th>Start date</th>
-          </thead>
-          <tbody>
-            {% for collaboration in active_collaborations %}
-              <tr>
-                <td><a href="{{collaboration.project.url()}}">{{collaboration.project.name}}</a></td>
-                <td>{{collaboration.collaborationtype.capitalize()}}</td>
-                <td>{{collaboration.startdate.strftime("%d %B %Y")}}</td>
-              </tr>
-            {% endfor %}
-          </tbody>
-        </table>
-      </div>
-    {% endif %}
-
-    {%if closed_collaborations %}
-      <div class="grid-20">
-        <h3>Past projects collaborations</h3>
-      </div>
-      <div class="grid-20">
-        <table>
-          <thead>
-            <th>Project</th>
-            <th>Collaboration type</th>
-            <th>Start date</th>
-            <th>End date</th>
-          </thead>
-          <tbody>
-            {% for collaboration in closed_collaborations %}
-              <tr>
-                <td><a href="{{collaboration.project.url()}}">{{collaboration.project.name}}</a></td>
-                <td>{{collaboration.collaborationtype.capitalize()}}</td>
-                <td>{{collaboration.startdate.strftime("%d %B %Y")}}</td>
-                <td>{{collaboration.closeddate.strftime("%d %B %Y")}}</td>
-              </tr>
-            {% endfor %}
-          </tbody>
-        </table>
-      </div>
-    {% endif %}
-
-    {% if not (closed_collaborations or active_collaborations) %}
-      <div class="grid-18"><p>This organization has never collaborated to any project.</p></div>
-    {% endif %}
-
-  {% endif %}
-{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/templates/user_memberships.html
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/templates/user_memberships.html b/ForgeOrganization/forgeorganization/organization/templates/user_memberships.html
index 649b637..f130cea 100644
--- a/ForgeOrganization/forgeorganization/organization/templates/user_memberships.html
+++ b/ForgeOrganization/forgeorganization/organization/templates/user_memberships.html
@@ -12,7 +12,6 @@
           <tr>
             <th>Name</th>
             <th>Organization type</th>
-            <th>Permission level</th>
             <th>Role</th>
             <th>Status</th>
             <th>Actions</th>
@@ -22,7 +21,7 @@
           {% for membership in memberships %}
             {{forms.new_change_membership_from_user_form().display(
                   membership=membership,
-                  action=membership.organization.url()+'change_membership')}}
+                  action='organization/change_membership')}}
           {% endfor %}
         </tbody>
       </table>

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization/widgets/forms.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization/widgets/forms.py b/ForgeOrganization/forgeorganization/organization/widgets/forms.py
index 91cb3d1..f0403e1 100644
--- a/ForgeOrganization/forgeorganization/organization/widgets/forms.py
+++ b/ForgeOrganization/forgeorganization/organization/widgets/forms.py
@@ -1,6 +1,6 @@
 import logging
 import warnings
-from pylons import g
+from pylons import g, c
 from allura.lib import validators as V
 from allura.lib import helpers as h
 from allura.lib import plugin
@@ -206,9 +206,9 @@ class ChangeMembershipFromUser(ForgeForm):
         m = kw.get('membership')
         org = m.organization
 
-        orgnamefield = '<a href="%s">%s</a>' % (org.url(), org.fullname)
-        if m.membertype == 'admin':
-            orgnamefield+=' (<a href="%sedit_profile">edit</a>)'%org.url()
+        orgnamefield = '<a href="%s">%s</a>' % (org.url()+"organizationprofile", org.fullname)
+        if c.user.username in m.organization.project().admins():
+            orgnamefield+=' (<a href="%sadmin/organizationprofile">edit</a>)'%org.url()
         if m.status == 'active':
             statusoptions = [
                 ew.Option(py_value='active',label='Active',selected=True),
@@ -231,23 +231,6 @@ class ChangeMembershipFromUser(ForgeForm):
                 ew.Option(
                     py_value='remove',label='Remove request',selected=False)]
  
-        if m.membertype=='admin':
-            permission = ew.SingleSelectField(
-                name='permission',
-                show_errors=False,
-                options = [
-                    ew.Option(
-                        py_value='admin',label='Admin',selected=True),
-                    ew.Option(
-                        py_value='member',label='Member',selected=False)])
-            additional_hidden = []
-        else:
-            permission = ew.HTMLField(
-                text=m.membertype.capitalize(), show_errors=False)
-            additional_hidden = [ew.HiddenField(
-                name="permission",
-                show_errors=False,
-                attrs={'value':m.membertype})]
         self.fields = [
             ew.RowField(
                 show_errors=False,
@@ -260,7 +243,7 @@ class ChangeMembershipFromUser(ForgeForm):
                         name="requestfrom",
                         attrs={'value':'user'},
                         show_errors=False)
-                ] + additional_hidden,
+                ],
                 fields=[
                     ew.HTMLField(
                         text=orgnamefield,
@@ -268,7 +251,6 @@ class ChangeMembershipFromUser(ForgeForm):
                     ew.HTMLField(
                         text=org.organization_type,
                         show_errors=False),
-                    permission,
                     ew.TextField(
                         name='role',
                         attrs=dict(value=m.role),
@@ -332,18 +314,6 @@ class ChangeMembershipFromOrganization(ForgeForm):
                         text='<a href="%s">%s</a>' % (
                             user.url(), user.display_name),
                         show_errors=False),
-                    ew.SingleSelectField(
-                        name='permission',
-                        show_errors=False,
-                        options = [
-                            ew.Option(
-                                py_value='admin',
-                                label='Admin',
-                                selected=m.membertype=='admin'),
-                            ew.Option(
-                                py_value='member',
-                                label='Member',
-                                selected=m.membertype=='member')]),
                     ew.TextField(
                         name='role',
                         attrs=dict(value=m.role),
@@ -431,5 +401,3 @@ class ChangeCollaborationStatusForm(ForgeForm):
                         attrs={'value':'Save'},
                         show_errors=False)])]
         return super(ChangeCollaborationStatusForm, self).display(**kw)
-
-

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization_profile/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization_profile/__init__.py b/ForgeOrganization/forgeorganization/organization_profile/__init__.py
new file mode 100644
index 0000000..0eae989
--- /dev/null
+++ b/ForgeOrganization/forgeorganization/organization_profile/__init__.py
@@ -0,0 +1 @@
+from .organization_main import OrganizationProfileApp

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization_profile/organization_main.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization_profile/organization_main.py b/ForgeOrganization/forgeorganization/organization_profile/organization_main.py
new file mode 100644
index 0000000..a74fddb
--- /dev/null
+++ b/ForgeOrganization/forgeorganization/organization_profile/organization_main.py
@@ -0,0 +1,277 @@
+import logging
+from pprint import pformat
+
+import pkg_resources
+from pylons import tmpl_context as c, app_globals as g
+from pylons import request
+from formencode import validators
+from tg import expose, redirect, validate, response, flash
+from webob import exc
+
+from allura import version
+from allura.app import Application, SitemapEntry
+from allura.lib import helpers as h
+from allura.lib.helpers import DateTimeConverter
+from allura.lib.security import require_access
+import allura.model as M
+from allura.model import User, Feed, ACE
+from allura.controllers import BaseController
+from allura.lib.decorators import require_post
+
+from forgeorganization.organization.model import Organization, WorkFields, Membership, ProjectInvolvement
+
+import forgeorganization.organization.widgets.forms as forms
+from allura.lib import validators as V
+from allura.lib.security import require_authenticated
+from allura.lib.decorators import require_post
+
+log = logging.getLogger(__name__)
+
+class Forms(object):
+    update_profile = forms.UpdateProfile()
+    add_work_field = forms.AddWorkField()
+    remove_work_field = forms.RemoveWorkField()
+    invite_user_form = forms.InviteUser()
+    admission_request_form = forms.RequestAdmissionForm()
+    request_collaboration_form = forms.RequestCollaborationForm()
+    def new_change_collaboration_status(self):
+        return forms.ChangeCollaborationStatusForm()
+    def new_change_membership_from_organization(self):
+        return forms.ChangeMembershipFromOrganization()
+
+F = Forms()
+
+class OrganizationProfileApp(Application):
+    __version__ = version.__version__
+    installable = False
+    icons={
+        24:'images/home_24.png',
+        32:'images/home_32.png',
+        48:'images/home_48.png'
+    }
+
+    def __init__(self, user, config):
+        Application.__init__(self, user, config)
+        self.root = OrganizationProfileController()
+        self.admin = OrganizationProfileAdminController()
+
+    def admin_menu(self):
+        links = [SitemapEntry(
+            'Edit',
+            '%sadmin/organizationprofile' % c.project.organization_project_of.url())]
+        return links
+
+    def install(self, project):
+        pr = c.user.project_role()
+        if pr:
+            self.config.acl = [
+                ACE.allow(pr._id, perm)
+                for perm in self.permissions ]
+
+    def uninstall(self, project):
+        pass
+
+    @property
+    @h.exceptionless([], log)
+    def sitemap(self):
+        return []
+
+class OrganizationProfileController(BaseController):
+
+    @expose('jinja:forgeorganization:organization_profile/templates/organization_index.html')
+    def index(self, **kw):
+        organization = c.project.organization_project_of
+        if not organization:
+            raise exc.HTTPNotFound()
+        activecoll=[coll for coll in organization.project_involvements
+                    if coll.status=='active']
+        closedcoll=[p for p in organization.project_involvements 
+                    if p.status=='closed']
+        mlist=[m for m in organization.memberships if m.status=='active']
+        plist=[m for m in organization.memberships if m.status=='closed']
+        return dict(
+            forms = F,
+            ask_admission = (c.user not in [m.member for m in mlist]) and c.user != M.User.anonymous(),
+            workfields = WorkFields.query.find(),
+            organization=organization,
+            members = mlist,
+            past_members=plist,
+            active_collaborations=activecoll,
+            closed_collaborations=closedcoll)
+
+    @expose()
+    @require_post()
+    @validate(F.admission_request_form, error_handler=index)
+    def admission_request(self, role, **kw):
+        require_access(c.project, 'read')
+        m=Membership.insert(
+            role, 'request', c.project.organization_project_of._id, c.user._id)
+        flash('Request sent')
+        redirect(c.project.organization_project_of.url()+'organizationprofile')
+
+class OrganizationProfileAdminController(BaseController):
+    @expose('jinja:forgeorganization:organization_profile/templates/edit_profile.html')
+    def index(self, **kw):
+        require_access(c.project, 'admin')
+        
+        organization = c.project.organization_project_of
+        mlist=[m for m in organization.memberships if m.status!='closed']
+        clist=[el for el in organization.project_involvements 
+               if el.status!='closed']
+
+        return dict(
+            organization = organization,
+            members = mlist,
+            collaborations= clist,
+            forms = F)
+
+    @expose()
+    @require_post()
+    @validate(F.remove_work_field, error_handler=index)
+    def remove_work_field(self, **kw):
+        require_access(c.project, 'admin')
+        c.project.organization_project_of.removeWorkField(kw['workfield'])
+        flash('The organization profile has been successfully updated.')
+        redirect(c.project.organization_project_of.url()+'admin/organizationprofile')
+
+    @expose()
+    @require_post()
+    @validate(V.NullValidator(), error_handler=index)
+    def add_work_field(self, workfield, **kw):
+        require_access(c.project, 'admin')
+        workfield = WorkFields.getById(workfield)
+
+        if workfield is None:
+            flash("Invalid workfield. Select a valid value.", "error")
+            redirect(c.project.organization_project_of.url()+'admin/organizationprofile')
+        c.project.organization_project_of.addWorkField(workfield)
+        flash('The organization profile has been successfully updated.')
+        redirect(c.project.organization_project_of.url()+'admin/organizationprofile')
+
+    @expose()
+    @require_post()
+    @validate(F.invite_user_form, error_handler=index)
+    def invite_user(self, **kw):
+        require_access(c.project, 'admin')
+        username = kw['username']
+        user = M.User.query.get(username=kw['username'])
+        if not user:
+            flash(
+                '''The username "%s" doesn't belong to any user on the forge'''\
+                % username, "error")
+            redirect(c.project.organization_project_of.url() + 'admin/organizationprofile')
+
+        invitation = Membership.insert(kw['role'], 'invitation', 
+            c.project.organization_project_of._id, user._id)
+        if invitation:
+            flash(
+                'The user '+ username +' has been successfully invited to '+ \
+                'become a member of the organization.')
+        else:
+            flash(
+                username+' is already a member of the organization.', 'error')
+
+        redirect(c.project.organization_project_of.url()+'admin/organizationprofile')
+
+    @expose()
+    @require_post()
+    @validate(V.NullValidator(), error_handler=index)
+    def change_membership(self, **kw):        
+        membershipid = kw['membershipid']
+        memb = Membership.getById(membershipid)
+        status = kw['status']
+
+        return_url = memb.organization.url() + 'admin/organizationprofile'
+
+        if status == 'remove':
+            old_status = memb.status
+            if memb.status in ['invitation', 'request']:
+                Membership.delete(memb)
+                flash('The pending %s has been removed.' % old_status)
+                redirect(return_url)
+                return
+            else:
+                flash(
+                    "You don't have the permission to perform this action.", 
+                    "error")
+                redirect(return_url)
+                return
+
+        allowed=True
+        if memb.status=='closed' and status!='closed':
+            allowed=False
+        if memb.status=='invitation' and status=='active':
+            allowed=False
+
+        if allowed:
+            memb.setStatus(status)
+            memb.role = kw.get('role')
+            flash('The membership has been successfully updated.')
+        else:
+            flash("You are not allowed to perform this action.")
+        redirect(return_url)
+
+    @expose()
+    @require_post()
+    @validate(F.request_collaboration_form, error_handler=index)
+    def send_collaboration_request(self, project_url_name, collaboration_type, **kw):
+        require_access(c.project, 'admin')
+        project=M.Project.query.get(shortname=project_url_name)
+        if not project:
+            flash(
+                "Invalid URL name. Please, insert the URL name of an existing "+\
+                "project.", "error")
+        else:
+            ProjectInvolvement.insert('request', collaboration_type, 
+                c.project.organization_project_of._id, project._id)
+            flash("Collaboration request successfully sent.")
+        redirect('%sadmin/organizationprofile' % c.project.organization_project_of.url())
+            
+    @expose()
+    @require_post()
+    @validate(V.NullValidator(), error_handler=index)
+    def update_collaboration_status(self, collaborationid, collaborationtype, status, **kw):
+        require_access(c.project, 'admin')
+
+        coll = ProjectInvolvement.getById(collaborationid)
+
+        allowed = True
+        if coll.status != status:
+            if coll.status=='invitation' and status not in ['active','remove']:
+                allowed=False
+            elif coll.status=='closed':
+                allowed=False
+            elif coll.status=='active' and status!='closed':
+                allowed=False
+            elif coll.status=='request' and status !='remove':
+                allowed=False
+
+        if allowed:
+            if status=='closed':
+                collaborationtype=coll.collaborationtype
+
+            if status=='remove':
+                ProjectInvolvement.delete(coll._id)
+            else:
+                coll.collaborationtype=collaborationtype
+                coll.setStatus(status)
+            flash('The information about this collaboration has been updated')
+        else:
+            flash("You are not allowed to perform this action", "error")
+        redirect('%sadmin/organizationprofile' % coll.organization.url())
+
+    @expose()
+    @require_post()
+    @validate(F.update_profile, error_handler=index)
+    def change_data(self, **kw):
+        require_access(c.project, 'admin')
+
+        c.project.organization_project_of.organization_type = kw['organization_type']
+        c.project.organization_project_of.fullname = kw['fullname']
+        c.project.organization_project_of.description = kw['description']
+        c.project.organization_project_of.headquarters = kw['headquarters']
+        c.project.organization_project_of.dimension = kw['dimension']
+        c.project.organization_project_of.website = kw['website']
+
+        flash('The organization profile has been successfully updated.')
+        redirect(c.project.organization_project_of.url() + 'admin/organizationprofile')

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization_profile/templates/__init__.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization_profile/templates/__init__.py b/ForgeOrganization/forgeorganization/organization_profile/templates/__init__.py
new file mode 100644
index 0000000..e69de29

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html b/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
new file mode 100644
index 0000000..aca2a57
--- /dev/null
+++ b/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
@@ -0,0 +1,111 @@
+{% set hide_left_bar = True %}
+{% extends g.theme.master %}
+
+{% block title %}Change organization data{% endblock %}
+
+{% block header %}Change organization data{% endblock %}
+
+{% block content %}
+
+  <ul><li><a href="{{organization.url()}}organizationprofile">Click here</a> to check your public profile.</ul>
+  <div class="grid-20">
+    <h2>Data to be included in {{organization.fullname}}'s profile</h2>
+    {{forms.update_profile.display(organization=organization, action=organization.url()+'admin/organizationprofile/change_data') }}
+  </div>
+
+  <div class="grid-20" style="clear:both;">
+    <h2>Work Fields</h2>
+    {% if organization.workfields %}
+      <table>
+        <tr>
+          <thead>
+            <th>Work field</th>
+            <th>Description</th>
+            <th>Actions</th>
+          </thead>
+        </tr>
+        {% for wf in organization.getWorkfields() %}
+          {{forms.remove_work_field.display(workfield=wf, action=organization.url()+'admin/organizationprofile/remove_work_field')}} 
+        {%endfor%}
+      </table>
+    {% else %}
+      <p>At the moment, there are no working fields set for this organization.</p>
+    {% endif %}
+    <h3>Add a new work field</h3>
+    <div class="grid-20" style="margin:0;">
+      {{forms.add_work_field.display(organization=organization, action=organization.url()+'admin/organizationprofile/add_work_field') }}
+    </div>
+  </div>
+
+  <div class="grid-20">
+    <h2>Members</h2>
+
+    {% if members %}
+      <table>
+        <thead>
+          <tr>
+            <th>Name</th>
+            <th>Role</th>
+            <th>Status</th>
+            <th>Actions</th>
+          </tr>
+        </thead>
+        <tbody>
+          {% for membership in members %}
+            <tr>
+              {{forms.new_change_membership_from_organization().display(
+                  membership=membership,
+                  action=membership.organization.url()+'admin/organizationprofile/change_membership')}}
+            </tr>
+          {% endfor %}
+        </tbody>
+      </table>
+    {% else %}
+      <p>This organization doesn't have any enrolled member.</p>
+    {% endif %}
+    <h3>Add a new user</h3>
+    <p>
+      You can add a member of your organization to the above list by filling the following form with his or her 
+      username and the user's role within the organization.
+    </p>
+    {{forms.invite_user_form.display(action=organization.url()+'admin/organizationprofile/invite_user')}}
+
+  </div>
+
+  <div class="grid-20">
+    <h2>Collaborations</h2>
+
+    {% if collaborations %}
+      <h3>Edit existing collaborations</h3>
+      <table>
+        <thead>
+          <tr>
+            <th>Project</th>
+            <th>Collaboration type</th>
+            <th>Status</th>
+            <th>Actions</th>
+          </tr>
+        </thead>
+        <tbody>
+          {% for org in collaborations %}
+            <tr>
+              {{forms.new_change_collaboration_status().display(
+                    collaboration=org,
+                    action=organization.url()+'admin/organizationprofile/update_collaboration_status')}}
+            </tr>
+          {% endfor %}
+        </tbody>
+      </table>
+    {% else %}
+      <p>At the moment, this organization doesn't collaborate in any project.</p>
+    {% endif %}
+
+    <h3>Add a new collaboration</h3>
+    <p>
+      If you want to include a new collaboration in your profile, you can look for the project and send an admission request.
+      Otherwise, you can add it using the following form.
+    </p>
+    {{forms.request_collaboration_form.display(action=organization.url()+'admin/organizationprofile/send_collaboration_request')}}
+  </div>
+
+{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html b/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
new file mode 100644
index 0000000..3c04a96
--- /dev/null
+++ b/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
@@ -0,0 +1,206 @@
+{% set hide_left_bar = True %}
+{% extends g.theme.master %}
+
+{% block title %}{{organization.fullname}} / Profile{% endblock %}
+
+{% block header %}{{ organization.fullname }}'s profile{% endblock %}
+
+{% block extra_css %}
+  <link rel="stylesheet" type="text/css"
+        href="{{g.app_static('css/user_profile.css')}}"/>
+{% endblock %}
+
+{% block head %}
+  <link rel="alternate" type="application/rss+xml" title="RSS" href="feed.rss">
+  <link rel="alternate" type="application/atom+xml" title="Atom" href="feed.atom">
+{% endblock %}
+
+{% block actions %}
+  <a href="{{c.app.url}}feed.rss" title="Follow"><b data-icon="{{g.icons['feed'].char}}" class="ico {{g.icons['feed'].css}}"></b></a>
+{% endblock %}
+
+{% block content %}
+
+  {% if not organization %}
+
+    <div class="grid-20">
+      This organization doesn't exists.
+    </div>
+
+  {% else %}
+
+    <h2>{{organization.fullname}} – General data</h2>
+    <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+      <label class="grid-4">Organization Type:</label>
+      <label class="grid-14">{{organization.organization_type}}</label>
+    </div>
+
+    {% if organization.description %}
+      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+        <label class="grid-4">Description:</label>
+        <label class="grid-14">{{organization.description}}</label>
+      </div>
+    {% endif %}
+
+    {% if organization.dimension and organization.dimension != 'Unknown' %}
+      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+        <label class="grid-4">Dimension:</label>
+        <label class="grid-14">
+          {% if organization.dimension == 'Small' %}Small – No more than 50 members{% endif %}
+          {% if organization.dimension == 'Medium' %}Medium – Between 51 and 250 members{% endif %}
+          {% if organization.dimension == 'Large' %}Big – More than 250 members{% endif %}
+        </label>
+      </div>
+    {% endif %}
+
+    {% if organization.headquarters %}
+      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+        <label class="grid-4">Headquarters:</label>
+        <label class="grid-14">{{organization.headquarters}}</label>
+      </div>
+    {% endif %}
+
+    {% if organization.website %}
+      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+        <label class="grid-4">Website:</label>
+        <label class="grid-14"><a href="{{organization.website}}">{{organization.website}}</a></label>
+      </div>
+    {% endif %}
+
+    {% if organization.getWorkfields() %}
+      <div class="grid-20" style="margin-top:5px;margin-left:5px;">
+        <label class="grid-4">Workfields:</label>
+        <div class="grid-14">
+          <ul>
+            {% for wf in organization.getWorkfields() %}
+              <li>{{wf.name}} – {{wf.description}}</li>
+            {% endfor %}
+          </ul>
+        </div>
+      </div>
+    {% endif %}
+
+    <h2 style="clear:both;">Members</h2>
+    <div class="grid-20">
+      {% if members %}
+        <h3>Currently enrolled members</h3>
+        <table>
+          <thead>
+            <tr>
+              <th>Name</th>
+              <th>Role</th>
+              <th>Admission date on the forge</th>
+            </tr>
+          </thead>
+          <tbody>
+            {% for member in members -%}
+              <tr>
+                <td><a href="{{member.member.url()}}">{{member.member.display_name}}</a></td>
+                <td>{{member.role}}</td>
+                <td>{{member.startdate.strftime("%d %B %Y")}}</td>
+              </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+      {% else %}
+        <p>Currently, this organization doesn't have any member.</p>
+      {% endif %}
+    </div>
+
+    <div class="grid-20">
+      {% if past_members %}
+        <h3>Past members of the organization</h3>
+        <table>
+          <thead>
+            <tr>
+              <th>Name</th>
+              <th>Role</th>
+              <th>Admission date on the forge</th>
+              <th>Closing membership date</th>
+            </tr>
+          </thead>
+          <tbody>
+            {% for member in past_members -%}
+              <tr>
+                <td><a href="{{member.member.url()}}">{{member.member.display_name}}</a></td>
+                <td>{{member.role}}</td>
+                <td>{{member.startdate.strftime("%d %B %Y")}}</td>
+                <td>{{member.closeddate.strftime("%d %B %Y")}}</td>
+              </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+      {% endif %}
+    </div>
+  
+    {% if ask_admission %}
+      <div class="grid-20" style="clear:both;">
+        <h3>Are you a member of this organization?</h3>
+        <p>
+          If you are a member of this organization, you can send a request to appear in the list above. Before being admitted
+          to the organization, an administrator of the organization profile has to confirm your enrollment.
+        </p>
+        <div class="grid-20" style="margin:0;clear:both;">
+          {{forms.admission_request_form.display(action=organization.url()+'organizationprofile/admission_request')}}
+        </div>
+      </div>
+    {% endif %}
+
+    <h2 style="clear:both;">Projects and collaborations</h2>
+    {%if active_collaborations %}
+      <div class="grid-20">
+        <h3>Active collaborations</h3>
+      </div>
+      <div class="grid-20">
+        <table>
+          <thead>
+            <th>Project</th>
+            <th>Collaboration type</th>
+            <th>Start date</th>
+          </thead>
+          <tbody>
+            {% for collaboration in active_collaborations %}
+              <tr>
+                <td><a href="{{collaboration.project.url()}}">{{collaboration.project.name}}</a></td>
+                <td>{{collaboration.collaborationtype.capitalize()}}</td>
+                <td>{{collaboration.startdate.strftime("%d %B %Y")}}</td>
+              </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+      </div>
+    {% endif %}
+
+    {%if closed_collaborations %}
+      <div class="grid-20">
+        <h3>Past projects collaborations</h3>
+      </div>
+      <div class="grid-20">
+        <table>
+          <thead>
+            <th>Project</th>
+            <th>Collaboration type</th>
+            <th>Start date</th>
+            <th>End date</th>
+          </thead>
+          <tbody>
+            {% for collaboration in closed_collaborations %}
+              <tr>
+                <td><a href="{{collaboration.project.url()}}">{{collaboration.project.name}}</a></td>
+                <td>{{collaboration.collaborationtype.capitalize()}}</td>
+                <td>{{collaboration.startdate.strftime("%d %B %Y")}}</td>
+                <td>{{collaboration.closeddate.strftime("%d %B %Y")}}</td>
+              </tr>
+            {% endfor %}
+          </tbody>
+        </table>
+      </div>
+    {% endif %}
+
+    {% if not (closed_collaborations or active_collaborations) %}
+      <div class="grid-18"><p>This organization has never collaborated to any project.</p></div>
+    {% endif %}
+
+  {% endif %}
+  
+{% endblock %}

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/tests/test_organizations.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/tests/test_organizations.py b/ForgeOrganization/forgeorganization/tests/test_organizations.py
index 96d7d02..32bc944 100644
--- a/ForgeOrganization/forgeorganization/tests/test_organizations.py
+++ b/ForgeOrganization/forgeorganization/tests/test_organizations.py
@@ -40,7 +40,7 @@ class TestOrganization(TestController):
 
         #Add a new user
         self.user2 = User.by_username('test-user-2')
-        r = self.app.post('/organization/%s/invite_user' % self.name,
+        r = self.app.post((self.org.url()+'admin/organizationprofile/invite_user'),
             params=dict(
                 username = self.user2.username,
                 role = 'Software Engineer'),
@@ -48,10 +48,9 @@ class TestOrganization(TestController):
         m = OM.Membership.query.get(
             member_id=self.user2._id, 
             organization_id=self.org._id)
-        r = self.app.post('/organization/%s/change_membership' % self.name,
+        r = self.app.post('/organization/change_membership',
             params=dict(
                 status = 'active',
-                permission = 'member',
                 membershipid = str(m._id),
                 requestfrom = 'user',
                 role = 'Software Engineer'),
@@ -73,7 +72,7 @@ class TestOrganizationGeneral(TestOrganization):
         m = OM.Membership.query.get(
             member_id=c.user._id,
             organization_id=self.org._id)
-        assert self.org.userPermissions(c.user) == 'admin'
+        assert c.user.username in org.project().admins()
         assert m.status == 'active'
         assert m.role == self.role
 
@@ -88,7 +87,7 @@ class TestOrganizationGeneral(TestOrganization):
         website = 'http://www.example.com'
 
         #Update the profile of the organization
-        r = self.app.post('/organization/%s/change_data' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/change_data' % self.org.url(),
             params = dict(
                 fullname = fullname,
                 organization_type = organization_type,
@@ -100,7 +99,7 @@ class TestOrganizationGeneral(TestOrganization):
 
         ThreadLocalORMSession.flush_all()
 
-        r = self.app.get('/organization/%s/' % self.name)
+        r = self.app.get('%sorganizationprofile' % self.org.url())
         assert organization_type in r
         assert description in r
         assert headquarters in r
@@ -117,7 +116,7 @@ class TestOrganizationGeneral(TestOrganization):
         assert self.org.fullname == fullname
 
         #Try to provide invalid parameters
-        r = self.app.post('/organization/%s/change_data' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/change_data' % self.org.url(),
             params = dict(
                 fullname = 'a',
                 organization_type = 'Invalid type',
@@ -129,7 +128,7 @@ class TestOrganizationGeneral(TestOrganization):
 
         ThreadLocalORMSession.flush_all()
 
-        r = self.app.get('/organization/%s/' % self.name,
+        r = self.app.get('%sorganizationprofile' % self.org.url(),
             extra_environ=dict(username='test-user-1'))
 
         self.org = OM.Organization.query.get(_id=self.org._id)
@@ -140,21 +139,20 @@ class TestOrganizationGeneral(TestOrganization):
         assert self.org.website == website
         assert self.org.fullname == fullname
 
+
     @td.with_user_project('test-user-1')
     def test_workfield(self):
 
         wf = OM.WorkFields.query.get(name='Mobile apps')
         c.user = User.by_username('test-user-1')
 
-        r = self.app.get('/organization/%s/edit_profile' % self.name)
-
         #Add a workfield
-        r = self.app.post('/organization/%s/add_work_field' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/add_work_field' % self.org.url(),
             params = dict(
                 workfield = str(wf._id)),
             extra_environ=dict(username='test-user-1'))
 
-        r = self.app.get('/organization/%s/' % self.name)
+        r = self.app.get('%sorganizationprofile' % self.org.url())
         
         self.org = OM.Organization.query.get(_id=self.org._id)
         assert len(self.org.getWorkfields()) == 1
@@ -165,12 +163,12 @@ class TestOrganizationGeneral(TestOrganization):
         #Add a second workfield
         wf2 = OM.WorkFields.query.get(name='Web applications')
 
-        r = self.app.post('/organization/%s/add_work_field' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/add_work_field' % self.org.url(),
             params = dict(
                 workfield = str(wf2._id)),
             extra_environ=dict(username='test-user-1'))
 
-        r = self.app.get('/organization/%s/' % self.name)
+        r = self.app.get('%sorganizationprofile' % self.org.url())
         
         self.org = OM.Organization.query.get(_id=self.org._id)
         assert len(self.org.getWorkfields()) == 2
@@ -178,11 +176,11 @@ class TestOrganizationGeneral(TestOrganization):
         assert wf2.description in r
 
         #Remove a workfield
-        r = self.app.post('/organization/%s/remove_work_field' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/remove_work_field' % self.org.url(),
             params = {'workfieldid' : str(wf._id)},
             extra_environ=dict(username='test-user-1'))
 
-        r = self.app.get('/organization/%s/' % self.name)
+        r = self.app.get('%sorganizationprofile' % self.org.url())
         assert len(self.org.getWorkfields()) == 1
         assert self.org.getWorkfields()[0]._id == wf2._id
         assert wf.name not in r
@@ -191,42 +189,18 @@ class TestOrganizationGeneral(TestOrganization):
 class TestOrganizationMembership(TestOrganization):
 
     @td.with_user_project('test-user-1')
-    def test_invalid_close_membership(self):
-        m = OM.Membership.query.get(
-            member_id=c.user._id, 
-            organization_id=self.org._id)
-        
-        #Try to close the created membership
-        r = self.app.post('/organization/%s/change_membership' % self.name,
-            params=dict(
-                status = 'closed',
-                permission = 'admin',
-                membershipid = str(m._id),
-                requestfrom = 'user',
-                role = self.role),
-            extra_environ=dict(username='test-user-1'))
-
-        #Since there aren't other admins, check that nothing changed
-        m = OM.Membership.query.get(
-            member_id=c.user._id, 
-            organization_id=self.org._id)
-        assert self.org.userPermissions(c.user) == 'admin'
-        assert m.status == 'active'
-        assert m.role == self.role
-
-    @td.with_user_project('test-user-1')
     def test_invite_user(self):
         #Try to invite a new user
         user3 = User.by_username('test-admin')
         testrole = 'Software Engineer'
 
-        r = self.app.post('/organization/%s/invite_user' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/invite_user' % self.org.url(),
             params=dict(
                 username = user3.username,
                 role = testrole),
             extra_environ=dict(username='test-user-1'))
         
-        r = self.app.get('/organization/%s/edit_profile' % self.name,
+        r = self.app.get('%sadmin/organizationprofile' % self.org.url(),
             extra_environ=dict(username='test-user-1'))
         assert user3.display_name in r
 
@@ -237,12 +211,10 @@ class TestOrganizationMembership(TestOrganization):
         assert m.role == testrole
 
         #Accept invitation
-        r = self.app.post('/organization/%s/change_membership' % self.name,
+        r = self.app.post('/organization/change_membership',
             params=dict(
                 status = 'active',
-                permission = 'member',
                 membershipid = str(m._id),
-                requestfrom = 'user',
                 role = testrole),
             extra_environ=dict(username='test-admin'))
 
@@ -251,41 +223,22 @@ class TestOrganizationMembership(TestOrganization):
             organization_id=self.org._id)
         assert m.status == 'active'
         assert m.role == testrole
-        assert m.membertype == 'member'
-
+        
     @td.with_user_project('test-user-1')
     def test_change_permissions(self):
         m = OM.Membership.query.get(
             member_id=self.user2._id, 
             organization_id=self.org._id)
 
-        #Change permissions of the non-admin user
-        r = self.app.post('/organization/%s/change_membership' % self.name,
-            params=dict(
-                status = 'active',
-                permission = 'admin',
-                membershipid = str(m._id),
-                requestfrom = 'organization',
-                role = 'Software Engineer'),
-            extra_environ=dict(username='test-user-1'))
-
-        m = OM.Membership.query.get(
-            member_id=self.user2._id, 
-            organization_id=self.org._id)
-        assert m.status == 'active'
-        assert m.role == 'Software Engineer'
-        assert m.membertype == 'admin'
-
         #Close the involvement of test-user-1
         testuser1 = User.by_username('test-user-1')
         m = OM.Membership.query.get(
             member_id=testuser1._id, 
             organization_id=self.org._id)
 
-        r = self.app.post('/organization/%s/change_membership' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/change_membership' % self.org.url(),
             params=dict(
                 status = 'closed',
-                permission = 'admin',
                 membershipid = str(m._id),
                 requestfrom = 'user',
                 role = self.role),
@@ -294,23 +247,23 @@ class TestOrganizationMembership(TestOrganization):
         m = OM.Membership.query.get(
             member_id=c.user._id, 
             organization_id=self.org._id)
-        assert self.org.userPermissions(c.user) == 'admin'
         assert m.status == 'closed'
         assert m.role == self.role
 
 
     @td.with_user_project('test-admin')
     def test_send_request(self):
-        #Send an admission new user
+        #Send an admission request from a new user
         user3 = User.by_username('test-admin')
         testrole = 'Software Engineer'
 
-        r = self.app.post('/organization/%s/admission_request' % self.name,
+        r = self.app.post('%sorganizationprofile/admission_request' % self.org.url(),
             params=dict(
                 role = testrole),
             extra_environ=dict(username='test-admin'))
-        
-        r = self.app.get('/organization/%s/edit_profile' % self.name,
+
+        c.user = M.User.by_username('test-user-1')
+        r = self.app.get('%sadmin/organizationprofile' % self.org.url(),
             extra_environ=dict(username='test-user-1'))
         assert user3.display_name in r
 
@@ -320,26 +273,10 @@ class TestOrganizationMembership(TestOrganization):
         assert m.status == 'request'
         assert m.role == testrole
 
-        #Check that the user is not allowed to accept his own request
-        r = self.app.post('/organization/%s/change_membership' % self.name,
-            params=dict(
-                status = 'active',
-                permission = 'member',
-                membershipid = str(m._id),
-                requestfrom = 'user',
-                role = testrole),
-            extra_environ=dict(username='test-admin'))
-
-        m = OM.Membership.query.get(
-            member_id=user3._id, 
-            organization_id=self.org._id)
-        assert m.status == 'request'
-
         #Accept request
-        r = self.app.post('/organization/%s/change_membership' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/change_membership' % self.org.url(),
             params=dict(
                 status = 'active',
-                permission = 'member',
                 membershipid = str(m._id),
                 requestfrom = 'user',
                 role = testrole),
@@ -350,10 +287,8 @@ class TestOrganizationMembership(TestOrganization):
             organization_id=self.org._id)
         assert m.status == 'active'
         assert m.role == testrole
-        assert m.membertype == 'member'
-
-#check progetti
 
+#check projects
 class TestOrganizationProjects(TestOrganization):
 
     @td.with_user_project('test-admin')
@@ -425,7 +360,7 @@ class TestOrganizationProjects(TestOrganization):
         assert p.collaborationtype == 'cooperation'
 
         #As the admin of the organization, reject pending invitation
-        r = self.app.post('/organization/%s/update_collaboration_status' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/update_collaboration_status' % self.org.url(),
             params=dict(
                 collaborationid = str(p._id),
                 collaborationtype = 'cooperation',
@@ -438,7 +373,7 @@ class TestOrganizationProjects(TestOrganization):
         p = send_invitation(self)
 
         #As the admin of the organization, accept pending invitation
-        r = self.app.post('/organization/%s/update_collaboration_status' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/update_collaboration_status' % self.org.url(),
             params=dict(
                 collaborationid = str(p._id),
                 collaborationtype = 'cooperation',
@@ -449,7 +384,7 @@ class TestOrganizationProjects(TestOrganization):
         assert p.collaborationtype == 'cooperation'
 
         #As the admin of the organization, close the collaboration
-        r = self.app.post('/organization/%s/update_collaboration_status' % self.name,
+        r = self.app.post('%sadmin/organizationprofile/update_collaboration_status' % self.org.url(),
             params=dict(
                 collaborationid = str(p._id),
                 collaborationtype = 'cooperation',

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/forgeorganization/tool/controller/organizationtool.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/forgeorganization/tool/controller/organizationtool.py b/ForgeOrganization/forgeorganization/tool/controller/organizationtool.py
index 078ed72..af64a81 100644
--- a/ForgeOrganization/forgeorganization/tool/controller/organizationtool.py
+++ b/ForgeOrganization/forgeorganization/tool/controller/organizationtool.py
@@ -33,8 +33,8 @@ class OrganizationToolController(BaseController):
                       if el.collaborationtype=='cooperation']
         participations=[el for el in c.project.organizations
                         if el.collaborationtype=='participation']
-        user_organizations=[o.organization for o in c.user.memberships
-                            if o.membertype == 'admin']
+        user_organizations=[o for o in Organization.query.find()
+                            if c.user.username in o.project().admins()]
         return dict(
             user_organizations=user_organizations,
             cooperations=cooperations, 
@@ -125,7 +125,7 @@ class OrganizationToolController(BaseController):
     def send_request(self, organization, coll_type, **kw):
         organization = Organization.getById(organization)     
 
-        if not organization or organization.userPermissions(c.user)!='admin':
+        if (not organization) or not (c.user.username in organization.project().admins()):
             flash("You are not allowed to perform this action.", "error")
             redirect(".")
             return

http://git-wip-us.apache.org/repos/asf/incubator-allura/blob/c4e7da6e/ForgeOrganization/setup.py
----------------------------------------------------------------------
diff --git a/ForgeOrganization/setup.py b/ForgeOrganization/setup.py
index 5330aa1..e7389d6 100644
--- a/ForgeOrganization/setup.py
+++ b/ForgeOrganization/setup.py
@@ -27,7 +27,7 @@ setup(name='ForgeOrganization',
       organization=forgeorganization.organization.main:ForgeOrganizationApp
 
       [allura]
+      organizationprofile = forgeorganization.organization_profile.organization_main:OrganizationProfileApp
       organizationstool=forgeorganization.tool.main:ForgeOrganizationToolApp
-
       """,
       )