Ejemplo n.º 1
0
def acs(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    auth.process_response()

    data = {
        'errors': auth.get_errors(),
        'not_auth_warn': not auth.is_authenticated()
    }

    if not data['errors']:
        request.session['samlUserdata'] = auth.get_attributes()
        request.session['samlNameId'] = auth.get_nameid()
        request.session['samlSessionIndex'] = auth.get_session_index()

        user = authenticate(saml_authentication=auth)
        if user is None:
            data['errors'] = ['Authentication backend failed.']
        elif not user.is_active:
            data['errors'] = ['User is not active. TODO: logout at idp?']
        else:
            login(request, user)
            if 'RelayState' in req['post_data'] and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
            return HttpResponseRedirect(OneLogin_Saml2_Utils.get_self_url(req) + '/profile')

    return draw_page(request, data)
Ejemplo n.º 2
0
    def testGetSelfURL(self):
        """
        Tests the get_self_url method of the OneLogin_Saml2_Utils
        """
        request_data = {
            'http_host': 'example.com'
        }
        url = OneLogin_Saml2_Utils.get_self_url_host(request_data)
        self.assertEqual(url, OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = ''
        self.assertEqual(url, OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/'
        self.assertEqual(url + '/', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = 'index.html'
        self.assertEqual(url + 'index.html', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '?index.html'
        self.assertEqual(url + '?index.html', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/index.html'
        self.assertEqual(url + '/index.html', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/index.html?testing'
        self.assertEqual(url + '/index.html?testing', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/test/index.html?testing'
        self.assertEqual(url + '/test/index.html?testing', OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = 'https://example.com/testing'
        self.assertEqual(url + '/testing', OneLogin_Saml2_Utils.get_self_url(request_data))
Ejemplo n.º 3
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        return HttpResponseRedirect(auth.login())
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        name_id = None
        session_index = None
        if 'samlNameId' in request.session:
            name_id = request.session['samlNameId']
        if 'samlSessionIndex' in request.session:
            session_index = request.session['samlSessionIndex']

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in req['get_data']:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if not errors:
            request.session['samlUserdata'] = auth.get_attributes()
            request.session['samlNameId'] = auth.get_nameid()
            request.session['samlSessionIndex'] = auth.get_session_index()
            if 'RelayState' in req['post_data'] and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
    elif 'sls' in req['get_data']:
        dscb = lambda: request.session.flush()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in request.session:
        paint_logout = True
        if len(request.session['samlUserdata']) > 0:
            attributes = request.session['samlUserdata'].items()

    return render_to_response('index.html',
                              {'errors': errors,
                               'not_auth_warn': not_auth_warn,
                               'success_slo': success_slo,
                               'attributes': attributes,
                               'paint_logout': paint_logout},
                              context_instance=RequestContext(request))
async def acs(request):
    session = await get_session(request)
    post = await request.post()
    req = await prepare_saml_req(request)
    auth = init_saml_auth(req, request.app['saml_settings'])

    request_id = None
    if 'AuthNRequestID' in session:
        request_id = session['AuthNRequestID']

    auth.process_response(request_id=request_id)
    errors = auth.get_errors()
    not_auth_warn = not auth.is_authenticated()
    if len(errors) == 0:
        if 'AuthNRequestID' in session:
            del session['AuthNRequestID']
        session['samlUserdata'] = auth.get_attributes()
        session['samlNameIdFormat'] = auth.get_nameid_format()
        session['samlNameIdNameQualifier'] = auth.get_nameid_nq()
        session['samlNameIdSPNameQualifier'] = auth.get_nameid_spnq()
        session['samlSessionIndex'] = auth.get_session_index()
        self_url = OneLogin_Saml2_Utils.get_self_url(req)
        if 'RelayState' in post and self_url != post['RelayState']:
            raise HTTPFound(auth.redirect_to(post['RelayState']))
    elif auth.get_settings().is_debug_active():
        raise HTTPInternalServerError(text=auth.get_last_error_reason())
Ejemplo n.º 5
0
def index():
    req = prepare_bottle_request(request)
    auth = init_saml_auth(req)
    paint_logout = False
    attributes = False

    session = request.environ['beaker.session']

    auth.process_response()
    errors = auth.get_errors()
    not_auth_warn = not auth.is_authenticated()
    if len(errors) == 0:
        session['samlUserdata'] = auth.get_attributes()
        session['samlNameId'] = auth.get_nameid()
        session['samlSessionIndex'] = auth.get_session_index()
        self_url = OneLogin_Saml2_Utils.get_self_url(req)
        if 'RelayState' in request.forms and self_url != request.forms['RelayState']:
            return redirect(request.forms['RelayState'])

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return {
        'errors':errors,
        'not_auth_warn':not_auth_warn,
        'attributes':attributes,
        'paint_logout':paint_logout
    }
Ejemplo n.º 6
0
def index():
    req = prepare_bottle_request(request)
    auth = init_saml_auth(req)
    paint_logout = False
    attributes = False

    session = request.environ['beaker.session']

    auth.process_response()
    errors = auth.get_errors()
    not_auth_warn = not auth.is_authenticated()
    if len(errors) == 0:
        session['samlUserdata'] = auth.get_attributes()
        session['samlNameId'] = auth.get_nameid()
        session['samlSessionIndex'] = auth.get_session_index()
        self_url = OneLogin_Saml2_Utils.get_self_url(req)
        if 'RelayState' in request.forms and self_url != request.forms[
                'RelayState']:
            return redirect(request.forms['RelayState'])

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return {
        'errors': errors,
        'not_auth_warn': not_auth_warn,
        'attributes': attributes,
        'paint_logout': paint_logout
    }
Ejemplo n.º 7
0
def saml_login(request):
    attributes = None
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    if 'acs' in req['get_data']:
        # IDP initiated
        request_id = None

        if 'AuthNRequestID' in request.session:
            request_id = request.session['AuthNRequestID']

        auth.process_response(request_id=request_id)
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()

        if not errors:
            if 'AuthNRequestID' in request.session:
                del request.session['AuthNRequestID']

            request.session['samlUserdata'] = auth.get_attributes()
            request.session['samlNameId'] = auth.get_nameid()
            request.session['samlSessionIndex'] = auth.get_session_index()
            attributes = request.session['samlUserdata'].items()
            user = authenticate(request=request)
            login(request, user)
            if hasattr(settings, 'SAML_REDIRECT'):
                return HttpResponseRedirect(settings.SAML_REDIRECT)
            elif 'RelayState' in req['post_data'] and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
            else:
                return HttpResponseRedirect(OneLogin_Saml2_Utils.get_self_url(req))
        else:
            raise SAMLError('ERRORS FOUND IN SAML REQUEST: %s' % errors)
    elif 'provider' in req['get_data']:
        # SP Initiated
        if hasattr(settings, 'SAML_REDIRECT'):
            return HttpResponseRedirect(auth.login(return_to=settings.SAML_REDIRECT))
        elif REDIRECT_FIELD_NAME in req['get_data']:
            return HttpResponseRedirect(auth.login(return_to=req['get_data'][REDIRECT_FIELD_NAME]))
        elif 'RelayState' in req['post_data']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
        else:
            redir = OneLogin_Saml2_Utils.get_self_url(req)
            return HttpResponseRedirect(auth.login(return_to=redir))
    else:
        return HttpResponseRedirect(auth.login())
Ejemplo n.º 8
0
    def get(self):
        req = prepare_tornado_request(self.request)
        auth = init_saml_auth(req)
        error_reason = None
        errors = []
        not_auth_warn = False
        success_slo = False
        attributes = False
        paint_logout = False

        if 'sso' in req['get_data']:
            print('-sso-')
            return self.redirect(auth.login())
        elif 'sso2' in req['get_data']:
            print('-sso2-')
            return_to = '%s/attrs' % self.request.host
            return self.redirect(auth.login(return_to))
        elif 'slo' in req['get_data']:
            print('-slo-')
            name_id = None
            session_index = None
            if 'samlNameId' in session:
                name_id = session['samlNameId']
            if 'samlSessionIndex' in session:
                session_index = session['samlSessionIndex']
            return self.redirect(auth.logout(name_id=name_id, session_index=session_index))
        elif 'acs' in req['get_data']:
            print('-acs-')
            auth.process_response()
            errors = auth.get_errors()
            not_auth_warn = not auth.is_authenticated()
            if len(errors) == 0:
                session['samlUserdata'] = auth.get_attributes()
                session['samlNameId'] = auth.get_nameid()
                session['samlSessionIndex'] = auth.get_session_index()
                self_url = OneLogin_Saml2_Utils.get_self_url(req)
                if 'RelayState' in self.request.arguments and self_url != self.request.arguments['RelayState'][0].decode('utf-8'):
                    return self.redirect(auth.redirect_to(self.request.arguments['RelayState'][0].decode('utf-8')))
                elif auth.get_settings().is_debug_active():
                    error_reason = auth.get_last_error_reason()
        elif 'sls' in req['get_data']:
            print('-sls-')
            dscb = lambda: session.clear()  # clear out the session
            url = auth.process_slo(delete_session_cb=dscb)
            errors = auth.get_errors()
            if len(errors) == 0:
                if url is not None:
                    return self.redirect(url)
                else:
                    success_slo = True
            elif auth.get_settings().is_debug_active():
                error_reason = auth.get_last_error_reason()
        if 'samlUserdata' in session:
            print('-samlUserdata-')
            paint_logout = True
            if len(session['samlUserdata']) > 0:
                attributes = session['samlUserdata'].items()
                print("ATTRIBUTES", attributes)
        self.render('index.html', errors=errors, error_reason=error_reason, not_auth_warn=not_auth_warn, success_slo=success_slo, attributes=attributes, paint_logout=paint_logout)
Ejemplo n.º 9
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        return HttpResponseRedirect(auth.login())
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        return HttpResponseRedirect(auth.logout())
    elif 'acs' in req['get_data']:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if not errors:
            request.session['samlUserdata'] = auth.get_attributes()
            if 'RelayState' in req['post_data'] and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
    elif 'sls' in req['get_data']:
        dscb = lambda: request.session.flush()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in request.session:
        paint_logout = True
        if len(request.session['samlUserdata']) > 0:
            attributes = request.session['samlUserdata'].items()

    return render_to_response('index.html',
                              {'errors': errors,
                               'not_auth_warn': not_auth_warn,
                               'success_slo': success_slo,
                               'attributes': attributes,
                               'paint_logout': paint_logout},
                              context_instance=RequestContext(request))
Ejemplo n.º 10
0
def saml_login():
    if not current_app.config.get('SAML_ENABLED'):
        abort(400)
    req = saml.prepare_flask_request(request)
    auth = saml.init_saml_auth(req)
    redirect_url = OneLogin_Saml2_Utils.get_self_url(req) + url_for(
        'index.saml_authorized')
    return redirect(auth.login(return_to=redirect_url))
Ejemplo n.º 11
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    error_reason = None
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        return HttpResponseRedirect(auth.login())
        # If AuthNRequest ID need to be stored in order to later validate it, do instead
        # sso_built_url = auth.login()
        # request.session['AuthNRequestID'] = auth.get_last_request_id()
        # return HttpResponseRedirect(sso_built_url)
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        name_id = session_index = name_id_format = name_id_nq = name_id_spnq = None
        if 'samlNameId' in request.session:
            name_id = request.session['samlNameId']
        if 'samlSessionIndex' in request.session:
            session_index = request.session['samlSessionIndex']
        if 'samlNameIdFormat' in request.session:
            name_id_format = request.session['samlNameIdFormat']
        if 'samlNameIdNameQualifier' in request.session:
            name_id_nq = request.session['samlNameIdNameQualifier']
        if 'samlNameIdSPNameQualifier' in request.session:
            name_id_spnq = request.session['samlNameIdSPNameQualifier']

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index, nq=name_id_nq, name_id_format=name_id_format, spnq=name_id_spnq))
        # If LogoutRequest ID need to be stored in order to later validate it, do instead
        # slo_built_url = auth.logout(name_id=name_id, session_index=session_index)
        # request.session['LogoutRequestID'] = auth.get_last_request_id()
        # return HttpResponseRedirect(slo_built_url)

    elif 'sls' in req['get_data']:
        request_id = None
        if 'LogoutRequestID' in request.session:
            request_id = request.session['LogoutRequestID']
        dscb = lambda: request.session.flush()
        url = auth.process_slo(request_id=request_id, delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in request.session:
        paint_logout = True
        if len(request.session['samlUserdata']) > 0:
            attributes = request.session['samlUserdata'].items()

    return render(request, 'index.html', {'errors': errors, 'error_reason': error_reason, 'not_auth_warn': not_auth_warn, 'success_slo': success_slo,
                                          'attributes': attributes, 'paint_logout': paint_logout})
Ejemplo n.º 12
0
def index():
    req = prepare_flask_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in request.args:
        return redirect(auth.login())
    elif 'sso2' in request.args:
        return_to = '%sattrs/' % request.host_url
        return redirect(auth.login(return_to))
    elif 'slo' in request.args:
        name_id = None
        session_index = None
        if 'samlNameId' in session:
            name_id = session['samlNameId']
        if 'samlSessionIndex' in session:
            session_index = session['samlSessionIndex']

        return redirect(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in request.args:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            session['samlUserdata'] = auth.get_attributes()
            session['samlNameId'] = auth.get_nameid()
            session['samlSessionIndex'] = auth.get_session_index()
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            #print urllib.unquote(request.form['RelayState']).decode('utf8')
            if 'RelayState' in request.form and self_url != request.form['RelayState']:
                return redirect(auth.redirect_to(urllib.unquote(request.form['RelayState']).decode('utf8')))
    elif 'sls' in request.args:
        dscb = lambda: session.clear()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return redirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return render_template(
        'loginSSO.html',
        errors=errors,
        not_auth_warn=not_auth_warn,
        success_slo=success_slo,
        attributes=attributes,
        paint_logout=paint_logout
    )
Ejemplo n.º 13
0
    def post(self):
        if "onelogin" not in current_app.config.get("ACTIVE_PROVIDERS"):
            return "Onelogin is not enabled in the config.  See the ACTIVE_PROVIDERS section.", 404
        auth = OneLogin_Saml2_Auth(self.req,
                                   current_app.config.get("ONELOGIN_SETTINGS"))

        self.reqparse.add_argument('return_to',
                                   required=False,
                                   default=current_app.config.get('WEB_PATH'))
        self.reqparse.add_argument('acs', required=False)
        self.reqparse.add_argument('sls', required=False)

        args = self.reqparse.parse_args()

        return_to = args['return_to']

        if args['acs'] != None:
            # valids the SAML response and checks if successfully authenticated
            if self._consumer(auth):
                email = auth.get_attribute(
                    current_app.config.get("ONELOGIN_EMAIL_FIELD"))[0]
                user = User.query.filter(User.email == email).first()

                # if we get an sso user create them an account
                if not user:
                    user = User(
                        email=email,
                        active=True,
                        role=current_app.config.get('ONELOGIN_DEFAULT_ROLE')
                        # profile_picture=profile.get('thumbnailPhotoUrl')
                    )
                    db.session.add(user)
                    db.session.commit()
                    db.session.refresh(user)

                # Tell Flask-Principal the identity changed
                identity_changed.send(current_app._get_current_object(),
                                      identity=Identity(user.id))
                login_user(user)
                db.session.commit()
                db.session.refresh(user)

                self_url = OneLogin_Saml2_Utils.get_self_url(self.req)
                if 'RelayState' in request.form and self_url != request.form[
                        'RelayState']:
                    return redirect(auth.redirect_to(
                        request.form['RelayState']),
                                    code=302)
                else:
                    return redirect(current_app.config.get('BASE_URL'),
                                    code=302)
            else:
                return dict(message='OneLogin authentication failed.'), 403
        elif args['sls'] != None:
            return dict(message='OneLogin SLS not implemented yet.'), 405
        else:
            return redirect(auth.login(return_to=return_to))
Ejemplo n.º 14
0
def index():
    req = prepare_flask_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if "sso" in request.args:
        return redirect(auth.login())
    elif "sso2" in request.args:
        return_to = "%sattrs/" % request.host_url
        return redirect(auth.login(return_to))
    elif "slo" in request.args:
        name_id = None
        session_index = None
        if "samlNameId" in session:
            name_id = session["samlNameId"]
        if "samlSessionIndex" in session:
            session_index = session["samlSessionIndex"]

        return redirect(auth.logout(name_id=name_id, session_index=session_index))
    elif "acs" in request.args:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            session["samlUserdata"] = auth.get_attributes()
            session["samlNameId"] = auth.get_nameid()
            session["samlSessionIndex"] = auth.get_session_index()
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if "RelayState" in request.form and self_url != request.form["RelayState"]:
                return redirect(auth.redirect_to(request.form["RelayState"]))
    elif "sls" in request.args:
        dscb = lambda: session.clear()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return redirect(url)
            else:
                success_slo = True

    if "samlUserdata" in session:
        paint_logout = True
        if len(session["samlUserdata"]) > 0:
            attributes = session["samlUserdata"].items()

    return render_template(
        "index.html",
        errors=errors,
        not_auth_warn=not_auth_warn,
        success_slo=success_slo,
        attributes=attributes,
        paint_logout=paint_logout,
    )
Ejemplo n.º 15
0
def index():
    req = prepare_flask_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in request.args:
        return redirect(auth.login())
    elif 'sso2' in request.args:
        return_to = '%sattrs/' % request.host_url
        return redirect(auth.login(return_to))
    elif 'slo' in request.args:
        name_id = None
        session_index = None
        if 'samlNameId' in session:
            name_id = session['samlNameId']
        if 'samlSessionIndex' in session:
            session_index = session['samlSessionIndex']

        return redirect(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in request.args:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            session['samlUserdata'] = auth.get_attributes()
            session['samlNameId'] = auth.get_nameid()
            session['samlSessionIndex'] = auth.get_session_index()
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in request.form and self_url != request.form['RelayState']:
                return redirect(auth.redirect_to(request.form['RelayState']))
    elif 'sls' in request.args:
        dscb = lambda: session.clear()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return redirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return render_template(
        'index.html',
        errors=errors,
        not_auth_warn=not_auth_warn,
        success_slo=success_slo,
        attributes=attributes,
        paint_logout=paint_logout
    )
Ejemplo n.º 16
0
def get_relaystate_redirect_url(saml_info, fallback_url):
    saml_auth = saml_info.auth

    if 'RelayState' in request.form and \
            OneLogin_Saml2_Utils.get_self_url(saml_info.req) \
            != request.form['RelayState']:
        return saml_auth.redirect_to(request.form['RelayState'])

    return fallback_url
Ejemplo n.º 17
0
def saml():
    if "saml" not in syllabus.get_config()['authentication_methods']:
        abort(404)
    req = prepare_request(request)
    req['request_uri'] = request.path  # hack to ensure to have the correct path and to avoid RelayState loops
    auth = init_saml_auth(req, saml_config)

    # if 'sso' in request.args:
    #     return
    if request.method == "GET":
        return redirect(auth.login())
    else:
        auth.process_response()
        errors = auth.get_errors()
        # Try and check if IdP is using several signature certificates
        # This is a limitation of python3-saml
        for cert in saml_config["idp"].get("additionalX509certs", []):
            if auth.get_last_error_reason(
            ) == "Signature validation failed. SAML Response rejected":
                import copy
                # Change used IdP certificate
                new_settings = copy.deepcopy(saml_config)
                new_settings["idp"]["x509cert"] = cert
                # Retry processing response
                auth = init_saml_auth(req, new_settings)
                auth.process_response()
                errors = auth.get_errors()
        if len(errors) == 0:
            attrs = auth.get_attributes()
            # session['samlNameId'] = auth.get_nameid()
            # session['samlSessionIndex'] = auth.get_session_index()

            username = attrs[saml_config['sp']['attrs']['username']][0]
            realname = attrs[saml_config['sp']['attrs']['realname']][0]
            email = attrs[saml_config['sp']['attrs']['email']][0]

            user = User.query.filter(User.email == email).first()

            if user is None:  # The user does not exist in our DB
                user = User(name=username,
                            full_name=realname,
                            email=email,
                            hash_password=None,
                            change_password_url=None)
                db_session.add(user)
                db_session.commit()

            session["user"] = user.to_dict()
            session["user"].update({"login_method": "saml"})

            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in request.form and self_url != request.form[
                    'RelayState']:
                return redirect(auth.redirect_to(request.form['RelayState']))

    return seeother("/")
Ejemplo n.º 18
0
    def post(self):
        """
            Receive the POST binding request from IDP.

             - process the request
            - extract user attributes
            - create a new User if it doesn't exist
            - fill in the session
            - redirect to RelayState or /
        """

        # SAML boiler plate code
        req = prepare_request()
        settings = build_settings(self.config['saml2'])
        # this is the object to interact with the shibboleth parameters
        auth = init_saml_auth(req, settings)
        errors = []
        not_auth_warn = False
        success_slo = False

        input_data = flask.request.form

        if 'acs' in flask.request.args:
            auth.process_response()  # decrypt and extract informations
            errors = auth.get_errors()
            not_auth_warn = not auth.is_authenticated()

            if len(errors) == 0:
                attrs = auth.get_attributes(
                )  # get attributes returned by the shibboleth idp

                for key in attrs.keys():
                    print("(" + key + ", " + str(attrs[key]) + ")")

                username = attrs[settings['sp']['attrs']['username']][0]
                realname = attrs[settings['sp']['attrs']['realname']][0]
                email = attrs[settings['sp']['attrs']['email']][0]

                u = User.selectBy(email=email).getOne(None)
                if not u:  # The user does not exist in our DB
                    u = User(username=username,
                             email=email,
                             fullname=realname,
                             super_admin=False,
                             disabled=True)

                self.session['user'] = u.to_dictionary(
                    ['id', 'fullname', 'username', 'email'])

                self_url = OneLogin_Saml2_Utils.get_self_url(req)
                if 'RelayState' in input_data and self_url != input_data[
                        'RelayState']:
                    return resp.seeother(
                        auth.redirect_to(input_data['RelayState']))

        return resp.seeother('/')
Ejemplo n.º 19
0
    def redirect(self):
        auth_object = self._create_auth_object()
        request_data = self.get_request_data()
        self_url = OneLogin_Saml2_Utils.get_self_url(request_data)
        redirect_path = "/"

        if "RelayState" in request.form and self_url != request.form["RelayState"]:
            redirect_path = request.form["RelayState"]

        return auth_object.redirect_to(redirect_path)
Ejemplo n.º 20
0
def acs(request):
    attributes = None
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    # IDP initiated
    request_id = None

    if 'AuthNRequestID' in request.session:
        request_id = request.session['AuthNRequestID']

    auth.process_response(request_id=request_id)
    errors = auth.get_errors()
    not_auth_warn = not auth.is_authenticated()

    if not errors:
        if 'AuthNRequestID' in request.session:
            del request.session['AuthNRequestID']

        request.session['samlUserdata'] = auth.get_attributes()
        request.session['samlNameId'] = auth.get_nameid()
        request.session['samlSessionIndex'] = auth.get_session_index()
        attributes = request.session['samlUserdata'].items()
        user = authenticate(request=request)
        if user is None:
            if hasattr(settings, 'SAML_FAIL_REDIRECT'):
                return HttpResponseRedirect(settings.SAML_FAIL_REDIRECT)
            raise SAMLError('FAILED TO AUTHENTICATE SAML USER WITH BACKEND')
        login(request, user)
        if hasattr(settings, 'SAML_REDIRECT'):
            return HttpResponseRedirect(settings.SAML_REDIRECT)
        elif 'RelayState' in req[
                'post_data'] and OneLogin_Saml2_Utils.get_self_url(
                    req) != req['post_data']['RelayState']:
            return HttpResponseRedirect(
                auth.redirect_to(req['post_data']['RelayState']))
        else:
            return HttpResponseRedirect(OneLogin_Saml2_Utils.get_self_url(req))
    else:
        raise SAMLError('ERRORS FOUND IN SAML REQUEST: %s' % errors)
Ejemplo n.º 21
0
    def POST(self):
        req = prepare_request()
        input_data = web.input()

        auth = OneLogin_Saml2_Auth(req, settings)
        auth.process_response()
        errors = auth.get_errors()

        # Try and check if IdP is using several signature certificates
        # This is a limitation of python3-saml
        for cert in settings["idp"].get("additionalX509certs", []):
            if auth.get_last_error_reason(
            ) == "Signature validation failed. SAML Response rejected":
                # Change used IdP certificate
                logging.getLogger('inginious.webapp.plugin.auth.saml').debug(
                    "Trying another certificate...")
                new_settings = copy.deepcopy(settings)
                new_settings["idp"]["x509cert"] = cert
                # Retry processing response
                auth = OneLogin_Saml2_Auth(req, new_settings)
                auth.process_response()
                errors = auth.get_errors()

        if len(errors) == 0 and "attributes" in settings:
            attrs = auth.get_attributes()

            username = attrs[settings["attributes"]["uid"]][0]
            realname = attrs[settings["attributes"]["cn"]][0]
            email = attrs[settings["attributes"]["email"]][0]

            # Initialize session in user manager and update cache
            self.user_manager._set_session(username, realname, email)
            self.database.user_info_cache.update_one(
                {"_id": username},
                {"$set": {
                    "realname": realname,
                    "email": email
                }},
                upsert=True)
            self.user_manager._logger.info("User %s connected - %s - %s - %s",
                                           username, realname, email,
                                           web.ctx.ip)

            # Redirect to desired url
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in input_data and self_url != input_data[
                    'RelayState']:
                raise web.seeother(auth.redirect_to(input_data['RelayState']))
        else:
            logging.getLogger('inginious.webapp.plugin.auth.saml').error(
                "Errors while processing response : " + ", ".join(errors))
            raise web.seeother("/")
def callback():
    auth = OneLogin_Saml2_Auth(prepare_saml_request(request),
                               current_app.config["SAML"])
    auth.process_response()
    errors = auth.get_errors()
    if len(errors) == 0:
        auth_attrs = auth.get_attributes()
        mappings = current_app.config["SAML"]["attributes"]
        attrs = {
            key: auth_attrs[mapping][0]
            for key, mapping in mappings.items()
        }

        user = User.query.get(attrs["uid"])
        if not user:
            user = User(id=attrs["uid"],
                        name=attrs["sn"],
                        first_name=attrs["givenName"],
                        email=attrs["email"])
            db.session.add(user)
            db.session.commit()

        session["logged_in"] = True
        session["user_id"] = user.id
        session["first_name"] = user.first_name
        session["name"] = user.name
        session["email"] = user.email
        session["admin"] = user.admin

        # To do : create function to avoid duplication with pub_page '/moderate'
        if user.admin:
            chans = get_moderate_channels_for_user(user)
            pubs_per_chan = (db.session.query(Publishing).filter(
                (Publishing.channel_id == c.id) & (Publishing.state == 0))
                             for c in chans)
            flattened_list_pubs = [y for x in pubs_per_chan for y in x]
            session["notification"] = len(flattened_list_pubs)
        else:
            session["notification"] = 0

        # Redirect to desired url
        self_url = OneLogin_Saml2_Utils.get_self_url(
            prepare_saml_request(request))
        if 'RelayState' in request.form and self_url != request.form[
                'RelayState']:
            return redirect(auth.redirect_to(request.form['RelayState']))
    else:
        return make_response(", ".join(errors), 500)

    return make_response("saml_acs_error", 500)
Ejemplo n.º 23
0
def acs():
    req = prepare_auth_request(request)
    saml_auth = init_saml_auth(req)
    saml_auth.process_response()
    errors = saml_auth.get_errors()

    if len(errors) == 0:  # No errors, let's authenticate the user
        session['samlUserdata'] = saml_auth.get_attributes()
        session['samlNameId'] = saml_auth.get_nameid()
        session['samlSessionIndex'] = saml_auth.get_session_index()
        authenticate(session)
        self_url = OneLogin_Saml2_Utils.get_self_url(req)

        if 'RelayState' in request.form and self_url != request.form['RelayState']:
            return redirect(saml_auth.redirect_to(request.form['RelayState']))
Ejemplo n.º 24
0
def acs():
    req = prepare_auth_request(request)
    saml_auth = init_saml_auth(req)
    saml_auth.process_response()
    errors = saml_auth.get_errors()

    if len(errors) == 0:  # No errors, let's authenticate the user
        session["samlUserdata"] = saml_auth.get_attributes()
        session["samlNameId"] = saml_auth.get_nameid()
        session["samlSessionIndex"] = saml_auth.get_session_index()
        authenticate(session)
        self_url = OneLogin_Saml2_Utils.get_self_url(req)

        if "RelayState" in request.form and self_url != request.form["RelayState"]:
            return redirect(saml_auth.redirect_to(request.form["RelayState"]))
Ejemplo n.º 25
0
    def post(self):
        if "onelogin" not in current_app.config.get("ACTIVE_PROVIDERS"):
            return "Onelogin is not enabled in the config.  See the ACTIVE_PROVIDERS section.", 404
        auth = OneLogin_Saml2_Auth(self.req, current_app.config.get("ONELOGIN_SETTINGS"))

        self.reqparse.add_argument('return_to', required=False, default=current_app.config.get('WEB_PATH'))
        self.reqparse.add_argument('acs', required=False)
        self.reqparse.add_argument('sls', required=False)

        args = self.reqparse.parse_args()

        return_to = args['return_to']

        if args['acs'] != None:
            # valids the SAML response and checks if successfully authenticated
            if self._consumer(auth):
                email = auth.get_attribute(current_app.config.get("ONELOGIN_EMAIL_FIELD"))[0]
                user = User.query.filter(User.email == email).first()

                # if we get an sso user create them an account
                if not user:
                    user = User(
                        email=email,
                        active=True,
                        role=current_app.config.get('ONELOGIN_DEFAULT_ROLE')
                        # profile_picture=profile.get('thumbnailPhotoUrl')
                    )
                    db.session.add(user)
                    db.session.commit()
                    db.session.refresh(user)

                # Tell Flask-Principal the identity changed
                identity_changed.send(current_app._get_current_object(), identity=Identity(user.id))
                login_user(user)
                db.session.commit()
                db.session.refresh(user)

                self_url = OneLogin_Saml2_Utils.get_self_url(self.req)
                if 'RelayState' in request.form and self_url != request.form['RelayState']:
                    return redirect(auth.redirect_to(request.form['RelayState']), code=302)
                else:
                    return redirect(current_app.config.get('BASE_URL'), code=302)
            else:
                return dict(message='OneLogin authentication failed.'), 403
        elif args['sls'] != None:
            return dict(message='OneLogin SLS not implemented yet.'), 405
        else:
            return redirect(auth.login(return_to=return_to))
def logout(request):
    """Kick off a SAML logout request."""
    req = prepare_django_request(request)
    saml_auth = OneLogin_Saml2_Auth(req, old_settings=settings.ONELOGIN_SAML_SETTINGS)
    name_id = request.session.get('samlNameId', None)
    session_index = request.session.get('samlSessionIndex', None)
    name_id_format = request.session.get('samlNameIdFormat', None)
    name_id_nq = request.session.get('samlNameIdNameQualifier', None)
    name_id_spnq = request.session.get('samlNameIdSPNameQualifier', None)
    auth.logout(request)
    url = saml_auth.logout(
        name_id=name_id, session_index=session_index, nq=name_id_nq, name_id_format=name_id_format, spnq=name_id_spnq,
        return_to=OneLogin_Saml2_Utils.get_self_url(req) + settings.SAML_LOGOUT_REDIRECT
    )
    request.session['LogoutRequestID'] = saml_auth.get_last_request_id()
    return HttpResponseRedirect(url)
Ejemplo n.º 27
0
def sls(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    dscb = lambda: request.session.flush()
    url = auth.process_slo(delete_session_cb=dscb)

    data = {'not_auth_warn': False, 'errors': auth.get_errors()}

    if len(data['errors']) == 0:
        logout(request)
        if url is not None:
            return HttpResponseRedirect(url)
        else:
            return HttpResponseRedirect(OneLogin_Saml2_Utils.get_self_url(req))

    return draw_page(request, data)
Ejemplo n.º 28
0
    def testGetSelfURL(self):
        """
        Tests the get_self_url method of the OneLogin_Saml2_Utils
        """
        request_data = {'http_host': 'example.com'}
        url = OneLogin_Saml2_Utils.get_self_url_host(request_data)
        self.assertEqual(url, OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = ''
        self.assertEqual(url, OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/'
        self.assertEqual(url + '/',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = 'index.html'
        self.assertEqual(url + 'index.html',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '?index.html'
        self.assertEqual(url + '?index.html',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/index.html'
        self.assertEqual(url + '/index.html',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/index.html?testing'
        self.assertEqual(url + '/index.html?testing',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = '/test/index.html?testing'
        self.assertEqual(url + '/test/index.html?testing',
                         OneLogin_Saml2_Utils.get_self_url(request_data))

        request_data['request_uri'] = 'https://example.com/testing'
        self.assertEqual(url + '/testing',
                         OneLogin_Saml2_Utils.get_self_url(request_data))
Ejemplo n.º 29
0
def index():
    req = prepare_flask_request(request)
    auth = init_saml_auth(req)
    errors = []
    error_reason = None
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'acs' in request.args:
        request_id = None
        if 'AuthNRequestID' in session:
            request_id = session['AuthNRequestID']

        auth.process_response(request_id=request_id, validate_sign=False)
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            print("Data")
            print(auth.get_attributes())
            print(auth.get_nameid())
            print("---")
            if 'AuthNRequestID' in session:
                del session['AuthNRequestID']
            session['samlUserdata'] = auth.get_attributes()
            session['samlNameId'] = auth.get_nameid()
            session['samlNameIdFormat'] = auth.get_nameid_format()
            session['samlNameIdNameQualifier'] = auth.get_nameid_nq()
            session['samlNameIdSPNameQualifier'] = auth.get_nameid_spnq()
            session['samlSessionIndex'] = auth.get_session_index()
            self_url = OneLogin_Saml2_Utils.get_self_url(req)

            # if 'RelayState' in request.form and self_url != request.form['RelayState']:
            #     return redirect(auth.redirect_to(request.form['RelayState']))
        elif auth.get_settings().is_debug_active():
            error_reason = auth.get_last_error_reason()
            session["samlUserdataError"] = error_reason

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return redirect("/attrs")
 def post(self, request):
     req = prepare_from_django_request(request)
     auth = OneLogin_Saml2_Auth(req, self.get_saml_settings())
     auth.process_response()
     errors = auth.get_errors()
     if not errors:
         if auth.is_authenticated():
             user = authenticate(saml_authentication=auth)
             login(self.request, user)
             if 'RelayState' in req['post_data'] and \
               OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                 return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
             else:
                 return HttpResponseRedirect("/")
         else:
             raise PermissionDenied()
     else:
         logger.error(auth.get_last_error_reason(), exc_info=True)
         return HttpResponseBadRequest("Error when processing SAML Response: %s" % (', '.join(errors)))
def saml():
    if "saml" not in syllabus.get_config()['authentication_methods']:
        abort(404)
    req = prepare_request(request)
    req['request_uri'] = request.path  # hack to ensure to have the correct path and to avoid RelayState loops
    auth = init_saml_auth(req, saml_config)

    # if 'sso' in request.args:
    #     return
    if request.method == "GET":
        return redirect(auth.login())
    elif 'acs' in request.args:
        auth.process_response()
        errors = auth.get_errors()
        if len(errors) == 0:
            attrs = auth.get_attributes()
            # session['samlNameId'] = auth.get_nameid()
            # session['samlSessionIndex'] = auth.get_session_index()

            username = attrs[saml_config['sp']['attrs']['username']][0]
            realname = attrs[saml_config['sp']['attrs']['realname']][0]
            email = attrs[saml_config['sp']['attrs']['email']][0]

            user = User.query.filter(User.email == email).first()

            if user is None:  # The user does not exist in our DB
                user = User(name=username,
                            full_name=realname,
                            email=email,
                            hash_password=None,
                            change_password_url=None)
                db_session.add(user)
                db_session.commit()

            session["user"] = user.to_dict()
            session["user"].update({"login_method": "saml"})

            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in request.form and self_url != request.form[
                    'RelayState']:
                return redirect(auth.redirect_to(request.form['RelayState']))

    return seeother("/")
Ejemplo n.º 32
0
 def get_saml_auth(self, request):
     saml_request = dict(get_saml_settings().request_settings)
     # Update not existing keys
     saml_request["https"] = saml_request.get(
         "https", "on" if request.is_secure() else "off")
     saml_request["http_host"] = saml_request.get("http_host",
                                                  request.META["HTTP_HOST"])
     saml_request["script_name"] = saml_request.get(
         "script_name", request.META["PATH_INFO"])
     saml_request["server_port"] = saml_request.get(
         "server_port", request.META["SERVER_PORT"])
     # add get and post data
     saml_request["get_data"] = request.GET.copy()
     saml_request["post_data"] = request.POST.copy()
     return (
         OneLogin_Saml2_Utils.get_self_url(saml_request),
         OneLogin_Saml2_Auth(saml_request,
                             get_saml_settings().saml_settings),
     )
Ejemplo n.º 33
0
    def callback(self, user_manager):
        req = prepare_request(self._settings)
        input_data = web.input()

        auth = OneLogin_Saml2_Auth(req, self._settings)
        auth.process_response()
        errors = auth.get_errors()

        # Try and check if IdP is using several signature certificates
        # This is a limitation of python3-saml
        for cert in self._settings["idp"].get("additionalX509certs", []):
            if auth.get_last_error_reason(
            ) == "Signature validation failed. SAML Response rejected":
                # Change used IdP certificate
                logging.getLogger('inginious.webapp.plugin.auth.saml').debug(
                    "Trying another certificate...")
                new_settings = copy.deepcopy(self._settings)
                new_settings["idp"]["x509cert"] = cert
                # Retry processing response
                auth = OneLogin_Saml2_Auth(req, new_settings)
                auth.process_response()
                errors = auth.get_errors()

        if len(errors) == 0 and "attributes" in self._settings:
            attrs = auth.get_attributes()
            username = attrs[self._settings["attributes"]["uid"]][0]
            realname = attrs[self._settings["attributes"]["cn"]][0]
            email = attrs[self._settings["attributes"]["email"]][0]

            # Redirect to desired url
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in input_data and self_url != input_data[
                    'RelayState']:
                redirect_url = auth.redirect_to(input_data['RelayState'])
                # Initialize session in user manager and update cache
                return (
                    str(username), realname, email
                ) if redirect_url == user_manager.session_redir_url() else None
        else:
            logging.getLogger('inginious.webapp.plugin.auth.saml').error(
                "Errors while processing response : ", ", ".join(errors))
            return None
Ejemplo n.º 34
0
def sls(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    dscb = lambda: request.session.flush()
    url = auth.process_slo(delete_session_cb=dscb)

    data = {
        'not_auth_warn': False,
        'errors': auth.get_errors()
    }

    if len(data['errors']) == 0:
        logout(request)
        if url is not None:
            return HttpResponseRedirect(url)
        else:
            return HttpResponseRedirect(OneLogin_Saml2_Utils.get_self_url(req))

    return draw_page(request, data)
Ejemplo n.º 35
0
def acs_after_login():
    """Assertion Consumer Service, IDP response after log in."""
    req = prepare_flask_request(request)
    sauth = init_saml_auth(req)
    sauth.process_response()

    # Retrieves possible validation errors
    errors = sauth.get_errors()
    if errors is not None and len(errors) > 0:
        current_app.logger.error(sauth.get_last_error_reason())
        current_app.logger.error('Request details: %s', req)
        abort(500, message=', '.join(errors))

    if not sauth.is_authenticated():
        abort(401, message='Not authenticated!')

    saml_userdata = sauth.get_attributes()
    # build identity and store to session
    user_uid = saml_userdata['uid']
    # XXX: strangely, saml_userdata['uid'] is a list...
    if isinstance(user_uid, list):
        if len(user_uid) == 1:
            user_uid = user_uid[0]
        else:
            abort(500, message='Unexpected response of Identity Provider!')
    session['identity'] = {
        'uid': user_uid,
        'roles': saml_userdata['roles'],
        'type': 'user'
    }
    # store some saml info too
    session['saml_name_id'] = sauth.get_nameid()
    session['saml_session_idx'] = sauth.get_session_index()

    # redirect to a custom RelayState, if any
    relay_state = req['post_data'].get('RelayState')
    if (relay_state is not None
            and OneLogin_Saml2_Utils.get_self_url(req) != relay_state):
        return redirect(sauth.redirect_to(relay_state))  # 302

    return jsonify(session['identity']), 200
Ejemplo n.º 36
0
def attributes_consumer(request):
    """
    Consume attributes from IDP
    ( IDP -> SP )
    """
    req = prepare_django_request(request)
    idp = request.session.get("idp")
    attr_cons_index = request.session.get("attr_cons_index")
    request_id = request.session.get("request_id")
    request_instant = request.session.get("request_instant")
    if idp and request_id:
        auth = init_saml_auth(req, idp, attr_cons_index)
        errors = []
        auth.process_response(request_id=request_id,
                              request_instant=request_instant)
        errors = auth.get_errors()
        if not errors:
            user_attributes = auth.get_attributes()
            request.session["samlUserdata"] = user_attributes
            request.session["samlNameId"] = auth.get_nameid()
            request.session["samlSessionIndex"] = auth.get_session_index()
            redirect_to = "/"
            if ("RelayState" in req["post_data"]
                    and OneLogin_Saml2_Utils.get_self_url(req) !=
                    req["post_data"]["RelayState"]):
                redirect_to = auth.redirect_to(req["post_data"]["RelayState"])
            return HttpResponseRedirect(redirect_to)
        else:
            error_params = "?errors=%s&error_msg=%s" % (
                errors,
                auth.get_last_error_reason(),
            )
            return redirect(
                reverse(settings.SPID_ERROR_PAGE_URL) + error_params)
    else:
        if not idp:
            print("------- ERROR: not IDP in session!")
        if not request_id:
            print("------- ERROR: not request_id in session!")
        # Return to homepage
        return redirect(settings.SPID_BAD_REQUEST_REDIRECT_PAGE)
Ejemplo n.º 37
0
def saml_acs(request):
    """Handle an AuthenticationResponse from the IdP."""
    if request.method != 'POST':
        return HttpResponse('Method not allowed.', status=405)
    try:
        req = prepare_django_request(request)
        saml_auth = OneLogin_Saml2_Auth(
            req, old_settings=settings.ONELOGIN_SAML_SETTINGS)
        request_id = request.session.get('AuthNRequestID', None)
        saml_auth.process_response(request_id=request_id)

        errors = saml_auth.get_errors()

        if not errors:
            user = auth.authenticate(session_data=saml_auth.get_attributes())
            if user is None:
                if settings.SAML_NO_USER_REDIRECT:
                    return HttpResponseRedirect(settings.SAML_NO_USER_REDIRECT)
                raise PermissionDenied()
            auth.login(request, user)
            # This data is used during Single Log Out
            request.session['samlNameId'] = saml_auth.get_nameid()
            request.session['samlNameIdFormat'] = saml_auth.get_nameid_format()
            request.session[
                'samlNameIdNameQualifier'] = saml_auth.get_nameid_nq()
            request.session[
                'samlNameIdSPNameQualifier'] = saml_auth.get_nameid_spnq()
            request.session['samlSessionIndex'] = saml_auth.get_session_index()
            if 'RelayState' in req['post_data'] \
                    and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                url = saml_auth.redirect_to(req['post_data']['RelayState'])
                return HttpResponseRedirect(url)
            else:
                return HttpResponseRedirect(settings.SAML_LOGIN_REDIRECT)
        logger.exception(saml_auth.get_last_error_reason())
        return HttpResponse(content="Invalid Response", status=400)
    except PermissionDenied:
        raise
    except Exception as e:
        logger.exception(e)
        return HttpResponse(content="Invalid Response", status=400)
Ejemplo n.º 38
0
def saml_login(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)

    if 'provider' in req['get_data']:
        # SP Initiated
        if hasattr(settings, 'SAML_REDIRECT'):
            return HttpResponseRedirect(
                auth.login(return_to=settings.SAML_REDIRECT))
        elif REDIRECT_FIELD_NAME in req['get_data']:
            return HttpResponseRedirect(
                auth.login(return_to=req['get_data'][REDIRECT_FIELD_NAME]))
        elif 'RelayState' in req['post_data']:
            return HttpResponseRedirect(
                auth.redirect_to(req['post_data']['RelayState']))
        else:
            redir = OneLogin_Saml2_Utils.get_self_url(
                req) + request.get_full_path()
            return HttpResponseRedirect(auth.login(return_to=redir))
    else:
        return HttpResponseRedirect(auth.login())
Ejemplo n.º 39
0
def complete_login(request):
    req = get_request_details(request)
    auth = OneLogin_Saml2_Auth(req, custom_base_path=settings.SAML_FOLDER)

    auth.process_response()
    errors = auth.get_errors()
    if not errors:
        if auth.is_authenticated():
            user = authenticate(saml_authentication=auth)
            login(request, user)
            if 'RelayState' in req['post_data'] and \
                        OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
            else:
                return HttpResponseRedirect(settings.LOGIN_REDIRECT_URL)
        else:
            raise PermissionDenied()
    else:
        logger.error('Error in django_saml_sp.views.complete_login: %s' % (auth.get_last_error_reason()))
        logger.error('Errors: %s' % (', '.join(errors)))
        return HttpResponseBadRequest("Error when processing SAML Response: %s" % (', '.join(errors)))
Ejemplo n.º 40
0
def saml_authorized():
    errors = []
    if not app.config.get('SAML_ENABLED'):
        return abort(400)
    req = utils.prepare_flask_request(request)
    auth = utils.init_saml_auth(req)
    auth.process_response()
    errors = auth.get_errors()
    if len(errors) == 0:
        session['samlUserdata'] = auth.get_attributes()
        session['samlNameId'] = auth.get_nameid()
        session['samlSessionIndex'] = auth.get_session_index()
        self_url = OneLogin_Saml2_Utils.get_self_url(req)
        self_url = self_url + req['script_name']
        if 'RelayState' in request.form and self_url != request.form[
                'RelayState']:
            return redirect(auth.redirect_to(request.form['RelayState']))
        user = User.query.filter_by(
            username=session['samlNameId'].lower()).first()
        if not user:
            # create user
            user = User(username=session['samlNameId'],
                        plain_text_password=None,
                        email=session['samlNameId'])
            user.create_local_user()
        session['user_id'] = user.id
        if session['samlUserdata'].has_key("email"):
            user.email = session['samlUserdata']["email"][0].lower()
        if session['samlUserdata'].has_key("givenname"):
            user.firstname = session['samlUserdata']["givenname"][0]
        if session['samlUserdata'].has_key("surname"):
            user.lastname = session['samlUserdata']["surname"][0]
        user.plain_text_password = None
        user.update_profile()
        session['external_auth'] = True
        login_user(user, remember=False)
        return redirect(url_for('index'))
    else:
        return render_template('errors/SAML.html', errors=errors)
Ejemplo n.º 41
0
def callback():
    auth = OneLogin_Saml2_Auth(prepare_saml_request(request),
                               current_app.config["SAML"])
    auth.process_response()
    errors = auth.get_errors()
    if len(errors) == 0:
        auth_attrs = auth.get_attributes()
        mappings = current_app.config["SAML"]["attributes"]
        attrs = {
            key: auth_attrs[mapping][0]
            for key, mapping in mappings.items()
        }

        user = User.query.get(attrs["uid"])
        if not user:
            user = User(id=attrs["uid"],
                        name=attrs["sn"],
                        first_name=attrs["givenName"],
                        email=attrs["email"])
            db.session.add(user)
            db.session.commit()

        session["logged_in"] = True
        session["user_id"] = user.id
        session["first_name"] = user.first_name
        session["name"] = user.name
        session["email"] = user.email
        session["admin"] = user.admin

        # Redirect to desired url
        self_url = OneLogin_Saml2_Utils.get_self_url(
            prepare_saml_request(request))
        if 'RelayState' in request.form and self_url != request.form[
                'RelayState']:
            return redirect(auth.redirect_to(request.form['RelayState']))
    else:
        return make_response(", ".join(errors), 500)

    return make_response("saml_acs_error", 500)
Ejemplo n.º 42
0
    def callback(self, auth_storage):
        req = prepare_request(self._settings)
        input_data = web.input()

        auth = OneLogin_Saml2_Auth(req, self._settings)
        auth.process_response()
        errors = auth.get_errors()

        # Try and check if IdP is using several signature certificates
        # This is a limitation of python3-saml
        for cert in self._settings["idp"].get("additionalX509certs", []):
            if auth.get_last_error_reason() == "Signature validation failed. SAML Response rejected":
                # Change used IdP certificate
                logging.getLogger('inginious.webapp.plugin.auth.saml').debug("Trying another certificate...")
                new_settings = copy.deepcopy(self._settings)
                new_settings["idp"]["x509cert"] = cert
                # Retry processing response
                auth = OneLogin_Saml2_Auth(req, new_settings)
                auth.process_response()
                errors = auth.get_errors()

        if len(errors) == 0 and "attributes" in self._settings:
            attrs = auth.get_attributes()
            username = attrs[self._settings["attributes"]["uid"]][0]
            realname = attrs[self._settings["attributes"]["cn"]][0]
            email = attrs[self._settings["attributes"]["email"]][0]

            # Redirect to desired url
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in input_data and self_url != input_data['RelayState']:
                redirect_url = auth.redirect_to(input_data['RelayState'])
                # Initialize session in user manager and update cache
                return (str(username), realname, email) if redirect_url == auth_storage["redir_url"] else None
        else:
            logging.getLogger('inginious.webapp.plugin.auth.saml').error("Errors while processing response : ",
                                                                         ", ".join(errors))
            return None
Ejemplo n.º 43
0
def index(request):
    req = prepare_pyramid_request(request)
    auth = init_saml_auth(req)
    errors = []
    error_reason = ""
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    session = request.session

    if 'sso' in request.GET:
        return HTTPFound(auth.login())
    elif 'sso2' in request.GET:
        return_to = '%s/attrs/' % request.host_url
        return HTTPFound(auth.login(return_to))
    elif 'slo' in request.GET:
        name_id = None
        session_index = None
        if 'samlNameId' in session:
            name_id = session['samlNameId']
        if 'samlSessionIndex' in session:
            session_index = session['samlSessionIndex']

        return HTTPFound(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in request.GET:
        auth.process_response()
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if len(errors) == 0:
            session['samlUserdata'] = auth.get_attributes()
            session['samlNameId'] = auth.get_nameid()
            session['samlSessionIndex'] = auth.get_session_index()
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in request.POST and self_url != request.POST['RelayState']:
                return HTTPFound(auth.redirect_to(request.POST['RelayState']))
        else:
            error_reason = auth.get_last_error_reason()
    elif 'sls' in request.GET:
        dscb = lambda: session.clear()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HTTPFound(url)
            else:
                success_slo = True

    if 'samlUserdata' in session:
        paint_logout = True
        if len(session['samlUserdata']) > 0:
            attributes = session['samlUserdata'].items()

    return {
        'errors': errors,
        'error_reason': error_reason,
        'not_auth_warn': not_auth_warn,
        'success_slo': success_slo,
        'attributes': attributes,
        'paint_logout': paint_logout,
    }
Ejemplo n.º 44
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    error_reason = None
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        return HttpResponseRedirect(auth.login())
        # If AuthNRequest ID need to be stored in order to later validate it, do instead
        # sso_built_url = auth.login()
        # request.session['AuthNRequestID'] = auth.get_last_request_id()
        # return HttpResponseRedirect(sso_built_url)
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        name_id = None
        session_index = None
        if 'samlNameId' in request.session:
            name_id = request.session['samlNameId']
        if 'samlSessionIndex' in request.session:
            session_index = request.session['samlSessionIndex']

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index))

        # If LogoutRequest ID need to be stored in order to later validate it, do instead
        # slo_built_url = auth.logout(name_id=name_id, session_index=session_index)
        # request.session['LogoutRequestID'] = auth.get_last_request_id()
        #return HttpResponseRedirect(slo_built_url)
    elif 'acs' in req['get_data']:
        request_id = None
        if 'AuthNRequestID' in request.session:
            request_id = request.session['AuthNRequestID']

        auth.process_response(request_id=request_id)
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()

        if not errors:
            if 'AuthNRequestID' in request.session:
                del request.session['AuthNRequestID']
            request.session['samlUserdata'] = auth.get_attributes()
            request.session['samlNameId'] = auth.get_nameid()
            request.session['samlSessionIndex'] = auth.get_session_index()
            if 'RelayState' in req['post_data'] and OneLogin_Saml2_Utils.get_self_url(req) != req['post_data']['RelayState']:
                return HttpResponseRedirect(auth.redirect_to(req['post_data']['RelayState']))
        else:
            if auth.get_settings().is_debug_active():
                error_reason = auth.get_last_error_reason()
    elif 'sls' in req['get_data']:
        request_id = None
        if 'LogoutRequestID' in request.session:
            request_id = request.session['LogoutRequestID']
        dscb = lambda: request.session.flush()
        url = auth.process_slo(request_id=request_id, delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in request.session:
        paint_logout = True
        if len(request.session['samlUserdata']) > 0:
            attributes = request.session['samlUserdata'].items()

    return render(request, 'index.html', {'errors': errors, 'error_reason': error_reason, not_auth_warn: not_auth_warn, 'success_slo': success_slo,
                                          'attributes': attributes, 'paint_logout': paint_logout})
Ejemplo n.º 45
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        if 'redirect_url' in req['get_data']:
            return HttpResponseRedirect(auth.login(return_to=req['get_data']['redirect_url']))
        else:
            return HttpResponseRedirect(auth.login())
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        name_id = None
        session_index = None
        if 'samlNameId' in request.session:
            name_id = request.session['samlNameId']
        if 'samlSessionIndex' in request.session:
            session_index = request.session['samlSessionIndex']

        # update record of user in table accounts_nih_user
        # so that active=0
        # and dbGaP_authorized=0

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in req['get_data']:
        auth.process_response()
        errors = auth.get_errors()
        if errors:
            logger.info('executed auth.get_errors(). errors are:')
            logger.warn(errors)
            logger.info('error is because')
            logger.warn(auth.get_last_error_reason())

        not_auth_warn = not auth.is_authenticated()

        if not errors:
            request.session['samlUserdata'] = auth.get_attributes()
            request.session['samlNameId'] = auth.get_nameid()
            NIH_username = request.session['samlNameId']
            request.session['samlSessionIndex'] = auth.get_session_index()

            user_email = User.objects.get(id=request.user.id).email

            # check to see if user already has authenticated through
            # another NIH_username. If so, don't allow the same google email
            # to be linked to two different NIH usernames
            nih_usernames_already_linked_to_google_identity = NIH_User.objects.filter(user_id=request.user.id)
            for nih_user in nih_usernames_already_linked_to_google_identity:
                if nih_user.NIH_username != NIH_username:
                    logger.warn("User {} is already linked to the eRA commons identity {} and attempted authentication"
                                " with the eRA commons identity {}."
                                .format(user_email, nih_user.NIH_username, NIH_username))
                    messages.warning(request, "User {} is already linked to the eRA commons identity {}. "
                                           "Please unlink these before authenticating with the eRA commons identity {}."
                                     .format(user_email, nih_user.NIH_username, NIH_username))
                    return redirect('/users/' + str(request.user.id))

            # check if there is another google identity with the same NIH_username
            try:
                preexisting_nih_user = NIH_User.objects.get(NIH_username=NIH_username)
                if preexisting_nih_user.user_id != request.user.id:
                    logger.warn("User id {} tried to log into the NIH account {} that is already linked to user {}".format(
                        user_email,
                        NIH_username,
                        preexisting_nih_user.user_id
                    ))
                    messages.warning(request, "You tried to log into an NIH account that is linked to another google email address.")
                    return redirect('/users/' + str(request.user.id))

            except (ObjectDoesNotExist, MultipleObjectsReturned), e:
                # only redirect if there is a MultipleObjectsReturned error
                if type(e) is MultipleObjectsReturned:
                    logger.error("Error %s on NIH login: more than one NIH User with NIH_username %s" % (str(e), NIH_username))
                    return redirect('/users/' + str(request.user.id))

            storage_client = get_storage_resource()
            # check authenticated NIH username against NIH authentication list
            is_dbGaP_authorized = check_NIH_authorization_list(NIH_username, storage_client)

            saml_response = None if 'SAMLResponse' not in req['post_data'] else req['post_data']['SAMLResponse']
            saml_response = saml_response.replace('\r\n', '')
            NIH_assertion_expiration = datetime.datetime.now() + datetime.timedelta(days=1)

            updated_values = {
                'NIH_assertion': saml_response,
                'NIH_assertion_expiration': pytz.utc.localize(NIH_assertion_expiration),
                'dbGaP_authorized': is_dbGaP_authorized,
                'user_id': request.user.id,
                'active': 1
            }

            nih_user, created = NIH_User.objects.update_or_create(NIH_username=NIH_username,
                                                                  user_id=request.user.id,
                                                                  defaults=updated_values)
            logger.info("NIH_User.objects.update_or_create() returned nih_user: {} and created: {}".format(
                str(nih_user.NIH_username), str(created)))

            # add or remove user from ACL_GOOGLE_GROUP if they are or are not dbGaP authorized
            directory_client, http_auth = get_directory_resource()
            # default warn message is for eRA Commons users who are not dbGaP authorized
            warn_message = '''
            WARNING NOTICE
            You are accessing a US Government web site which may contain information that must be protected under the US Privacy Act or other sensitive information and is intended for Government authorized use only.

            Unauthorized attempts to upload information, change information, or use of this web site may result in disciplinary action, civil, and/or criminal penalties. Unauthorized users of this website should have no expectation of privacy regarding any communications or data processed by this website.

            Anyone accessing this website expressly consents to monitoring of their actions and all communications or data transiting or stored on related to this website and is advised that if such monitoring reveals possible evidence of criminal activity, NIH may provide that evidence to law enforcement officials.
            '''

            if is_dbGaP_authorized:
                # if user is dbGaP authorized, warn message is different
                warn_message = 'You are reminded that when accessing controlled access information you are bound by the dbGaP TCGA DATA USE CERTIFICATION AGREEMENT (DUCA).' + warn_message
            try:
                result = directory_client.members().get(groupKey=ACL_GOOGLE_GROUP,
                                                        memberKey=user_email).execute(http=http_auth)
                # if the user is in the google group but isn't dbGaP authorized, delete member from group
                if len(result) and not is_dbGaP_authorized:
                    directory_client.members().delete(groupKey=ACL_GOOGLE_GROUP,
                                                      memberKey=user_email).execute(http=http_auth)
                    logger.warn("User {} was deleted from group {} because they don't have dbGaP authorization.".format(user_email, ACL_GOOGLE_GROUP))
            # if the user_email doesn't exist in the google group an HttpError will be thrown...
            except HttpError:
                # ...if the user is dbGaP authorized they should be added to the ACL_GOOGLE_GROUP
                if is_dbGaP_authorized:
                    body = {
                        "email": user_email,
                        "role": "MEMBER"
                    }
                    result = directory_client.members().insert(
                        groupKey=ACL_GOOGLE_GROUP,
                        body=body
                    ).execute(http=http_auth)
                    logger.info(result)
                    logger.info("User {} added to {}.".format(user_email, ACL_GOOGLE_GROUP))

            # Add task in queue to deactivate NIH_User entry after NIH_assertion_expiration has passed.
            try:
                task = Task(url=CHECK_NIH_USER_LOGIN_TASK_URI,
                            params={'user_id': request.user.id, 'deployment': CRON_MODULE},
                            countdown=COUNTDOWN_SECONDS)
                task.add(queue_name=LOGOUT_WORKER_TASKQUEUE)
                logger.info('enqueued check_login task for user, {}, for {} hours from now'.format(
                    request.user.id, COUNTDOWN_SECONDS / (60*60)))
            except Exception as e:
                logger.error("Failed to enqueue automatic logout task")
                logging.exception(e)

            messages.info(request, warn_message)
            return HttpResponseRedirect(auth.redirect_to('https://{}'.format(req['http_host'])))
Ejemplo n.º 46
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if 'sso' in req['get_data']:
        if 'redirect_url' in req['get_data']:
            return HttpResponseRedirect(auth.login(return_to=req['get_data']['redirect_url']))
        else:
            return HttpResponseRedirect(auth.login())
    elif 'sso2' in req['get_data']:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse('attrs')
        return HttpResponseRedirect(auth.login(return_to))
    elif 'slo' in req['get_data']:
        name_id = None
        session_index = None
        if 'samlNameId' in request.session:
            name_id = request.session['samlNameId']
        if 'samlSessionIndex' in request.session:
            session_index = request.session['samlSessionIndex']

        # update record of user in table accounts_nih_user
        # so that active=0
        # and dbGaP_authorized=0

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index))
    elif 'acs' in req['get_data']:
        auth.process_response()
        errors = auth.get_errors()
        if errors:
            logger.info('executed auth.get_errors(). errors are:')
            logger.warn(errors)
            logger.info('error is because')
            logger.warn(auth.get_last_error_reason())

        not_auth_warn = not auth.is_authenticated()

        if not errors:
            request.session['samlUserdata'] = auth.get_attributes()
            request.session['samlNameId'] = auth.get_nameid()
            NIH_username = request.session['samlNameId']
            request.session['samlSessionIndex'] = auth.get_session_index()

            user_email = User.objects.get(id=request.user.id).email

            # 1. check if this google identity is currently linked to other NIH usernames
            # note: the NIH username exclusion is case-insensitive so this will not return a false positive
            # e.g. if this google identity is linked to 'NIHUSERNAME1' but just authenticated with 'nihusername1',
            # it will still pass this test
            nih_usernames_already_linked_to_this_google_identity = NIH_User.objects.filter(
                user_id=request.user.id, linked=True).exclude(NIH_username__iexact=NIH_username)
            for nih_user in nih_usernames_already_linked_to_this_google_identity:
                if nih_user.NIH_username.lower() != NIH_username.lower():
                    logger.warn("User {} is already linked to the eRA commons identity {} and attempted authentication"
                                " with the eRA commons identity {}."
                                .format(user_email, nih_user.NIH_username, NIH_username))
                    messages.warning(request, "User {} is already linked to the eRA commons identity {}. "
                                              "Please unlink these before authenticating with the eRA commons "
                                              "identity {}.".format(user_email, nih_user.NIH_username, NIH_username))
                    return redirect('/users/' + str(request.user.id))

            # 2. check if there are other google identities that are still linked to this NIH_username
            # note: the NIH username match is case-insensitive so this will not return a false negative.
            # e.g. if a different google identity is linked to 'NIHUSERNAME1' and this google identity just authenticated with 'nihusername1',
            # this will fail the test and return to the /users/ url with a warning message
            preexisting_nih_users = NIH_User.objects.filter(
                NIH_username__iexact=NIH_username, linked=True).exclude(user_id=request.user.id)

            if len(preexisting_nih_users) > 0:
                preexisting_nih_user_user_ids = [preexisting_nih_user.user_id for preexisting_nih_user in preexisting_nih_users]
                prelinked_user_email_list = [user.email for user in User.objects.filter(id__in=preexisting_nih_user_user_ids)]
                prelinked_user_emails = ', '.join(prelinked_user_email_list)

                logger.warn("User {} tried to log into the NIH account {} that is already linked to user(s) {}".format(
                    user_email,
                    NIH_username,
                    prelinked_user_emails + '.'
                ))
                messages.warning(request, "You tried to log into an NIH account that is linked to another google email address.")
                return redirect('/users/' + str(request.user.id))

            storage_client = get_storage_resource()
            # check authenticated NIH username against NIH authentication list
            is_dbGaP_authorized = check_NIH_authorization_list(NIH_username, storage_client)

            saml_response = None if 'SAMLResponse' not in req['post_data'] else req['post_data']['SAMLResponse']
            saml_response = saml_response.replace('\r\n', '')
            NIH_assertion_expiration = datetime.datetime.now() + datetime.timedelta(days=1)

            updated_values = {
                'NIH_assertion': saml_response,
                'NIH_assertion_expiration': pytz.utc.localize(NIH_assertion_expiration),
                'dbGaP_authorized': is_dbGaP_authorized,
                'user_id': request.user.id,
                'active': 1,
                'linked': True
            }

            nih_user, created = NIH_User.objects.update_or_create(NIH_username=NIH_username,
                                                                  user_id=request.user.id,
                                                                  defaults=updated_values)
            logger.info("NIH_User.objects.update_or_create() returned nih_user: {} and created: {}".format(
                str(nih_user.NIH_username), str(created)))

            # add or remove user from ACL_GOOGLE_GROUP if they are or are not dbGaP authorized
            directory_client, http_auth = get_directory_resource()
            # default warn message is for eRA Commons users who are not dbGaP authorized
            warn_message = '''
            WARNING NOTICE
            You are accessing a US Government web site which may contain information that must be protected under the US Privacy Act or other sensitive information and is intended for Government authorized use only.

            Unauthorized attempts to upload information, change information, or use of this web site may result in disciplinary action, civil, and/or criminal penalties. Unauthorized users of this website should have no expectation of privacy regarding any communications or data processed by this website.

            Anyone accessing this website expressly consents to monitoring of their actions and all communications or data transiting or stored on related to this website and is advised that if such monitoring reveals possible evidence of criminal activity, NIH may provide that evidence to law enforcement officials.
            '''

            if is_dbGaP_authorized:
                # if user is dbGaP authorized, warn message is different
                warn_message = 'You are reminded that when accessing controlled access information you are bound by the dbGaP TCGA DATA USE CERTIFICATION AGREEMENT (DUCA).' + warn_message
            try:
                result = directory_client.members().get(groupKey=ACL_GOOGLE_GROUP,
                                                        memberKey=user_email).execute(http=http_auth)
                # if the user is in the google group but isn't dbGaP authorized, delete member from group
                if len(result) and not is_dbGaP_authorized:
                    directory_client.members().delete(groupKey=ACL_GOOGLE_GROUP,
                                                      memberKey=user_email).execute(http=http_auth)
                    logger.warn("User {} was deleted from group {} because they don't have dbGaP authorization.".format(user_email, ACL_GOOGLE_GROUP))
            # if the user_email doesn't exist in the google group an HttpError will be thrown...
            except HttpError:
                # ...if the user is dbGaP authorized they should be added to the ACL_GOOGLE_GROUP
                if is_dbGaP_authorized:
                    body = {
                        "email": user_email,
                        "role": "MEMBER"
                    }
                    result = directory_client.members().insert(
                        groupKey=ACL_GOOGLE_GROUP,
                        body=body
                    ).execute(http=http_auth)
                    logger.info(result)
                    logger.info("User {} added to {}.".format(user_email, ACL_GOOGLE_GROUP))

            # Add task in queue to deactivate NIH_User entry after NIH_assertion_expiration has passed.
            try:
                task = Task(url=CHECK_NIH_USER_LOGIN_TASK_URI,
                            params={'user_id': request.user.id, 'deployment': CRON_MODULE},
                            countdown=COUNTDOWN_SECONDS)
                task.add(queue_name=LOGOUT_WORKER_TASKQUEUE)
                logger.info('enqueued check_login task for user, {}, for {} hours from now'.format(
                    request.user.id, COUNTDOWN_SECONDS / (60*60)))
            except Exception as e:
                logger.error("Failed to enqueue automatic logout task")
                logging.exception(e)

            messages.info(request, warn_message)
            return HttpResponseRedirect(auth.redirect_to('https://{}'.format(req['http_host'])))

    elif 'sls' in req['get_data']:
        dscb = lambda: request.session.flush()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if 'samlUserdata' in request.session:
        paint_logout = True
        if len(request.session['samlUserdata']) > 0:
            attributes = request.session['samlUserdata'].items()

    return render_to_response('demo/index.html',
                              {'errors': errors,
                               'not_auth_warn': not_auth_warn,
                               'success_slo': success_slo,
                               'attributes': attributes,
                               'paint_logout': paint_logout},
                              context_instance=RequestContext(request))
Ejemplo n.º 47
0
def sso(action):
    req = prepare_flask_request(request)
    auth = init_saml_auth(req)
    errors = []

    if action=='acs':
        auth.process_response()
        errors = auth.get_errors()
        if not auth.is_authenticated():
            errors.append('user not authenticated')
        if SAML_UID_ATTRIBUTE:
            uid=auth.get_attribute(SAML_UID_ATTRIBUTE)
            if not uid:
                errors.append('uid attribute not found in response')
            elif len(uid)>1:
                errors.append('uid attribute has multiple values')
            else:
                uid=uid[0]
        else:
            uid=auth.get_nameid()
            if not uid:
                errors.append('nameID is not available')
        session_index = auth.get_session_index()
        if not session_index:
            errors.append('session index is not provided')
        else:
            session['SAML_SESSION_INDEX']=session_index
        if len(errors) == 0:
            login_user(User(uid))
            self_url = OneLogin_Saml2_Utils.get_self_url(req)
            if 'RelayState' in request.form and self_url != request.form['RelayState']:
                return redirect(auth.redirect_to(request.form['RelayState']))
            else: 
                return redirect(url_for(MAIN_VIEW))
    elif action=='sls':
        def dscb ():
            try:
                session.pop('SAML_SESSION_INDEX')
            except KeyError:
                pass
            logout_user()
        url = auth.process_slo(delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return redirect(url)
            else:
                return redirect(url_for(MAIN_VIEW))
    else:
        return ('Invalid request', 400)

    for e in errors:
        flash(e)
    return render_template(
        'access/sso.html',
        
    )

        

        
Ejemplo n.º 48
0
def index(request):
    req = prepare_django_request(request)
    auth = init_saml_auth(req)
    errors = []
    not_auth_warn = False
    success_slo = False
    attributes = False
    paint_logout = False

    if "sso" in req["get_data"]:
        return HttpResponseRedirect(auth.login())
        # If AuthNRequest ID need to be stored in order to later validate it, do instead
        # sso_built_url = auth.login()
        # request.session['AuthNRequestID'] = auth.get_last_request_id()
        # return HttpResponseRedirect(sso_built_url)
    elif "sso2" in req["get_data"]:
        return_to = OneLogin_Saml2_Utils.get_self_url(req) + reverse("attrs")
        return HttpResponseRedirect(auth.login(return_to))
    elif "slo" in req["get_data"]:
        name_id = None
        session_index = None
        if "samlNameId" in request.session:
            name_id = request.session["samlNameId"]
        if "samlSessionIndex" in request.session:
            session_index = request.session["samlSessionIndex"]

        return HttpResponseRedirect(auth.logout(name_id=name_id, session_index=session_index))

        # If LogoutRequest ID need to be stored in order to later validate it, do instead
        # slo_built_url = auth.logout(name_id=name_id, session_index=session_index)
        # request.session['LogoutRequestID'] = auth.get_last_request_id()
        # return HttpResponseRedirect(slo_built_url)
    elif "acs" in req["get_data"]:
        request_id = None
        if "AuthNRequestID" in request.session:
            request_id = request.session["AuthNRequestID"]

        auth.process_response(request_id=request_id)
        errors = auth.get_errors()
        not_auth_warn = not auth.is_authenticated()
        if not errors:
            if "AuthNRequestID" in request.session:
                del request.session["AuthNRequestID"]
            request.session["samlUserdata"] = auth.get_attributes()
            request.session["samlNameId"] = auth.get_nameid()
            request.session["samlSessionIndex"] = auth.get_session_index()
            if (
                "RelayState" in req["post_data"]
                and OneLogin_Saml2_Utils.get_self_url(req) != req["post_data"]["RelayState"]
            ):
                return HttpResponseRedirect(auth.redirect_to(req["post_data"]["RelayState"]))
    elif "sls" in req["get_data"]:
        request_id = None
        if "LogoutRequestID" in request.session:
            request_id = request.session["LogoutRequestID"]
        dscb = lambda: request.session.flush()
        url = auth.process_slo(request_id=request_id, delete_session_cb=dscb)
        errors = auth.get_errors()
        if len(errors) == 0:
            if url is not None:
                return HttpResponseRedirect(url)
            else:
                success_slo = True

    if "samlUserdata" in request.session:
        paint_logout = True
        if len(request.session["samlUserdata"]) > 0:
            attributes = request.session["samlUserdata"].items()

    return render_to_response(
        "index.html",
        {
            "errors": errors,
            "not_auth_warn": not_auth_warn,
            "success_slo": success_slo,
            "attributes": attributes,
            "paint_logout": paint_logout,
        },
        context_instance=RequestContext(request),
    )