Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 3c22bad0

History | View | Annotate | Download (29.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 8f5a3a06 Sofia Papagiannaki
import socket
36 f36af44a Antony Chazapis
37 f36af44a Antony Chazapis
from django.utils.translation import ugettext as _
38 f9224cc0 Sofia Papagiannaki
from django.core.mail import send_mail, get_connection
39 f36af44a Antony Chazapis
from django.core.urlresolvers import reverse
40 49790d9d Sofia Papagiannaki
from django.template import Context, loader
41 bf0c6de5 Sofia Papagiannaki
from django.contrib.auth import (
42 bf0c6de5 Sofia Papagiannaki
    login as auth_login,
43 73fbaec4 Sofia Papagiannaki
    logout as auth_logout)
44 9a06d96f Olga Brani
from django.contrib.auth.models import AnonymousUser
45 73fbaec4 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
46 974ee6a6 Sofia Papagiannaki
from django.db import IntegrityError
47 3c22bad0 Giorgos Korfiatis
from django.db.models import Q
48 ff67242a Giorgos Korfiatis
from django.http import Http404
49 27e26a41 Sofia Papagiannaki
50 734107ef Kostas Papadimitriou
from synnefo_branding.utils import render_to_string
51 734107ef Kostas Papadimitriou
52 683cf244 Sofia Papagiannaki
from urllib import quote
53 8f5a3a06 Sofia Papagiannaki
from smtplib import SMTPException
54 751d24cf Sofia Papagiannaki
from datetime import datetime
55 111f3da6 Sofia Papagiannaki
from functools import wraps
56 f36af44a Antony Chazapis
57 d2c9adac Christos Stavrakakis
from synnefo.lib import join_urls
58 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
59 31bc3a62 Kostas Papadimitriou
    CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
60 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
61 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
62 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
64 2e7924de Giorgos Korfiatis
    )
65 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
66 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
67 e30537f1 Sofia Papagiannaki
    AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project,
68 3c22bad0 Giorgos Korfiatis
    UserSetting, Chain, new_chain)
69 3c22bad0 Giorgos Korfiatis
from astakos.im.quotas import (qh_sync_user, get_pending_app_quota,
70 3c22bad0 Giorgos Korfiatis
                               register_pending_apps, qh_sync_project,
71 3c22bad0 Giorgos Korfiatis
                               qh_sync_locked_users, get_users_for_update,
72 3c22bad0 Giorgos Korfiatis
                               members_to_sync)
73 a3eb3a95 Giorgos Korfiatis
from astakos.im.project_notif import (
74 466cc12c Giorgos Korfiatis
    membership_change_notify, membership_enroll_notify,
75 bb6a4465 Giorgos Korfiatis
    membership_request_notify, membership_leave_request_notify,
76 a3eb3a95 Giorgos Korfiatis
    application_submit_notify, application_approve_notify,
77 19eb3ee6 Giorgos Korfiatis
    application_deny_notify,
78 a3eb3a95 Giorgos Korfiatis
    project_termination_notify, project_suspension_notify)
79 0a7a4104 Kostas Papadimitriou
from astakos.im import settings
80 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
81 f36af44a Antony Chazapis
82 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
83 f36af44a Antony Chazapis
84 5ce3ce4f Sofia Papagiannaki
85 bf0c6de5 Sofia Papagiannaki
def login(request, user):
86 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
87 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
88 c3c2212a Sofia Papagiannaki
    SessionCatalog(
89 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
90 c3c2212a Sofia Papagiannaki
        user=user
91 c3c2212a Sofia Papagiannaki
    ).save()
92 5df4c364 Kostas Papadimitriou
    logger.info('%s logged in.', user.log_display)
93 5df4c364 Kostas Papadimitriou
94 bf0c6de5 Sofia Papagiannaki
95 5df4c364 Kostas Papadimitriou
def logout(request, *args, **kwargs):
96 5df4c364 Kostas Papadimitriou
    user = request.user
97 5df4c364 Kostas Papadimitriou
    auth_logout(request, *args, **kwargs)
98 5df4c364 Kostas Papadimitriou
    logger.info('%s logged out.', user.log_display)
99 111f3da6 Sofia Papagiannaki
100 5ce3ce4f Sofia Papagiannaki
101 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
102 f36af44a Antony Chazapis
    """
103 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
104 f36af44a Antony Chazapis
    """
105 e7cb4085 Kostas Papadimitriou
    url = join_urls(BASEURL, user.get_activation_url(nxt=reverse('index')))
106 683cf244 Sofia Papagiannaki
    message = render_to_string(template_name, {
107 5ce3ce4f Sofia Papagiannaki
                               'user': user,
108 5ce3ce4f Sofia Papagiannaki
                               'url': url,
109 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
110 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
111 31bc3a62 Kostas Papadimitriou
                               'support': CONTACT_EMAIL})
112 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
113 e7cb4085 Kostas Papadimitriou
    send_mail(_(VERIFICATION_EMAIL_SUBJECT), message, sender, [user.email],
114 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
115 e7cb4085 Kostas Papadimitriou
    logger.info("Sent user verirfication email: %s", user.log_display)
116 683cf244 Sofia Papagiannaki
117 5ce3ce4f Sofia Papagiannaki
118 9a06d96f Olga Brani
def _send_admin_notification(template_name,
119 e7cb4085 Kostas Papadimitriou
                             context=None,
120 e7cb4085 Kostas Papadimitriou
                             user=None,
121 e7cb4085 Kostas Papadimitriou
                             msg="",
122 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
123 683cf244 Sofia Papagiannaki
    """
124 e7cb4085 Kostas Papadimitriou
    Send notification email to settings.HELPDESK + settings.MANAGERS +
125 e7cb4085 Kostas Papadimitriou
    settings.ADMINS.
126 683cf244 Sofia Papagiannaki
    """
127 e7cb4085 Kostas Papadimitriou
    if context is None:
128 e7cb4085 Kostas Papadimitriou
        context = {}
129 e7cb4085 Kostas Papadimitriou
    if not 'user' in context:
130 e7cb4085 Kostas Papadimitriou
        context['user'] = user
131 e7cb4085 Kostas Papadimitriou
132 e7cb4085 Kostas Papadimitriou
    message = render_to_string(template_name, context)
133 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
134 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
135 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
136 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, recipient_list,
137 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
138 e7cb4085 Kostas Papadimitriou
    if user:
139 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s) for user %s' % (msg,
140 e7cb4085 Kostas Papadimitriou
                                                            user.log_display)
141 8f5a3a06 Sofia Papagiannaki
    else:
142 e7cb4085 Kostas Papadimitriou
        msg = 'Sent admin notification (%s)' % msg
143 683cf244 Sofia Papagiannaki
144 e7cb4085 Kostas Papadimitriou
    logger.log(LOGGING_LEVEL, msg)
145 5ce3ce4f Sofia Papagiannaki
146 e7cb4085 Kostas Papadimitriou
147 e7cb4085 Kostas Papadimitriou
def send_account_pending_moderation_notification(
148 e7cb4085 Kostas Papadimitriou
        user,
149 e7cb4085 Kostas Papadimitriou
        template_name='im/account_pending_moderation_notification.txt'):
150 e7cb4085 Kostas Papadimitriou
    """
151 e7cb4085 Kostas Papadimitriou
    Notify admins that a new user has verified his email address and moderation
152 e7cb4085 Kostas Papadimitriou
    step is required to activate his account.
153 e7cb4085 Kostas Papadimitriou
    """
154 5d5ce247 Kostas Papadimitriou
    subject = _(ACCOUNT_CREATION_SUBJECT) % {'user': user.email}
155 e7cb4085 Kostas Papadimitriou
    return _send_admin_notification(template_name, {}, subject=subject,
156 e7cb4085 Kostas Papadimitriou
                                    user=user, msg="account creation")
157 9a06d96f Olga Brani
158 9a06d96f Olga Brani
159 e7cb4085 Kostas Papadimitriou
def send_account_activated_notification(
160 e7cb4085 Kostas Papadimitriou
        user,
161 e7cb4085 Kostas Papadimitriou
        template_name='im/account_activated_notification.txt'):
162 a0be6a0c Sofia Papagiannaki
    """
163 e7cb4085 Kostas Papadimitriou
    Send email to settings.HELPDESK + settings.MANAGERES + settings.ADMINS
164 e7cb4085 Kostas Papadimitriou
    lists to notify that a new account has been accepted and activated.
165 a0be6a0c Sofia Papagiannaki
    """
166 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
167 3abf6c78 Sofia Papagiannaki
        template_name,
168 3abf6c78 Sofia Papagiannaki
        {'user': user}
169 3abf6c78 Sofia Papagiannaki
    )
170 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
171 e7cb4085 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK +
172 e7cb4085 Kostas Papadimitriou
                      settings.MANAGERS + settings.ADMINS]
173 e7cb4085 Kostas Papadimitriou
    send_mail(_(HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email},
174 e7cb4085 Kostas Papadimitriou
              message, sender, recipient_list, connection=get_connection())
175 e7cb4085 Kostas Papadimitriou
    msg = 'Sent helpdesk admin notification for %s' % user.email
176 e7cb4085 Kostas Papadimitriou
    logger.log(LOGGING_LEVEL, msg)
177 a0be6a0c Sofia Papagiannaki
178 5ce3ce4f Sofia Papagiannaki
179 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
180 683cf244 Sofia Papagiannaki
    """
181 683cf244 Sofia Papagiannaki
    Send invitation email.
182 683cf244 Sofia Papagiannaki
    """
183 1fcf4a99 Kostas Papadimitriou
    subject = _(INVITATION_EMAIL_SUBJECT)
184 d2c9adac Christos Stavrakakis
    url = '%s?code=%d' % (join_urls(BASEURL, reverse('index')), invitation.code)
185 aab4d540 Sofia Papagiannaki
    message = render_to_string(template_name, {
186 5ce3ce4f Sofia Papagiannaki
                               'invitation': invitation,
187 5ce3ce4f Sofia Papagiannaki
                               'url': url,
188 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
189 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
190 31bc3a62 Kostas Papadimitriou
                               'support': CONTACT_EMAIL})
191 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
192 e7cb4085 Kostas Papadimitriou
    send_mail(subject, message, sender, [invitation.username],
193 e7cb4085 Kostas Papadimitriou
              connection=get_connection())
194 e7cb4085 Kostas Papadimitriou
    msg = 'Sent invitation %s' % invitation
195 e7cb4085 Kostas Papadimitriou
    logger.log(LOGGING_LEVEL, msg)
196 e7cb4085 Kostas Papadimitriou
    inviter_invitations = invitation.inviter.invitations
197 e7cb4085 Kostas Papadimitriou
    invitation.inviter.invitations = max(0, inviter_invitations - 1)
198 e7cb4085 Kostas Papadimitriou
    invitation.inviter.save()
199 683cf244 Sofia Papagiannaki
200 5ce3ce4f Sofia Papagiannaki
201 683cf244 Sofia Papagiannaki
def send_greeting(user, email_template_name='im/welcome_email.txt'):
202 683cf244 Sofia Papagiannaki
    """
203 e7cb4085 Kostas Papadimitriou
    Send welcome email to an accepted/activated user.
204 5ce3ce4f Sofia Papagiannaki

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