Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 9cd9bfe7

History | View | Annotate | Download (28.6 kB)

1 abd8467c Giorgos Korfiatis
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 5ce3ce4f Sofia Papagiannaki
#
3 f36af44a Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 f36af44a Antony Chazapis
# without modification, are permitted provided that the following
5 f36af44a Antony Chazapis
# conditions are met:
6 5ce3ce4f Sofia Papagiannaki
#
7 f36af44a Antony Chazapis
#   1. Redistributions of source code must retain the above
8 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
9 f36af44a Antony Chazapis
#      disclaimer.
10 5ce3ce4f Sofia Papagiannaki
#
11 f36af44a Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
13 f36af44a Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 f36af44a Antony Chazapis
#      provided with the distribution.
15 5ce3ce4f Sofia Papagiannaki
#
16 f36af44a Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 f36af44a Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 f36af44a Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 f36af44a Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 f36af44a Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 f36af44a Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 f36af44a Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 f36af44a Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 f36af44a Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 f36af44a Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 f36af44a Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 f36af44a Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 5ce3ce4f Sofia Papagiannaki
#
29 f36af44a Antony Chazapis
# The views and conclusions contained in the software and
30 f36af44a Antony Chazapis
# documentation are those of the authors and should not be
31 f36af44a Antony Chazapis
# interpreted as representing official policies, either expressed
32 f36af44a Antony Chazapis
# or implied, of GRNET S.A.
33 f36af44a Antony Chazapis
34 f36af44a Antony Chazapis
import logging
35 f36af44a Antony Chazapis
36 f36af44a Antony Chazapis
from django.utils.translation import ugettext as _
37 f9224cc0 Sofia Papagiannaki
from django.core.mail import send_mail, get_connection
38 f36af44a Antony Chazapis
from django.core.urlresolvers import reverse
39 8998f09a Sofia Papagiannaki
from django.contrib.auth import login as auth_login, logout as auth_logout
40 73fbaec4 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
41 3c22bad0 Giorgos Korfiatis
from django.db.models import Q
42 ff67242a Giorgos Korfiatis
from django.http import Http404
43 27e26a41 Sofia Papagiannaki
44 734107ef Kostas Papadimitriou
from synnefo_branding.utils import render_to_string
45 734107ef Kostas Papadimitriou
46 d2c9adac Christos Stavrakakis
from synnefo.lib import join_urls
47 8998f09a Sofia Papagiannaki
from astakos.im.models import AstakosUser, Invitation, ProjectMembership, \
48 8998f09a Sofia Papagiannaki
    ProjectApplication, Project, Chain, new_chain
49 8998f09a Sofia Papagiannaki
from astakos.im.quotas import qh_sync_user, get_pending_app_quota, \
50 8998f09a Sofia Papagiannaki
    register_pending_apps, qh_sync_project, qh_sync_locked_users, \
51 8998f09a Sofia Papagiannaki
    get_users_for_update, members_to_sync
52 8998f09a Sofia Papagiannaki
from astakos.im.project_notif import membership_change_notify, \
53 8998f09a Sofia Papagiannaki
    membership_enroll_notify, membership_request_notify, \
54 8998f09a Sofia Papagiannaki
    membership_leave_request_notify, application_submit_notify, \
55 8998f09a Sofia Papagiannaki
    application_approve_notify, application_deny_notify, \
56 8998f09a Sofia Papagiannaki
    project_termination_notify, project_suspension_notify
57 0a7a4104 Kostas Papadimitriou
from astakos.im import settings
58 8998f09a Sofia Papagiannaki
59 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
60 f36af44a Antony Chazapis
61 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
62 f36af44a Antony Chazapis
63 5ce3ce4f Sofia Papagiannaki
64 bf0c6de5 Sofia Papagiannaki
def login(request, user):
65 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
66 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
67 c3c2212a Sofia Papagiannaki
    SessionCatalog(
68 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
69 c3c2212a Sofia Papagiannaki
        user=user
70 c3c2212a Sofia Papagiannaki
    ).save()
71 5df4c364 Kostas Papadimitriou
    logger.info('%s logged in.', user.log_display)
72 5df4c364 Kostas Papadimitriou
73 bf0c6de5 Sofia Papagiannaki
74 5df4c364 Kostas Papadimitriou
def logout(request, *args, **kwargs):
75 5df4c364 Kostas Papadimitriou
    user = request.user
76 5df4c364 Kostas Papadimitriou
    auth_logout(request, *args, **kwargs)
77 5df4c364 Kostas Papadimitriou
    logger.info('%s logged out.', user.log_display)
78 111f3da6 Sofia Papagiannaki
79 5ce3ce4f Sofia Papagiannaki
80 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
81 f36af44a Antony Chazapis
    """
82 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
83 f36af44a Antony Chazapis
    """
84 8998f09a Sofia Papagiannaki
    url = join_urls(settings.BASEURL, user.get_activation_url(nxt=reverse('index')))
85 683cf244 Sofia Papagiannaki
    message = render_to_string(template_name, {
86 5ce3ce4f Sofia Papagiannaki
                               'user': user,
87 5ce3ce4f Sofia Papagiannaki
                               'url': url,
88 8998f09a Sofia Papagiannaki
                               'baseurl': settings.BASEURL,
89 8998f09a Sofia Papagiannaki
                               'site_name': settings.SITENAME,
90 8998f09a Sofia Papagiannaki
                               'support': settings.CONTACT_EMAIL})
91 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
92 8998f09a Sofia Papagiannaki
    send_mail(_(settings.VERIFICATION_EMAIL_SUBJECT), message, sender, [user.email],
93 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
94 e7cb4085 Kostas Papadimitriou
    logger.info("Sent user verirfication email: %s", user.log_display)
95 683cf244 Sofia Papagiannaki
96 5ce3ce4f Sofia Papagiannaki
97 9a06d96f Olga Brani
def _send_admin_notification(template_name,
98 e7cb4085 Kostas Papadimitriou
                             context=None,
99 e7cb4085 Kostas Papadimitriou
                             user=None,
100 e7cb4085 Kostas Papadimitriou
                             msg="",
101 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
102 683cf244 Sofia Papagiannaki
    """
103 e7cb4085 Kostas Papadimitriou
    Send notification email to settings.HELPDESK + settings.MANAGERS +
104 e7cb4085 Kostas Papadimitriou
    settings.ADMINS.
105 683cf244 Sofia Papagiannaki
    """
106 e7cb4085 Kostas Papadimitriou
    if context is None:
107 e7cb4085 Kostas Papadimitriou
        context = {}
108 e7cb4085 Kostas Papadimitriou
    if not 'user' in context:
109 e7cb4085 Kostas Papadimitriou
        context['user'] = user
110 e7cb4085 Kostas Papadimitriou
111 e7cb4085 Kostas Papadimitriou
    message = render_to_string(template_name, context)
112 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
113 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
114 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
115 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, recipient_list,
116 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
117 e7cb4085 Kostas Papadimitriou
    if user:
118 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s) for user %s' % (msg,
119 e7cb4085 Kostas Papadimitriou
                                                            user.log_display)
120 8f5a3a06 Sofia Papagiannaki
    else:
121 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s)' % msg
122 683cf244 Sofia Papagiannaki
123 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
124 5ce3ce4f Sofia Papagiannaki
125 e7cb4085 Kostas Papadimitriou
126 e7cb4085 Kostas Papadimitriou
def send_account_pending_moderation_notification(
127 e7cb4085 Kostas Papadimitriou
        user,
128 e7cb4085 Kostas Papadimitriou
        template_name='im/account_pending_moderation_notification.txt'):
129 e7cb4085 Kostas Papadimitriou
    """
130 e7cb4085 Kostas Papadimitriou
    Notify admins that a new user has verified his email address and moderation
131 e7cb4085 Kostas Papadimitriou
    step is required to activate his account.
132 e7cb4085 Kostas Papadimitriou
    """
133 8998f09a Sofia Papagiannaki
    subject = _(settings.ACCOUNT_CREATION_SUBJECT) % {'user': user.email}
134 e7cb4085 Kostas Papadimitriou
    return _send_admin_notification(template_name, {}, subject=subject,
135 e7cb4085 Kostas Papadimitriou
                                    user=user, msg="account creation")
136 9a06d96f Olga Brani
137 9a06d96f Olga Brani
138 e7cb4085 Kostas Papadimitriou
def send_account_activated_notification(
139 e7cb4085 Kostas Papadimitriou
        user,
140 e7cb4085 Kostas Papadimitriou
        template_name='im/account_activated_notification.txt'):
141 a0be6a0c Sofia Papagiannaki
    """
142 e7cb4085 Kostas Papadimitriou
    Send email to settings.HELPDESK + settings.MANAGERES + settings.ADMINS
143 e7cb4085 Kostas Papadimitriou
    lists to notify that a new account has been accepted and activated.
144 a0be6a0c Sofia Papagiannaki
    """
145 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
146 3abf6c78 Sofia Papagiannaki
        template_name,
147 3abf6c78 Sofia Papagiannaki
        {'user': user}
148 3abf6c78 Sofia Papagiannaki
    )
149 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
150 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
151 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
152 8998f09a Sofia Papagiannaki
    send_mail(_(settings.HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email},
153 e7cb4085 Kostas Papadimitriou
              message, sender, recipient_list, connection=get_connection())
154 e7cb4085 Kostas Papadimitriou
    msg = 'Sent helpdesk admin notification for %s' % user.email
155 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
156 a0be6a0c Sofia Papagiannaki
157 5ce3ce4f Sofia Papagiannaki
158 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
159 683cf244 Sofia Papagiannaki
    """
160 683cf244 Sofia Papagiannaki
    Send invitation email.
161 683cf244 Sofia Papagiannaki
    """
162 8998f09a Sofia Papagiannaki
    subject = _(settings.INVITATION_EMAIL_SUBJECT)
163 8998f09a Sofia Papagiannaki
    url = '%s?code=%d' % (join_urls(settings.BASEURL, reverse('index')), invitation.code)
164 aab4d540 Sofia Papagiannaki
    message = render_to_string(template_name, {
165 5ce3ce4f Sofia Papagiannaki
                               'invitation': invitation,
166 5ce3ce4f Sofia Papagiannaki
                               'url': url,
167 8998f09a Sofia Papagiannaki
                               'baseurl': settings.BASEURL,
168 8998f09a Sofia Papagiannaki
                               'site_name': settings.SITENAME,
169 8998f09a Sofia Papagiannaki
                               'support': settings.CONTACT_EMAIL})
170 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
171 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, [invitation.username],
172 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
173 e7cb4085 Kostas Papadimitriou
    msg = 'Sent invitation %s' % invitation
174 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
175 e7cb4085 Kostas Papadimitriou
    inviter_invitations = invitation.inviter.invitations
176 e7cb4085 Kostas Papadimitriou
    invitation.inviter.invitations = max(0, inviter_invitations - 1)
177 e7cb4085 Kostas Papadimitriou
    invitation.inviter.save()
178 683cf244 Sofia Papagiannaki
179 5ce3ce4f Sofia Papagiannaki
180 683cf244 Sofia Papagiannaki
def send_greeting(user, email_template_name='im/welcome_email.txt'):
181 683cf244 Sofia Papagiannaki
    """
182 e7cb4085 Kostas Papadimitriou
    Send welcome email to an accepted/activated user.
183 5ce3ce4f Sofia Papagiannaki

184 f36af44a Antony Chazapis
    Raises SMTPException, socket.error
185 f36af44a Antony Chazapis
    """
186 8998f09a Sofia Papagiannaki
    subject = _(settings.GREETING_EMAIL_SUBJECT)
187 f36af44a Antony Chazapis
    message = render_to_string(email_template_name, {
188 5ce3ce4f Sofia Papagiannaki
                               'user': user,
189 8998f09a Sofia Papagiannaki
                               'url': join_urls(settings.BASEURL, reverse('index')),
190 8998f09a Sofia Papagiannaki
                               'baseurl': settings.BASEURL,
191 8998f09a Sofia Papagiannaki
                               'site_name': settings.SITENAME,
192 8998f09a Sofia Papagiannaki
                               'support': settings.CONTACT_EMAIL})
193 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
194 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, [user.email],
195 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
196 e7cb4085 Kostas Papadimitriou
    msg = 'Sent greeting %s' % user.log_display
197 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
198 8f5a3a06 Sofia Papagiannaki
199 5ce3ce4f Sofia Papagiannaki
200 8f5a3a06 Sofia Papagiannaki
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
201 8998f09a Sofia Papagiannaki
    subject = _(settings.FEEDBACK_EMAIL_SUBJECT)
202 7d145e78 Sofia Papagiannaki
    from_email = settings.SERVER_EMAIL
203 0a7a4104 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK]
204 8f5a3a06 Sofia Papagiannaki
    content = render_to_string(email_template_name, {
205 8f5a3a06 Sofia Papagiannaki
        'message': msg,
206 8f5a3a06 Sofia Papagiannaki
        'data': data,
207 8f5a3a06 Sofia Papagiannaki
        'user': user})
208 e182fc26 Sofia Papagiannaki
    send_mail(subject, content, from_email, recipient_list,
209 e182fc26 Sofia Papagiannaki
              connection=get_connection())
210 e182fc26 Sofia Papagiannaki
    msg = 'Sent feedback from %s' % user.log_display
211 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
212 f36af44a Antony Chazapis
213 5ce3ce4f Sofia Papagiannaki
214 73fbaec4 Sofia Papagiannaki
def send_change_email(
215 73fbaec4 Sofia Papagiannaki
    ec, request, email_template_name='registration/email_change_email.txt'):
216 e182fc26 Sofia Papagiannaki
    url = ec.get_url()
217 e182fc26 Sofia Papagiannaki
    url = request.build_absolute_uri(url)
218 8998f09a Sofia Papagiannaki
    c = {'url': url, 'site_name': settings.SITENAME, 'support': settings.CONTACT_EMAIL,
219 734107ef Kostas Papadimitriou
         'ec': ec}
220 734107ef Kostas Papadimitriou
    message = render_to_string(email_template_name, c)
221 e182fc26 Sofia Papagiannaki
    from_email = settings.SERVER_EMAIL
222 8998f09a Sofia Papagiannaki
    send_mail(_(settings.EMAIL_CHANGE_EMAIL_SUBJECT), message, from_email,
223 734107ef Kostas Papadimitriou
              [ec.new_email_address], connection=get_connection())
224 e182fc26 Sofia Papagiannaki
    msg = 'Sent change email for %s' % ec.user.log_display
225 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
226 f36af44a Antony Chazapis
227 5ce3ce4f Sofia Papagiannaki
228 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
229 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
230 73fbaec4 Sofia Papagiannaki
    inv.save()
231 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
232 e30537f1 Sofia Papagiannaki
    inviter.invitations = max(0, inviter.invitations - 1)
233 73fbaec4 Sofia Papagiannaki
    inviter.save()
234 5ce3ce4f Sofia Papagiannaki
235 73fbaec4 Sofia Papagiannaki
236 7a08e179 Giorgos Korfiatis
### PROJECT FUNCTIONS ###
237 fcc1e93f Sofia Papagiannaki
238 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
239 7a08e179 Giorgos Korfiatis
MODERATED_POLICY = 2
240 7a08e179 Giorgos Korfiatis
CLOSED_POLICY = 3
241 7a08e179 Giorgos Korfiatis
242 7a08e179 Giorgos Korfiatis
POLICIES = [AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY]
243 b0686c16 Giorgos Korfiatis
244 73fbaec4 Sofia Papagiannaki
245 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
246 73fbaec4 Sofia Papagiannaki
    try:
247 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
248 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
249 7a08e179 Giorgos Korfiatis
        m = (_(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) %
250 7a08e179 Giorgos Korfiatis
             project_application_id)
251 7a08e179 Giorgos Korfiatis
        raise IOError(m)
252 7a08e179 Giorgos Korfiatis
253 73fbaec4 Sofia Papagiannaki
254 a75dbd7b Giorgos Korfiatis
def get_related_project_id(application_id):
255 a75dbd7b Giorgos Korfiatis
    try:
256 a75dbd7b Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
257 a75dbd7b Giorgos Korfiatis
        chain = app.chain
258 7a08e179 Giorgos Korfiatis
        Project.objects.get(id=chain)
259 a75dbd7b Giorgos Korfiatis
        return chain
260 3966d268 Giorgos Korfiatis
    except (ProjectApplication.DoesNotExist, Project.DoesNotExist):
261 a75dbd7b Giorgos Korfiatis
        return None
262 a75dbd7b Giorgos Korfiatis
263 7a08e179 Giorgos Korfiatis
264 0932ac43 Giorgos Korfiatis
def get_chain_of_application_id(application_id):
265 0932ac43 Giorgos Korfiatis
    try:
266 0932ac43 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
267 0932ac43 Giorgos Korfiatis
        chain = app.chain
268 0932ac43 Giorgos Korfiatis
        return chain.chain
269 7a08e179 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
270 0932ac43 Giorgos Korfiatis
        return None
271 0932ac43 Giorgos Korfiatis
272 7a08e179 Giorgos Korfiatis
273 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
274 eb9ff37a Sofia Papagiannaki
    try:
275 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
276 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
277 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id
278 7a08e179 Giorgos Korfiatis
        raise IOError(m)
279 7a08e179 Giorgos Korfiatis
280 eb9ff37a Sofia Papagiannaki
281 c10f1cf5 Giorgos Korfiatis
def get_project_by_name(name):
282 c10f1cf5 Giorgos Korfiatis
    try:
283 c10f1cf5 Giorgos Korfiatis
        return Project.objects.get(name=name)
284 c10f1cf5 Giorgos Korfiatis
    except Project.DoesNotExist:
285 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % name
286 7a08e179 Giorgos Korfiatis
        raise IOError(m)
287 c10f1cf5 Giorgos Korfiatis
288 c10f1cf5 Giorgos Korfiatis
289 3c22bad0 Giorgos Korfiatis
def get_chain_for_update(chain_id):
290 8dcaa6ac Giorgos Korfiatis
    try:
291 3c22bad0 Giorgos Korfiatis
        return Chain.objects.get_for_update(chain=chain_id)
292 3c22bad0 Giorgos Korfiatis
    except Chain.DoesNotExist:
293 3c22bad0 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % chain_id
294 7a08e179 Giorgos Korfiatis
        raise IOError(m)
295 7a08e179 Giorgos Korfiatis
296 8dcaa6ac Giorgos Korfiatis
297 3c22bad0 Giorgos Korfiatis
def get_chain_of_application_for_update(app_id):
298 3c22bad0 Giorgos Korfiatis
    app = get_application(app_id)
299 3c22bad0 Giorgos Korfiatis
    return Chain.objects.get_for_update(chain=app.chain_id)
300 3c22bad0 Giorgos Korfiatis
301 3c22bad0 Giorgos Korfiatis
302 3c22bad0 Giorgos Korfiatis
def get_application(application_id):
303 19eb3ee6 Giorgos Korfiatis
    try:
304 3c22bad0 Giorgos Korfiatis
        return ProjectApplication.objects.get(id=application_id)
305 19eb3ee6 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
306 19eb3ee6 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
307 19eb3ee6 Giorgos Korfiatis
        raise IOError(m)
308 19eb3ee6 Giorgos Korfiatis
309 7a08e179 Giorgos Korfiatis
310 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
311 73fbaec4 Sofia Papagiannaki
    try:
312 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
313 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
314 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_USER_ID) % user_id
315 7a08e179 Giorgos Korfiatis
        raise IOError(m)
316 7a08e179 Giorgos Korfiatis
317 73fbaec4 Sofia Papagiannaki
318 3c049f6d Giorgos Korfiatis
def get_user_by_uuid(uuid):
319 3c049f6d Giorgos Korfiatis
    try:
320 3c049f6d Giorgos Korfiatis
        return AstakosUser.objects.get(uuid=uuid)
321 3c049f6d Giorgos Korfiatis
    except AstakosUser.DoesNotExist:
322 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_USER_ID) % uuid
323 7a08e179 Giorgos Korfiatis
        raise IOError(m)
324 3c049f6d Giorgos Korfiatis
325 97e93991 Kostas Papadimitriou
326 3c22bad0 Giorgos Korfiatis
def get_membership(project_id, user_id):
327 73fbaec4 Sofia Papagiannaki
    try:
328 3c22bad0 Giorgos Korfiatis
        objs = ProjectMembership.objects.select_related('project', 'person')
329 3c22bad0 Giorgos Korfiatis
        return objs.get(project__id=project_id, person__id=user_id)
330 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
331 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
332 7a08e179 Giorgos Korfiatis
        raise IOError(m)
333 7a08e179 Giorgos Korfiatis
334 73fbaec4 Sofia Papagiannaki
335 3c22bad0 Giorgos Korfiatis
def get_membership_by_id(project_id, memb_id):
336 7f3c4920 Giorgos Korfiatis
    try:
337 3c22bad0 Giorgos Korfiatis
        objs = ProjectMembership.objects.select_related('project', 'person')
338 3c22bad0 Giorgos Korfiatis
        return objs.get(project__id=project_id, id=memb_id)
339 7f3c4920 Giorgos Korfiatis
    except ProjectMembership.DoesNotExist:
340 7f3c4920 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
341 7f3c4920 Giorgos Korfiatis
        raise IOError(m)
342 7f3c4920 Giorgos Korfiatis
343 7f3c4920 Giorgos Korfiatis
344 d07ce657 Giorgos Korfiatis
def checkAllowed(entity, request_user, admin_only=False):
345 3c638f72 Giorgos Korfiatis
    if isinstance(entity, Project):
346 3c638f72 Giorgos Korfiatis
        application = entity.application
347 3c638f72 Giorgos Korfiatis
    elif isinstance(entity, ProjectApplication):
348 3c638f72 Giorgos Korfiatis
        application = entity
349 3c638f72 Giorgos Korfiatis
    else:
350 3c638f72 Giorgos Korfiatis
        m = "%s not a Project nor a ProjectApplication" % (entity,)
351 3c638f72 Giorgos Korfiatis
        raise ValueError(m)
352 3c638f72 Giorgos Korfiatis
353 d07ce657 Giorgos Korfiatis
    if not request_user or request_user.is_project_admin():
354 d07ce657 Giorgos Korfiatis
        return
355 d07ce657 Giorgos Korfiatis
356 d07ce657 Giorgos Korfiatis
    if not admin_only and application.owner == request_user:
357 d07ce657 Giorgos Korfiatis
        return
358 d07ce657 Giorgos Korfiatis
359 d07ce657 Giorgos Korfiatis
    m = _(astakos_messages.NOT_ALLOWED)
360 d07ce657 Giorgos Korfiatis
    raise PermissionDenied(m)
361 d07ce657 Giorgos Korfiatis
362 907f15db Giorgos Korfiatis
363 907f15db Giorgos Korfiatis
def checkAlive(project):
364 907f15db Giorgos Korfiatis
    if not project.is_alive:
365 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
366 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
367 7a08e179 Giorgos Korfiatis
368 907f15db Giorgos Korfiatis
369 ff67242a Giorgos Korfiatis
def accept_membership_checks(project, request_user):
370 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
371 907f15db Giorgos Korfiatis
    checkAlive(project)
372 b0686c16 Giorgos Korfiatis
373 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
374 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
375 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_JOIN_POLICY_CLOSED)
376 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
377 b0686c16 Giorgos Korfiatis
378 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
379 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED)
380 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
381 73fbaec4 Sofia Papagiannaki
382 d07ce657 Giorgos Korfiatis
383 7f3c4920 Giorgos Korfiatis
def accept_membership(project_id, memb_id, request_user=None):
384 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
385 14f7f6a5 Giorgos Korfiatis
386 3c22bad0 Giorgos Korfiatis
    membership = get_membership_by_id(project_id, memb_id)
387 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
388 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
389 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
390 d4fc6292 Giorgos Korfiatis
391 3c22bad0 Giorgos Korfiatis
    project = membership.project
392 3c22bad0 Giorgos Korfiatis
    accept_membership_checks(project, request_user)
393 7f3c4920 Giorgos Korfiatis
    user = membership.person
394 73fbaec4 Sofia Papagiannaki
    membership.accept()
395 e336910f Giorgos Korfiatis
    qh_sync_user(user)
396 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been accepted in %s." %
397 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
398 73fbaec4 Sofia Papagiannaki
399 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'accepted')
400 73fbaec4 Sofia Papagiannaki
    return membership
401 73fbaec4 Sofia Papagiannaki
402 7a08e179 Giorgos Korfiatis
403 ff67242a Giorgos Korfiatis
def reject_membership_checks(project, request_user):
404 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
405 907f15db Giorgos Korfiatis
    checkAlive(project)
406 e47fb17a Sofia Papagiannaki
407 d07ce657 Giorgos Korfiatis
408 7f3c4920 Giorgos Korfiatis
def reject_membership(project_id, memb_id, request_user=None):
409 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
410 3c22bad0 Giorgos Korfiatis
411 3c22bad0 Giorgos Korfiatis
    membership = get_membership_by_id(project_id, memb_id)
412 14f7f6a5 Giorgos Korfiatis
    if not membership.can_reject():
413 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
414 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
415 d4fc6292 Giorgos Korfiatis
416 3c22bad0 Giorgos Korfiatis
    project = membership.project
417 3c22bad0 Giorgos Korfiatis
    reject_membership_checks(project, request_user)
418 7f3c4920 Giorgos Korfiatis
    user = membership.person
419 73fbaec4 Sofia Papagiannaki
    membership.reject()
420 f30f0170 Giorgos Korfiatis
    logger.info("Request of user %s for %s has been rejected." %
421 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
422 73fbaec4 Sofia Papagiannaki
423 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'rejected')
424 73fbaec4 Sofia Papagiannaki
    return membership
425 73fbaec4 Sofia Papagiannaki
426 7a08e179 Giorgos Korfiatis
427 aad0e329 Giorgos Korfiatis
def cancel_membership_checks(project):
428 aad0e329 Giorgos Korfiatis
    checkAlive(project)
429 aad0e329 Giorgos Korfiatis
430 d07ce657 Giorgos Korfiatis
431 d07ce657 Giorgos Korfiatis
def cancel_membership(project_id, request_user):
432 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
433 3c22bad0 Giorgos Korfiatis
434 3c22bad0 Giorgos Korfiatis
    membership = get_membership(project_id, request_user.id)
435 aad0e329 Giorgos Korfiatis
    if not membership.can_cancel():
436 aad0e329 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
437 aad0e329 Giorgos Korfiatis
        raise PermissionDenied(m)
438 aad0e329 Giorgos Korfiatis
439 3c22bad0 Giorgos Korfiatis
    project = membership.project
440 3c22bad0 Giorgos Korfiatis
    cancel_membership_checks(project)
441 aad0e329 Giorgos Korfiatis
    membership.cancel()
442 f30f0170 Giorgos Korfiatis
    logger.info("Request of user %s for %s has been cancelled." %
443 f30f0170 Giorgos Korfiatis
                (membership.person.log_display, project))
444 aad0e329 Giorgos Korfiatis
445 7a08e179 Giorgos Korfiatis
446 ff67242a Giorgos Korfiatis
def remove_membership_checks(project, request_user=None):
447 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
448 907f15db Giorgos Korfiatis
    checkAlive(project)
449 73fbaec4 Sofia Papagiannaki
450 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
451 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
452 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED)
453 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
454 7a08e179 Giorgos Korfiatis
455 b0686c16 Giorgos Korfiatis
456 7f3c4920 Giorgos Korfiatis
def remove_membership(project_id, memb_id, request_user=None):
457 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
458 3c22bad0 Giorgos Korfiatis
459 3c22bad0 Giorgos Korfiatis
    membership = get_membership_by_id(project_id, memb_id)
460 14f7f6a5 Giorgos Korfiatis
    if not membership.can_remove():
461 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
462 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
463 d4fc6292 Giorgos Korfiatis
464 3c22bad0 Giorgos Korfiatis
    project = membership.project
465 3c22bad0 Giorgos Korfiatis
    remove_membership_checks(project, request_user)
466 7f3c4920 Giorgos Korfiatis
    user = membership.person
467 73fbaec4 Sofia Papagiannaki
    membership.remove()
468 e336910f Giorgos Korfiatis
    qh_sync_user(user)
469 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been removed from %s." %
470 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
471 73fbaec4 Sofia Papagiannaki
472 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'removed')
473 73fbaec4 Sofia Papagiannaki
    return membership
474 73fbaec4 Sofia Papagiannaki
475 7a08e179 Giorgos Korfiatis
476 ff67242a Giorgos Korfiatis
def enroll_member(project_id, user, request_user=None):
477 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
478 3c22bad0 Giorgos Korfiatis
    project = get_project_by_id(project_id)
479 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
480 e05c541e Giorgos Korfiatis
481 e05c541e Giorgos Korfiatis
    membership, created = ProjectMembership.objects.get_or_create(
482 e05c541e Giorgos Korfiatis
        project=project,
483 e05c541e Giorgos Korfiatis
        person=user)
484 14f7f6a5 Giorgos Korfiatis
485 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
486 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
487 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
488 d4fc6292 Giorgos Korfiatis
489 907f15db Giorgos Korfiatis
    membership.accept()
490 e336910f Giorgos Korfiatis
    qh_sync_user(user)
491 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been enrolled in %s." %
492 f30f0170 Giorgos Korfiatis
                (membership.person.log_display, project))
493 570015d2 Giorgos Korfiatis
494 466cc12c Giorgos Korfiatis
    membership_enroll_notify(project, membership.person)
495 907f15db Giorgos Korfiatis
    return membership
496 8dcaa6ac Giorgos Korfiatis
497 7a08e179 Giorgos Korfiatis
498 ff67242a Giorgos Korfiatis
def leave_project_checks(project):
499 907f15db Giorgos Korfiatis
    checkAlive(project)
500 8dcaa6ac Giorgos Korfiatis
501 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
502 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
503 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED)
504 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
505 7a08e179 Giorgos Korfiatis
506 73fbaec4 Sofia Papagiannaki
507 d4660e00 Giorgos Korfiatis
def can_leave_request(project, user):
508 d4660e00 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
509 d4660e00 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
510 d4660e00 Giorgos Korfiatis
        return False
511 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
512 d4660e00 Giorgos Korfiatis
    if m is None:
513 d4660e00 Giorgos Korfiatis
        return False
514 d4660e00 Giorgos Korfiatis
    if m.state != ProjectMembership.ACCEPTED:
515 d4660e00 Giorgos Korfiatis
        return False
516 d4660e00 Giorgos Korfiatis
    return True
517 d4660e00 Giorgos Korfiatis
518 d07ce657 Giorgos Korfiatis
519 d07ce657 Giorgos Korfiatis
def leave_project(project_id, request_user):
520 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
521 3c22bad0 Giorgos Korfiatis
522 3c22bad0 Giorgos Korfiatis
    membership = get_membership(project_id, request_user.id)
523 14f7f6a5 Giorgos Korfiatis
    if not membership.can_leave():
524 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
525 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
526 4e057833 Sofia Papagiannaki
527 3c22bad0 Giorgos Korfiatis
    project = membership.project
528 3c22bad0 Giorgos Korfiatis
    leave_project_checks(project)
529 3c22bad0 Giorgos Korfiatis
530 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
531 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
532 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
533 73fbaec4 Sofia Papagiannaki
        membership.remove()
534 e336910f Giorgos Korfiatis
        qh_sync_user(request_user)
535 f30f0170 Giorgos Korfiatis
        logger.info("User %s has left %s." %
536 3c22bad0 Giorgos Korfiatis
                    (request_user.log_display, project))
537 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
538 73fbaec4 Sofia Papagiannaki
    else:
539 c1007621 Giorgos Korfiatis
        membership.leave_request()
540 f30f0170 Giorgos Korfiatis
        logger.info("User %s requested to leave %s." %
541 3c22bad0 Giorgos Korfiatis
                    (request_user.log_display, project))
542 bb6a4465 Giorgos Korfiatis
        membership_leave_request_notify(project, membership.person)
543 bb6a4465 Giorgos Korfiatis
    return auto_accepted
544 73fbaec4 Sofia Papagiannaki
545 7a08e179 Giorgos Korfiatis
546 ff67242a Giorgos Korfiatis
def join_project_checks(project):
547 907f15db Giorgos Korfiatis
    checkAlive(project)
548 8dcaa6ac Giorgos Korfiatis
549 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
550 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
551 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_JOIN_POLICY_CLOSED)
552 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
553 7a08e179 Giorgos Korfiatis
554 73fbaec4 Sofia Papagiannaki
555 d4660e00 Giorgos Korfiatis
def can_join_request(project, user):
556 d4660e00 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
557 d4660e00 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
558 d4660e00 Giorgos Korfiatis
        return False
559 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
560 d4660e00 Giorgos Korfiatis
    if m:
561 d4660e00 Giorgos Korfiatis
        return False
562 d4660e00 Giorgos Korfiatis
    return True
563 d4660e00 Giorgos Korfiatis
564 d07ce657 Giorgos Korfiatis
565 d07ce657 Giorgos Korfiatis
def join_project(project_id, request_user):
566 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
567 3c22bad0 Giorgos Korfiatis
    project = get_project_by_id(project_id)
568 ff67242a Giorgos Korfiatis
    join_project_checks(project)
569 d07ce657 Giorgos Korfiatis
570 d07ce657 Giorgos Korfiatis
    membership, created = ProjectMembership.objects.get_or_create(
571 d07ce657 Giorgos Korfiatis
        project=project,
572 d07ce657 Giorgos Korfiatis
        person=request_user)
573 d07ce657 Giorgos Korfiatis
574 d07ce657 Giorgos Korfiatis
    if not created:
575 d07ce657 Giorgos Korfiatis
        msg = _(astakos_messages.MEMBERSHIP_REQUEST_EXISTS)
576 d07ce657 Giorgos Korfiatis
        raise PermissionDenied(msg)
577 73fbaec4 Sofia Papagiannaki
578 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
579 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
580 7a08e179 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and (
581 7a08e179 Giorgos Korfiatis
            not project.violates_members_limit(adding=1))):
582 73fbaec4 Sofia Papagiannaki
        membership.accept()
583 e336910f Giorgos Korfiatis
        qh_sync_user(request_user)
584 f30f0170 Giorgos Korfiatis
        logger.info("User %s joined %s." %
585 3c22bad0 Giorgos Korfiatis
                    (request_user.log_display, project))
586 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
587 bb6a4465 Giorgos Korfiatis
    else:
588 bb6a4465 Giorgos Korfiatis
        membership_request_notify(project, membership.person)
589 f30f0170 Giorgos Korfiatis
        logger.info("User %s requested to join %s." %
590 3c22bad0 Giorgos Korfiatis
                    (request_user.log_display, project))
591 bb6a4465 Giorgos Korfiatis
    return auto_accepted
592 8dcaa6ac Giorgos Korfiatis
593 7a08e179 Giorgos Korfiatis
594 6da04174 Giorgos Korfiatis
def submit_application(owner=None,
595 6da04174 Giorgos Korfiatis
                       name=None,
596 6da04174 Giorgos Korfiatis
                       precursor_id=None,
597 6da04174 Giorgos Korfiatis
                       homepage=None,
598 6da04174 Giorgos Korfiatis
                       description=None,
599 6da04174 Giorgos Korfiatis
                       start_date=None,
600 6da04174 Giorgos Korfiatis
                       end_date=None,
601 6da04174 Giorgos Korfiatis
                       member_join_policy=None,
602 6da04174 Giorgos Korfiatis
                       member_leave_policy=None,
603 6da04174 Giorgos Korfiatis
                       limit_on_members_number=None,
604 6da04174 Giorgos Korfiatis
                       comments=None,
605 6da04174 Giorgos Korfiatis
                       resource_policies=None,
606 6da04174 Giorgos Korfiatis
                       request_user=None):
607 69c822cc Giorgos Korfiatis
608 3e3743f2 Giorgos Korfiatis
    precursor = None
609 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
610 3c22bad0 Giorgos Korfiatis
        get_chain_of_application_for_update(precursor_id)
611 3c22bad0 Giorgos Korfiatis
        precursor = ProjectApplication.objects.get(id=precursor_id)
612 73fbaec4 Sofia Papagiannaki
613 3e3743f2 Giorgos Korfiatis
        if (request_user and
614 3e3743f2 Giorgos Korfiatis
            (not precursor.owner == request_user and
615 beda5f0f Georgios D. Tsoukalas
             not request_user.is_superuser
616 beda5f0f Georgios D. Tsoukalas
             and not request_user.is_project_admin())):
617 3e3743f2 Giorgos Korfiatis
            m = _(astakos_messages.NOT_ALLOWED)
618 3e3743f2 Giorgos Korfiatis
            raise PermissionDenied(m)
619 ee4aa6eb Giorgos Korfiatis
620 9770ba6c Giorgos Korfiatis
    force = request_user.is_project_admin()
621 9770ba6c Giorgos Korfiatis
    ok, limit = qh_add_pending_app(owner, precursor, force)
622 9770ba6c Giorgos Korfiatis
    if not ok:
623 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.REACHED_PENDING_APPLICATION_LIMIT) % limit
624 c7c0ec58 Giorgos Korfiatis
        raise PermissionDenied(m)
625 c7c0ec58 Giorgos Korfiatis
626 6da04174 Giorgos Korfiatis
    application = ProjectApplication(
627 6da04174 Giorgos Korfiatis
        applicant=request_user,
628 6da04174 Giorgos Korfiatis
        owner=owner,
629 6da04174 Giorgos Korfiatis
        name=name,
630 6da04174 Giorgos Korfiatis
        precursor_application_id=precursor_id,
631 6da04174 Giorgos Korfiatis
        homepage=homepage,
632 6da04174 Giorgos Korfiatis
        description=description,
633 6da04174 Giorgos Korfiatis
        start_date=start_date,
634 6da04174 Giorgos Korfiatis
        end_date=end_date,
635 6da04174 Giorgos Korfiatis
        member_join_policy=member_join_policy,
636 6da04174 Giorgos Korfiatis
        member_leave_policy=member_leave_policy,
637 6da04174 Giorgos Korfiatis
        limit_on_members_number=limit_on_members_number,
638 6da04174 Giorgos Korfiatis
        comments=comments)
639 1352dabb Kostas Papadimitriou
640 3e3743f2 Giorgos Korfiatis
    if precursor is None:
641 3e3743f2 Giorgos Korfiatis
        application.chain = new_chain()
642 3e3743f2 Giorgos Korfiatis
    else:
643 3e3743f2 Giorgos Korfiatis
        chain = precursor.chain
644 3e3743f2 Giorgos Korfiatis
        application.chain = chain
645 ea1e5d9f Giorgos Korfiatis
        objs = ProjectApplication.objects
646 3c22bad0 Giorgos Korfiatis
        pending = objs.filter(chain=chain, state=ProjectApplication.PENDING)
647 3e3743f2 Giorgos Korfiatis
        for app in pending:
648 3e3743f2 Giorgos Korfiatis
            app.state = ProjectApplication.REPLACED
649 3e3743f2 Giorgos Korfiatis
            app.save()
650 3e3743f2 Giorgos Korfiatis
651 3e3743f2 Giorgos Korfiatis
    application.save()
652 fa186923 Giorgos Korfiatis
    if resource_policies is not None:
653 fa186923 Giorgos Korfiatis
        application.set_resource_policies(resource_policies)
654 f30f0170 Giorgos Korfiatis
    logger.info("User %s submitted %s." %
655 f30f0170 Giorgos Korfiatis
                (request_user.log_display, application.log_display))
656 a3eb3a95 Giorgos Korfiatis
    application_submit_notify(application)
657 a3eb3a95 Giorgos Korfiatis
    return application
658 73fbaec4 Sofia Papagiannaki
659 7a08e179 Giorgos Korfiatis
660 64d0c13e Giorgos Korfiatis
def cancel_application(application_id, request_user=None, reason=""):
661 3c22bad0 Giorgos Korfiatis
    get_chain_of_application_for_update(application_id)
662 3c22bad0 Giorgos Korfiatis
    application = get_application(application_id)
663 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
664 3c638f72 Giorgos Korfiatis
665 01bdbd17 Giorgos Korfiatis
    if not application.can_cancel():
666 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_CANCEL %
667 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
668 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
669 3c638f72 Giorgos Korfiatis
670 9770ba6c Giorgos Korfiatis
    qh_release_pending_app(application.owner)
671 9770ba6c Giorgos Korfiatis
672 3c638f72 Giorgos Korfiatis
    application.cancel()
673 f30f0170 Giorgos Korfiatis
    logger.info("%s has been cancelled." % (application.log_display))
674 3c638f72 Giorgos Korfiatis
675 7a08e179 Giorgos Korfiatis
676 64d0c13e Giorgos Korfiatis
def dismiss_application(application_id, request_user=None, reason=""):
677 3c22bad0 Giorgos Korfiatis
    get_chain_of_application_for_update(application_id)
678 3c22bad0 Giorgos Korfiatis
    application = get_application(application_id)
679 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
680 3c638f72 Giorgos Korfiatis
681 01bdbd17 Giorgos Korfiatis
    if not application.can_dismiss():
682 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DISMISS %
683 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
684 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
685 3c638f72 Giorgos Korfiatis
686 3c638f72 Giorgos Korfiatis
    application.dismiss()
687 f30f0170 Giorgos Korfiatis
    logger.info("%s has been dismissed." % (application.log_display))
688 3c638f72 Giorgos Korfiatis
689 7a08e179 Giorgos Korfiatis
690 64d0c13e Giorgos Korfiatis
def deny_application(application_id, request_user=None, reason=""):
691 3c22bad0 Giorgos Korfiatis
    get_chain_of_application_for_update(application_id)
692 3c22bad0 Giorgos Korfiatis
    application = get_application(application_id)
693 01bdbd17 Giorgos Korfiatis
694 d07ce657 Giorgos Korfiatis
    checkAllowed(application, request_user, admin_only=True)
695 d07ce657 Giorgos Korfiatis
696 01bdbd17 Giorgos Korfiatis
    if not application.can_deny():
697 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DENY %
698 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
699 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
700 19eb3ee6 Giorgos Korfiatis
701 9770ba6c Giorgos Korfiatis
    qh_release_pending_app(application.owner)
702 9770ba6c Giorgos Korfiatis
703 2b745492 Giorgos Korfiatis
    application.deny(reason)
704 f30f0170 Giorgos Korfiatis
    logger.info("%s has been denied with reason \"%s\"." %
705 f30f0170 Giorgos Korfiatis
                (application.log_display, reason))
706 19eb3ee6 Giorgos Korfiatis
    application_deny_notify(application)
707 19eb3ee6 Giorgos Korfiatis
708 7a08e179 Giorgos Korfiatis
709 3c22bad0 Giorgos Korfiatis
def check_conflicting_projects(application):
710 3c22bad0 Giorgos Korfiatis
    try:
711 3c22bad0 Giorgos Korfiatis
        project = get_project_by_id(application.chain)
712 3c22bad0 Giorgos Korfiatis
    except IOError:
713 3c22bad0 Giorgos Korfiatis
        project = None
714 8dcaa6ac Giorgos Korfiatis
715 3c22bad0 Giorgos Korfiatis
    new_project_name = application.name
716 8dcaa6ac Giorgos Korfiatis
    try:
717 3c22bad0 Giorgos Korfiatis
        q = Q(name=new_project_name) & ~Q(state=Project.TERMINATED)
718 3c22bad0 Giorgos Korfiatis
        conflicting_project = Project.objects.get(q)
719 3c22bad0 Giorgos Korfiatis
        if (conflicting_project != project):
720 3c22bad0 Giorgos Korfiatis
            m = (_("cannot approve: project with name '%s' "
721 3c22bad0 Giorgos Korfiatis
                   "already exists (id: %s)") % (
722 3c22bad0 Giorgos Korfiatis
                    new_project_name, conflicting_project.id))
723 3c22bad0 Giorgos Korfiatis
            raise PermissionDenied(m) # invalid argument
724 3c22bad0 Giorgos Korfiatis
    except Project.DoesNotExist:
725 3c22bad0 Giorgos Korfiatis
        pass
726 3c22bad0 Giorgos Korfiatis
727 3c22bad0 Giorgos Korfiatis
    return project
728 3c22bad0 Giorgos Korfiatis
729 3c22bad0 Giorgos Korfiatis
730 3c22bad0 Giorgos Korfiatis
def approve_application(app_id, request_user=None, reason=""):
731 3c22bad0 Giorgos Korfiatis
    get_chain_of_application_for_update(app_id)
732 3c22bad0 Giorgos Korfiatis
    application = get_application(app_id)
733 8dcaa6ac Giorgos Korfiatis
734 d07ce657 Giorgos Korfiatis
    checkAllowed(application, request_user, admin_only=True)
735 d07ce657 Giorgos Korfiatis
736 01bdbd17 Giorgos Korfiatis
    if not application.can_approve():
737 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_APPROVE %
738 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
739 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
740 01bdbd17 Giorgos Korfiatis
741 3c22bad0 Giorgos Korfiatis
    project = check_conflicting_projects(application)
742 3c22bad0 Giorgos Korfiatis
743 3c22bad0 Giorgos Korfiatis
    # Pre-lock members and owner together in order to impose an ordering
744 3c22bad0 Giorgos Korfiatis
    # on locking users
745 3c22bad0 Giorgos Korfiatis
    members = members_to_sync(project) if project is not None else []
746 3c22bad0 Giorgos Korfiatis
    uids_to_sync = [member.id for member in members]
747 3c22bad0 Giorgos Korfiatis
    owner = application.owner
748 3c22bad0 Giorgos Korfiatis
    uids_to_sync.append(owner.id)
749 3c22bad0 Giorgos Korfiatis
    get_users_for_update(uids_to_sync)
750 3c22bad0 Giorgos Korfiatis
751 3c22bad0 Giorgos Korfiatis
    qh_release_pending_app(owner, locked=True)
752 3c22bad0 Giorgos Korfiatis
    application.approve(reason)
753 3c22bad0 Giorgos Korfiatis
    qh_sync_locked_users(members)
754 f30f0170 Giorgos Korfiatis
    logger.info("%s has been approved." % (application.log_display))
755 a3eb3a95 Giorgos Korfiatis
    application_approve_notify(application)
756 eb9ff37a Sofia Papagiannaki
757 7a08e179 Giorgos Korfiatis
758 7eadc230 Giorgos Korfiatis
def check_expiration(execute=False):
759 7eadc230 Giorgos Korfiatis
    objects = Project.objects
760 7eadc230 Giorgos Korfiatis
    expired = objects.expired_projects()
761 7eadc230 Giorgos Korfiatis
    if execute:
762 7eadc230 Giorgos Korfiatis
        for project in expired:
763 7eadc230 Giorgos Korfiatis
            terminate(project.id)
764 7eadc230 Giorgos Korfiatis
765 7eadc230 Giorgos Korfiatis
    return [project.expiration_info() for project in expired]
766 7eadc230 Giorgos Korfiatis
767 7a08e179 Giorgos Korfiatis
768 d07ce657 Giorgos Korfiatis
def terminate(project_id, request_user=None):
769 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
770 3c22bad0 Giorgos Korfiatis
    project = get_project_by_id(project_id)
771 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
772 907f15db Giorgos Korfiatis
    checkAlive(project)
773 5b9e9530 Giorgos Korfiatis
774 5b9e9530 Giorgos Korfiatis
    project.terminate()
775 e336910f Giorgos Korfiatis
    qh_sync_project(project)
776 f30f0170 Giorgos Korfiatis
    logger.info("%s has been terminated." % (project))
777 570015d2 Giorgos Korfiatis
778 a3eb3a95 Giorgos Korfiatis
    project_termination_notify(project)
779 eb9ff37a Sofia Papagiannaki
780 7a08e179 Giorgos Korfiatis
781 d07ce657 Giorgos Korfiatis
def suspend(project_id, request_user=None):
782 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
783 3c22bad0 Giorgos Korfiatis
    project = get_project_by_id(project_id)
784 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
785 db99f198 Giorgos Korfiatis
    checkAlive(project)
786 db99f198 Giorgos Korfiatis
787 db99f198 Giorgos Korfiatis
    project.suspend()
788 e336910f Giorgos Korfiatis
    qh_sync_project(project)
789 f30f0170 Giorgos Korfiatis
    logger.info("%s has been suspended." % (project))
790 570015d2 Giorgos Korfiatis
791 a3eb3a95 Giorgos Korfiatis
    project_suspension_notify(project)
792 db99f198 Giorgos Korfiatis
793 7a08e179 Giorgos Korfiatis
794 d07ce657 Giorgos Korfiatis
def resume(project_id, request_user=None):
795 3c22bad0 Giorgos Korfiatis
    get_chain_for_update(project_id)
796 3c22bad0 Giorgos Korfiatis
    project = get_project_by_id(project_id)
797 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
798 db99f198 Giorgos Korfiatis
799 db99f198 Giorgos Korfiatis
    if not project.is_suspended:
800 db99f198 Giorgos Korfiatis
        m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.__dict__
801 db99f198 Giorgos Korfiatis
        raise PermissionDenied(m)
802 db99f198 Giorgos Korfiatis
803 db99f198 Giorgos Korfiatis
    project.resume()
804 e336910f Giorgos Korfiatis
    qh_sync_project(project)
805 f30f0170 Giorgos Korfiatis
    logger.info("%s has been unsuspended." % (project))
806 ff67242a Giorgos Korfiatis
807 7a08e179 Giorgos Korfiatis
808 ff67242a Giorgos Korfiatis
def get_by_chain_or_404(chain_id):
809 ff67242a Giorgos Korfiatis
    try:
810 ff67242a Giorgos Korfiatis
        project = Project.objects.get(id=chain_id)
811 ff67242a Giorgos Korfiatis
        application = project.application
812 ff67242a Giorgos Korfiatis
        return project, application
813 ff67242a Giorgos Korfiatis
    except:
814 ff67242a Giorgos Korfiatis
        application = ProjectApplication.objects.latest_of_chain(chain_id)
815 ff67242a Giorgos Korfiatis
        if application is None:
816 ff67242a Giorgos Korfiatis
            raise Http404
817 ff67242a Giorgos Korfiatis
        else:
818 ff67242a Giorgos Korfiatis
            return None, application
819 c7c0ec58 Giorgos Korfiatis
820 c7c0ec58 Giorgos Korfiatis
821 3f5851eb Giorgos Korfiatis
def _partition_by(f, l):
822 3f5851eb Giorgos Korfiatis
    d = {}
823 3f5851eb Giorgos Korfiatis
    for x in l:
824 3f5851eb Giorgos Korfiatis
        group = f(x)
825 3f5851eb Giorgos Korfiatis
        group_l = d.get(group, [])
826 3f5851eb Giorgos Korfiatis
        group_l.append(x)
827 3f5851eb Giorgos Korfiatis
        d[group] = group_l
828 3f5851eb Giorgos Korfiatis
    return d
829 3f5851eb Giorgos Korfiatis
830 3f5851eb Giorgos Korfiatis
831 3f5851eb Giorgos Korfiatis
def count_pending_app(users):
832 103086a4 Giorgos Korfiatis
    users = list(users)
833 3f5851eb Giorgos Korfiatis
    apps = ProjectApplication.objects.filter(state=ProjectApplication.PENDING,
834 3f5851eb Giorgos Korfiatis
                                             owner__in=users)
835 3f5851eb Giorgos Korfiatis
    apps_d = _partition_by(lambda a: a.owner.uuid, apps)
836 3f5851eb Giorgos Korfiatis
837 3f5851eb Giorgos Korfiatis
    usage = {}
838 3f5851eb Giorgos Korfiatis
    for user in users:
839 3f5851eb Giorgos Korfiatis
        uuid = user.uuid
840 3f5851eb Giorgos Korfiatis
        usage[uuid] = len(apps_d.get(uuid, []))
841 3f5851eb Giorgos Korfiatis
    return usage
842 3f5851eb Giorgos Korfiatis
843 3f5851eb Giorgos Korfiatis
844 3c22bad0 Giorgos Korfiatis
def get_pending_app_diff(user, precursor):
845 c7c0ec58 Giorgos Korfiatis
    if precursor is None:
846 9770ba6c Giorgos Korfiatis
        diff = 1
847 9770ba6c Giorgos Korfiatis
    else:
848 9770ba6c Giorgos Korfiatis
        chain = precursor.chain
849 9770ba6c Giorgos Korfiatis
        objs = ProjectApplication.objects
850 9770ba6c Giorgos Korfiatis
        q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
851 9770ba6c Giorgos Korfiatis
        count = q.count()
852 9770ba6c Giorgos Korfiatis
        diff = 1 - count
853 3c22bad0 Giorgos Korfiatis
    return diff
854 3c22bad0 Giorgos Korfiatis
855 3c22bad0 Giorgos Korfiatis
856 3c22bad0 Giorgos Korfiatis
def qh_add_pending_app(user, precursor=None, force=False):
857 3c22bad0 Giorgos Korfiatis
    user = AstakosUser.forupdate.get_for_update(id=user.id)
858 3c22bad0 Giorgos Korfiatis
    diff = get_pending_app_diff(user, precursor)
859 3c22bad0 Giorgos Korfiatis
    return register_pending_apps(user, diff, force)
860 3c22bad0 Giorgos Korfiatis
861 c7c0ec58 Giorgos Korfiatis
862 3c22bad0 Giorgos Korfiatis
def check_pending_app_quota(user, precursor=None):
863 3c22bad0 Giorgos Korfiatis
    diff = get_pending_app_diff(user, precursor)
864 3c22bad0 Giorgos Korfiatis
    quota = get_pending_app_quota(user)
865 3c22bad0 Giorgos Korfiatis
    limit = quota['limit']
866 3c22bad0 Giorgos Korfiatis
    usage = quota['usage']
867 3c22bad0 Giorgos Korfiatis
    if usage + diff > limit:
868 3c22bad0 Giorgos Korfiatis
        return False, limit
869 3c22bad0 Giorgos Korfiatis
    return True, None
870 c7c0ec58 Giorgos Korfiatis
871 c7c0ec58 Giorgos Korfiatis
872 3c22bad0 Giorgos Korfiatis
def qh_release_pending_app(user, locked=False):
873 3c22bad0 Giorgos Korfiatis
    if not locked:
874 3c22bad0 Giorgos Korfiatis
        user = AstakosUser.forupdate.get_for_update(id=user.id)
875 9e3af524 Giorgos Korfiatis
    register_pending_apps(user, -1)