Ejemplo n.º 1
0
    def authenticate(self, request, institution, ticket, service):
        user_model = get_user_model()

        # Attempt to verify the ticket with the institution's CAS server
        client = CASClient(version=2, service_url=service,
                server_url=institution.cas_server_url)
        username, attributes, pgtiou = client.verify_ticket(ticket)

        # Add the attributes returned by the CAS server to the session
        if request and attributes:
            request.session['attributes'] = attributes

        # If no username was returned, verification failed
        if not username:
            return None

        # Attempt to find a user possessing an account
        # with that username for the institution
        try:
            user = InstitutionAccount.objects.get(cas_id=username,
                    institution=institution).profile.user
        except InstitutionAccount.DoesNotExist:
            user = None

        # If such a user does not exist, get or create
        # one with a deterministic, CAS username
        if not user:
            temp_username = "******" % (institution.slug, username)
            user, created = user_model._default_manager.get_or_create(
                    **{user_model.USERNAME_FIELD: temp_username})

        return user
Ejemplo n.º 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.parse.urlencode(
                {'next': success_redirect_url})
        return service_url
Ejemplo n.º 3
0
    def get(self):
        logging.warning("cas return")
        ticket = self.get_query_argument('ticket')
        logging.warning("ticket:%s", ticket)
        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))
        user, attrs, _ = client.verify_ticket(ticket)
        logging.debug("user:%s", user)
        logging.debug("attr:%s", attrs)
        openid = user
        role = const.DEFAULT_ROLE
        new_user_info = {
            'openid': openid,
            'email': attrs['mail'],
            'fullname': attrs['profile_name_full'],
            const.ROLE: role
        }
        user = yield dbapi.db_find_one(self.table, {'openid': openid})
        if not user:
            dbapi.db_save(self.table, new_user_info)
        else:
            role = user.get(const.ROLE)

        self.clear_cookie(const.OPENID)
        self.clear_cookie(const.ROLE)
        self.clear_cookie('ticket')
        self.set_secure_cookie(const.OPENID, openid)
        self.set_secure_cookie(const.ROLE, role)
        self.set_secure_cookie('ticket', ticket)

        self.redirect('http://{0}'.format(self.request.host))
Ejemplo n.º 4
0
 def post(self, request):
     serializer = self.serializer_class(data=request.data)
     serializer.is_valid(raise_exception=True)
     data = serializer.validated_data
     if data['domain'] == 'xjtu':
         cas_client = CASClient(version='CAS_2_SAML_1_0',
                                server_url='https://cas.xjtu.edu.cn',
                                service_url=data['service'])
         netid, attr, _ = cas_client.verify_ticket(data['ticket'])
         if netid is None:
             raise serializers.ValidationError(
                 'fail to verify ticket (xjtu)')
         identifier = 'xjtu-' + netid
         try:
             user = User.objects.get(username=identifier)
             angel = user.angel
         except User.DoesNotExist:
             user = User.objects.create_user(username=identifier)
             user.set_unusable_password()
             user.save()
             angel = Angel(user=user, real_name=unquote(attr['cn']))
             angel.save()
     else:
         raise serializers.ValidationError('unknown domain')
     token, _created = Token.objects.get_or_create(user=user)
     return Response({**AngelSerializer(angel).data, 'token': token.key})
Ejemplo n.º 5
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
Ejemplo n.º 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())
Ejemplo n.º 7
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)
Ejemplo n.º 8
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",
        }
Ejemplo n.º 9
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})
Ejemplo n.º 10
0
    def authenticate(self, request, **kwargs):
        """
        Method to verify CAS-tickets.

        :param request: HttpRequest to verification page.
        :param ticket: Ticket to verify (as string).
        :param service: Service url to use in verification.

        :returns user: User instance or None if not verified.
        """
        try:
            ticket = kwargs['ticket']
            service = kwargs['service']
        except KeyError:
            return None
        user_model = AuthUser

        # Attempt to verify the ticket with the institution's CAS server
        client = CASClient(version=2,
                           service_url=service,
                           server_url=str(utils.get_setting('CAS_SERVER_URL')))
        username, attributes, pgtiou = client.verify_ticket(ticket)

        # Add the attributes returned by the CAS server to the session
        if request and attributes:
            request.session['attributes'] = attributes

        # If no username was returned, verification failed
        if not username:
            return None

        # Try to find user
        try:
            user = user_model.objects.get_by_natural_key(username)
        except user_model.DoesNotExist:
            user = None

        return user if self.user_can_authenticate(user) else None