organization neighborhood and project
Signed-off-by: Stefano Invernizzi <stefanoinve@apache.org>
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 @@
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__()
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 @@
# 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):
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 @@
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 @@
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 @@
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 @@
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 @@
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
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 @@
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 @@
{
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 @@
.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");
}
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 @@
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 @@
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()
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 @@
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 @@
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 @@
@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 @@
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':
+ if memb.status=='request' and status=='active':
allowed=False
- if memb.status=='invitation' and status=='active' and memb.member!=c.user:
- 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())
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
m = cls(
organization_id=organization_id,
member_id=member_id,
- membertype=membertype,
role=role,
startdate=None,
status=status)
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>
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 @@
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 @@
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 @@
name="requestfrom",
attrs={'value':'user'},
show_errors=False)
- ] + additional_hidden,
+ ],
fields=[
ew.HTMLField(
text=orgnamefield,
@@ -268,7 +251,6 @@
ew.HTMLField(
text=org.organization_type,
show_errors=False),
- permission,
ew.TextField(
name='role',
attrs=dict(value=m.role),
@@ -332,18 +314,6 @@
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 @@
attrs={'value':'Save'},
show_errors=False)])]
return super(ChangeCollaborationStatusForm, self).display(**kw)
-
-
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
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')
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
--- /dev/null
+++ b/ForgeOrganization/forgeorganization/organization_profile/templates/__init__.py
diff --git a/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html b/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
similarity index 82%
rename from ForgeOrganization/forgeorganization/organization/templates/edit_profile.html
rename to ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
index df90567..aca2a57 100644
--- a/ForgeOrganization/forgeorganization/organization/templates/edit_profile.html
+++ b/ForgeOrganization/forgeorganization/organization_profile/templates/edit_profile.html
@@ -7,12 +7,10 @@
{% block content %}
-{% if permissions == 'admin' %}
-
- <ul><li><a href="{{organization.url()}}">Click here</a> to check your public profile.</ul>
+ <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()+'change_data') }}
+ {{forms.update_profile.display(organization=organization, action=organization.url()+'admin/organizationprofile/change_data') }}
</div>
<div class="grid-20" style="clear:both;">
@@ -27,7 +25,7 @@
</thead>
</tr>
{% for wf in organization.getWorkfields() %}
- {{forms.remove_work_field.display(workfield=wf, action=organization.url()+'remove_work_field')}}
+ {{forms.remove_work_field.display(workfield=wf, action=organization.url()+'admin/organizationprofile/remove_work_field')}}
{%endfor%}
</table>
{% else %}
@@ -35,7 +33,7 @@
{% 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') }}
+ {{forms.add_work_field.display(organization=organization, action=organization.url()+'admin/organizationprofile/add_work_field') }}
</div>
</div>
@@ -47,7 +45,6 @@
<thead>
<tr>
<th>Name</th>
- <th>Permission level</th>
<th>Role</th>
<th>Status</th>
<th>Actions</th>
@@ -58,7 +55,7 @@
<tr>
{{forms.new_change_membership_from_organization().display(
membership=membership,
- action=membership.organization.url()+'change_membership')}}
+ action=membership.organization.url()+'admin/organizationprofile/change_membership')}}
</tr>
{% endfor %}
</tbody>
@@ -71,7 +68,7 @@
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')}}
+ {{forms.invite_user_form.display(action=organization.url()+'admin/organizationprofile/invite_user')}}
</div>
@@ -94,7 +91,7 @@
<tr>
{{forms.new_change_collaboration_status().display(
collaboration=org,
- action=org.organization.url()+'update_collaboration_status')}}
+ action=organization.url()+'admin/organizationprofile/update_collaboration_status')}}
</tr>
{% endfor %}
</tbody>
@@ -108,11 +105,7 @@
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')}}
+ {{forms.request_collaboration_form.display(action=organization.url()+'admin/organizationprofile/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 %}
diff --git a/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html b/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
similarity index 88%
rename from ForgeOrganization/forgeorganization/organization/templates/organization_profile.html
rename to ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
index c825113..3c04a96 100644
--- a/ForgeOrganization/forgeorganization/organization/templates/organization_profile.html
+++ b/ForgeOrganization/forgeorganization/organization_profile/templates/organization_index.html
@@ -1,30 +1,47 @@
{% set hide_left_bar = True %}
{% extends g.theme.master %}
-{% block title %}Organization profile{% endblock %}
-{% block header %}Organization profile{% endblock %}
+
+{% 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 %}
- {% 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>
+ {% 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>
@@ -35,18 +52,21 @@
</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>
@@ -112,8 +132,8 @@
</table>
{% endif %}
</div>
-
- {% if not is_member %}
+
+ {% if ask_admission %}
<div class="grid-20" style="clear:both;">
<h3>Are you a member of this organization?</h3>
<p>
@@ -121,11 +141,11 @@
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')}}
+ {{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">
@@ -182,4 +202,5 @@
{% endif %}
{% endif %}
+
{% endblock %}
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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
#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 @@
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 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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',
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 @@
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 @@
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
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 @@
organization=forgeorganization.organization.main:ForgeOrganizationApp
[allura]
+ organizationprofile = forgeorganization.organization_profile.organization_main:OrganizationProfileApp
organizationstool=forgeorganization.tool.main:ForgeOrganizationToolApp
-
""",
)