Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ d59f5608

History | View | Annotate | Download (28.7 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 e3ff6830 Georgios D. Tsoukalas
    url = join_urls(settings.BASE_HOST,
85 e3ff6830 Georgios D. Tsoukalas
                    user.get_activation_url(nxt=reverse('index')))
86 683cf244 Sofia Papagiannaki
    message = render_to_string(template_name, {
87 5ce3ce4f Sofia Papagiannaki
                               'user': user,
88 5ce3ce4f Sofia Papagiannaki
                               'url': url,
89 6c7af65c Georgios D. Tsoukalas
                               'baseurl': settings.BASE_URL,
90 8998f09a Sofia Papagiannaki
                               'site_name': settings.SITENAME,
91 8998f09a Sofia Papagiannaki
                               'support': settings.CONTACT_EMAIL})
92 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
93 cfb7dd4f Giorgos Korfiatis
    send_mail(_(astakos_messages.VERIFICATION_EMAIL_SUBJECT), message, sender,
94 cfb7dd4f Giorgos Korfiatis
              [user.email],
95 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
96 e7cb4085 Kostas Papadimitriou
    logger.info("Sent user verirfication email: %s", user.log_display)
97 683cf244 Sofia Papagiannaki
98 5ce3ce4f Sofia Papagiannaki
99 9a06d96f Olga Brani
def _send_admin_notification(template_name,
100 e7cb4085 Kostas Papadimitriou
                             context=None,
101 e7cb4085 Kostas Papadimitriou
                             user=None,
102 e7cb4085 Kostas Papadimitriou
                             msg="",
103 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
104 683cf244 Sofia Papagiannaki
    """
105 e7cb4085 Kostas Papadimitriou
    Send notification email to settings.HELPDESK + settings.MANAGERS +
106 e7cb4085 Kostas Papadimitriou
    settings.ADMINS.
107 683cf244 Sofia Papagiannaki
    """
108 e7cb4085 Kostas Papadimitriou
    if context is None:
109 e7cb4085 Kostas Papadimitriou
        context = {}
110 e7cb4085 Kostas Papadimitriou
    if not 'user' in context:
111 e7cb4085 Kostas Papadimitriou
        context['user'] = user
112 e7cb4085 Kostas Papadimitriou
113 e7cb4085 Kostas Papadimitriou
    message = render_to_string(template_name, context)
114 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
115 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
116 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
117 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, recipient_list,
118 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
119 e7cb4085 Kostas Papadimitriou
    if user:
120 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s) for user %s' % (msg,
121 e7cb4085 Kostas Papadimitriou
                                                            user.log_display)
122 8f5a3a06 Sofia Papagiannaki
    else:
123 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s)' % msg
124 683cf244 Sofia Papagiannaki
125 8998f09a Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg)
126 5ce3ce4f Sofia Papagiannaki
127 e7cb4085 Kostas Papadimitriou
128 e7cb4085 Kostas Papadimitriou
def send_account_pending_moderation_notification(
129 e7cb4085 Kostas Papadimitriou
        user,
130 e7cb4085 Kostas Papadimitriou
        template_name='im/account_pending_moderation_notification.txt'):
131 e7cb4085 Kostas Papadimitriou
    """
132 e7cb4085 Kostas Papadimitriou
    Notify admins that a new user has verified his email address and moderation
133 e7cb4085 Kostas Papadimitriou
    step is required to activate his account.
134 e7cb4085 Kostas Papadimitriou
    """
135 cfb7dd4f Giorgos Korfiatis
    subject = (_(astakos_messages.ACCOUNT_CREATION_SUBJECT) %
136 cfb7dd4f Giorgos Korfiatis
               {'user': user.email})
137 e7cb4085 Kostas Papadimitriou
    return _send_admin_notification(template_name, {}, subject=subject,
138 e7cb4085 Kostas Papadimitriou
                                    user=user, msg="account creation")
139 9a06d96f Olga Brani
140 9a06d96f Olga Brani
141 e7cb4085 Kostas Papadimitriou
def send_account_activated_notification(
142 e7cb4085 Kostas Papadimitriou
        user,
143 e7cb4085 Kostas Papadimitriou
        template_name='im/account_activated_notification.txt'):
144 a0be6a0c Sofia Papagiannaki
    """
145 e7cb4085 Kostas Papadimitriou
    Send email to settings.HELPDESK + settings.MANAGERES + settings.ADMINS
146 e7cb4085 Kostas Papadimitriou
    lists to notify that a new account has been accepted and activated.
147 a0be6a0c Sofia Papagiannaki
    """
148 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
149 3abf6c78 Sofia Papagiannaki
        template_name,
150 3abf6c78 Sofia Papagiannaki
        {'user': user}
151 3abf6c78 Sofia Papagiannaki
    )
152 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
153 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
154 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
155 cfb7dd4f Giorgos Korfiatis
    send_mail(_(astakos_messages.HELPDESK_NOTIFICATION_EMAIL_SUBJECT) %
156 cfb7dd4f Giorgos Korfiatis
              {'user': user.email},
157 e7cb4085 Kostas Papadimitriou
              message, sender, recipient_list, connection=get_connection())
158 d59f5608 Sofia Papagiannaki
    msg = 'Sent helpdesk admin notification for %s'
159 d59f5608 Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg, user.email)
160 a0be6a0c Sofia Papagiannaki
161 5ce3ce4f Sofia Papagiannaki
162 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
163 683cf244 Sofia Papagiannaki
    """
164 683cf244 Sofia Papagiannaki
    Send invitation email.
165 683cf244 Sofia Papagiannaki
    """
166 cfb7dd4f Giorgos Korfiatis
    subject = _(astakos_messages.INVITATION_EMAIL_SUBJECT)
167 8c8e318d Kostas Papadimitriou
    url = '%s?code=%d' % (join_urls(settings.BASE_HOST,
168 8c8e318d Kostas Papadimitriou
                                    reverse('index')), invitation.code)
169 aab4d540 Sofia Papagiannaki
    message = render_to_string(template_name, {
170 5ce3ce4f Sofia Papagiannaki
                               'invitation': invitation,
171 5ce3ce4f Sofia Papagiannaki
                               'url': url,
172 6c7af65c Georgios D. Tsoukalas
                               'baseurl': settings.BASE_URL,
173 8998f09a Sofia Papagiannaki
                               'site_name': settings.SITENAME,
174 8998f09a Sofia Papagiannaki
                               'support': settings.CONTACT_EMAIL})
175 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
176 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, [invitation.username],
177 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
178 d59f5608 Sofia Papagiannaki
    msg = 'Sent invitation %s'
179 d59f5608 Sofia Papagiannaki
    logger.log(settings.LOGGING_LEVEL, msg, invitation)
180 e7cb4085 Kostas Papadimitriou
    inviter_invitations = invitation.inviter.invitations
181 e7cb4085 Kostas Papadimitriou
    invitation.inviter.invitations = max(0, inviter_invitations - 1)
182 e7cb4085 Kostas Papadimitriou
    invitation.inviter.save()
183 683cf244 Sofia Papagiannaki
184 5ce3ce4f Sofia Papagiannaki
185 683cf244 Sofia Papagiannaki
def send_greeting(user, email_template_name='im/welcome_email.txt'):
186 683cf244 Sofia Papagiannaki
    """
187 e7cb4085 Kostas Papadimitriou
    Send welcome email to an accepted/activated user.
188 5ce3ce4f Sofia Papagiannaki

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