示例#1
0
class CASLoginProvider(BaseProtocol):
    def __init__(self, success_redirect_url=None):
        self.name = 'cas'
        self.protocol_type = 'cas'
        self.display_name = askbot_settings.CAS_SERVER_NAME
        self.icon_media_path = askbot_settings.CAS_LOGIN_BUTTON
        self.one_click_registration = getattr(
            django_settings, 'ASKBOT_CAS_ONE_CLICK_REGISTRATION_ENABLED',
            False)
        self.client = CASClient(
            version=askbot_settings.CAS_PROTOCOL_VERSION,
            server_url=askbot_settings.CAS_SERVER_URL,
            service_url=self.get_service_url(success_redirect_url))

    def verify_ticket(self, *args, **kwargs):
        return self.client.verify_ticket(*args, **kwargs)

    def get_login_url(self):
        return self.client.get_login_url()

    @classmethod
    def get_service_url(cls, success_redirect_url):
        service_url = site_url(reverse('user_complete_cas_signin'))
        if success_redirect_url:
            service_url += '?' + urllib.parse.urlencode(
                {'next': success_redirect_url})
        return service_url
示例#2
0
class CASLoginProvider(BaseProtocol):

    def __init__(self, success_redirect_url=None):
        self.name = 'cas'
        self.protocol_type = 'cas'
        self.display_name = askbot_settings.CAS_SERVER_NAME
        self.icon_media_path = askbot_settings.CAS_LOGIN_BUTTON
        self.one_click_registration = getattr(
                                        django_settings,
                                        'ASKBOT_CAS_ONE_CLICK_REGISTRATION_ENABLED',
                                        False
                                             )
        self.client = CASClient(
                                version=askbot_settings.CAS_PROTOCOL_VERSION,
                                server_url=askbot_settings.CAS_SERVER_URL,
                                service_url=self.get_service_url(success_redirect_url)
                               )

    def verify_ticket(self, *args, **kwargs):
        return self.client.verify_ticket(*args, **kwargs)

    def get_login_url(self):
        return self.client.get_login_url()

    @classmethod
    def get_service_url(cls, success_redirect_url):
        service_url = site_url(reverse('user_complete_cas_signin'))
        if success_redirect_url:
            service_url += '?' + urllib.urlencode({'next': success_redirect_url})
        return service_url
示例#3
0
 def signin_with_cas(self):
     client = CASClient(version='2',
                        renew=False,
                        extra_login_params=False,
                        server_url=CONF.lfid_url,
                        service_url=CONF.lfid_return_url)
     redirect_url = client.get_login_url()
     self.redirect(url=redirect_url, permanent=False)
示例#4
0
 def signin_with_cas(self):
     client = CASClient(version='2',
                        renew=False,
                        extra_login_params=False,
                        server_url=CONF.lfid_url,
                        service_url='http://{0}/{1}'.format(
                            self.request.host, CONF.lfid_return_url))
     redirect_url = client.get_login_url()
     self.redirect(url=redirect_url, permanent=False)
示例#5
0
def link_from_profile(request, institution):
    """
    Attempts to authenticate a CAS account for the provided
    institution, and links it to the current Uniauth profile
    if successful.
    """
    next_url = request.GET.get('next')
    ticket = request.GET.get('ticket')

    # Ensure there is an institution with the provided slug
    try:
        institution = Institution.objects.get(slug=institution)
    except Institution.DoesNotExist:
        raise Http404

    if not next_url:
        next_url = get_redirect_url(request, use_referer=True)

    # If the user is not already logged into a verified
    # Uniauth account, raise permission denied
    if not request.user.is_authenticated or is_tmp_user(request.user) \
            or is_unlinked_account(request.user):
        raise PermissionDenied("Must be logged in as verified Uniauth user.")

    service_url = get_service_url(request, next_url)
    client = CASClient(version=2,
                       service_url=service_url,
                       server_url=institution.cas_server_url)

    # If a ticket was provided, attempt to authenticate with it
    if ticket:
        user = authenticate(request=request,
                            institution=institution,
                            ticket=ticket,
                            service=service_url)

        # Authentication successful: link to Uniauth profile if
        # the institution account has not been linked yet + proceed
        if user:
            if is_unlinked_account(user):
                merge_model_instances(request.user, [user])
                username_split = get_account_username_split(user.username)
                _add_institution_account(request.user.profile,
                                         username_split[1], username_split[2])

            return HttpResponseRedirect(next_url)

        # Authentication failed: raise permission denied
        else:
            raise PermissionDenied("Verification of CAS ticket failed")

    # If no ticket was provided, redirect to the
    # login URL for the institution's CAS server
    else:
        return HttpResponseRedirect(client.get_login_url())
示例#6
0
    async def get(self):
        try:
            if self.settings_dict["mode"] == "production":
                service_url = f"https://{self.settings_dict['domain']}/login?next=%2Flogin"
            else:
                service_url = "http://lscodebuddy.byu.edu:8008/login?next=%2Flogin"

            server_url = "https://cas.byu.edu/cas/"

            cas_client = CASClient(version=3,
                                   service_url=service_url,
                                   server_url=server_url)

            ticket = self.get_argument('ticket', False)
            if not ticket:
                cas_login_url = cas_client.get_login_url()
                self.redirect(cas_login_url)

            user_id, attributes, pgtiou = cas_client.verify_ticket(ticket)

            user_dict = {
                "name":
                attributes["preferredFirstName"] + " " +
                attributes["preferredSurname"],
                "given_name":
                attributes["preferredFirstName"],
                "family_name":
                attributes["preferredSurname"],
                "locale":
                "en",
                "email_address":
                attributes["emailAddress"]
            }

            if self.content.user_exists(user_id):
                # Update user with current information when they already exist.
                self.content.update_user(user_id, user_dict)
            else:
                # Store current user information when they do not already exist.
                self.content.add_user(user_id, user_dict)

            self.set_secure_cookie("user_id", user_id, expires_days=30)

            redirect_path = self.get_secure_cookie("redirect_path")
            self.clear_cookie("redirect_path")
            if not redirect_path:
                redirect_path = "/"
            self.redirect(redirect_path)
        except Exception as inst:
            self.clear_all_cookies()
            render_error(self, traceback.format_exc())
示例#7
0
def cas_login(request, institution):
    """
    Redirects to the CAS login URL, or verifies the
    CAS ticket, if provided.

    Accepts the slug of the institution to log in to.
    """
    next_url = request.GET.get('next')
    ticket = request.GET.get('ticket')

    # Ensure there is an institution with the provided slug
    try:
        institution = Institution.objects.get(slug=institution)
    except Institution.DoesNotExist:
        raise Http404

    if not next_url:
        next_url = get_redirect_url(request, use_referer=True)

    # If the user is already authenticated, proceed to next page
    if request.user.is_authenticated:
        return _login_success(request, request.user, next_url)

    service_url = get_service_url(request, next_url)
    client = CASClient(version=2,
                       service_url=service_url,
                       server_url=institution.cas_server_url)

    # If a ticket was provided, attempt to authenticate with it
    if ticket:
        user = authenticate(request=request,
                            institution=institution,
                            ticket=ticket,
                            service=service_url)

        # Authentication successful: setup session + proceed
        if user:
            if not request.session.exists(request.session.session_key):
                request.session.create()
            auth_login(request, user)
            request.session['auth-method'] = "cas-" + institution.slug
            return _login_success(request, user, next_url, ["ticket"])

        # Authentication failed: raise permission denied
        else:
            raise PermissionDenied("Verification of CAS ticket failed.")

    # If no ticket was provided, redirect to the
    # login URL for the institution's CAS server
    else:
        return HttpResponseRedirect(client.get_login_url())
示例#8
0
async def login_route(next: str = "/",
                      ticket: str = None,
                      cas_client: CASClient = Depends(get_cas),
                      db: AsyncIOMotorClient = Depends(get_database)):
    """login using CAS login

    """
    if not ticket:
        # No ticket, the request come from end user, send to CAS login
        cas_login_url = cas_client.get_login_url()
        return RedirectResponse(url=cas_login_url)

    _user, attributes, _ = cas_client.verify_ticket(ticket)
    if not _user:
        return {"success": 0, "message": "Invalid user! Retry logging in!"}
    else:
        logging.debug(f"CAS verify ticket response: user: {_user}")
        # TODO add additional login functionality here
        redirect_url = f"{next}#/?user={_user}"
        return RedirectResponse(url=redirect_url)
示例#9
0
async def login_route(request: Request,
                      ticket: str = None,
                      cas_client: CASClient = Depends(get_cas),
                      db: Session = Depends(get_db)):
    current_time = datetime.datetime.now()
    if not ticket:
        # No ticket, the request come from end user, send to CAS login
        cas_login_url = cas_client.get_login_url()
        return RedirectResponse(url=cas_login_url)

    username, attributes, _ = cas_client.verify_ticket(ticket)
    request.session['username'] = username

    if not username:
        return {"success": 0, "message": "Invalid user! Retry logging in!"}
    else:
        logging.debug(f"CAS verify ticket response: user: {username}")

        existing = await DBUser.get_by_username(db, username)
        if existing:
            db_user = {"last_login": current_time}
            await DBUser.update(db, username, db_user)
        else:
            # add the initial state as unanswered
            db_user = DBUser(
                username=username,
                last_login=current_time,
                first_login=current_time,
            )
            await DBUser.add(db, db_user)

        access_token = jwt.encode({
            'username': username
        },
                                  str(SECRET_KEY),
                                  algorithm="HS256").decode()
        return {
            "access_token": access_token,
            "username": username,
            "token_type": "bearer",
        }
示例#10
0
async def login_route(
    next: str = "/",
    ticket: str = None,
    cas_client: CASClient = Depends(get_cas),
    db: AsyncIOMotorClient = Depends(get_database)
) -> ResponseBase:
    """login using CAS login

    """
    if not ticket:
        # No ticket, the request come from end user, send to CAS login
        cas_login_url = cas_client.get_login_url()
        return RedirectResponse(url=cas_login_url)

    _user, attributes, _ = cas_client.verify_ticket(ticket)
    if not _user:
        return ResponseBase(success=False,
                            error=[f"Invalid user! {_user}", attributes])

    logging.debug(f"CAS verify ticket response: user: {_user}")

    _update = await db.core.users.update_one(
        {"username": _user},
        {"$set": {
            "last_login": attributes["authenticationDate"]
        }})
    if _update.matched_count == 0:
        user = User(username=_user,
                    first_login=attributes["authenticationDate"],
                    last_login=attributes["authenticationDate"])
        _res = await db.core.users.insert_one(user.dict())

    jwt_token = jwt.encode({
        'username': _user
    },
                           str(SECRET_KEY),
                           algorithm="HS256").decode()
    return ResponseBase(data={"token": jwt_token})