Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 07ad7b1c

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