Enforce authentication on 1st question

Hi @v_kostis :smiley: In my testes, I think isn’t possible to make authentication system using custom actions

action_listen and action_session_start is cool but, don’t stop any menssagens

So, we have the way build using condition for every story and an front-end solution

But, I think found a nice way build an Custom Connectors btw, the official docs are outdated

My custom connector check slot is_auth if false and not allowed intent, the user text changed to ‘/please_make_login’

Ex:

  • user input text “hi”-> (intent greet, it not allowed for no-auth users) → original user text changed to /please_make_login
  • user input text “need help”-> (intent help_login, its allowed for no-auth users) → no changes

‘/auth_true’ call the action ‘action_set_auth_true’ and set slot ‘is_auth’ true Im insert some prints

custom_channel.py

import asyncio
import inspect
import aiohttp
import json
from sanic import Sanic, Blueprint, response
from sanic.request import Request
from sanic.response import HTTPResponse
from typing import Text, Dict, Any, Optional, Callable, Awaitable, NoReturn

import rasa.utils.endpoints


from rasa.core.channels.channel import (
    InputChannel,
    CollectingOutputChannel,
    UserMessage,
)

class MyIO(InputChannel):
    def name(name) -> Text:
        return "myio"


    async def teste(self,url,payload):
        async with aiohttp.ClientSession() as session:
            
            async with session.post(url,data=payload) as response:
                try:
                    return await response.json()
                except Exception as e:
                    
                    return await response.text()

    def blueprint(
        self, on_new_message: Callable[[UserMessage], Awaitable[None]]
    ) -> Blueprint:

        custom_webhook = Blueprint(
            "custom_webhook_{}".format(type(self).__name__),
            inspect.getmodule(self).__name__,
        )
    
        @custom_webhook.route("/", methods=["GET"])
        async def health(request: Request) -> HTTPResponse:
            return response.json({"status": "ok"})
        

        @custom_webhook.route("/webhook", methods=["POST"])
        async def receive(request: Request) -> HTTPResponse:
            sender_id = request.json.get("sender") # method to get sender_id 
            text = request.json.get("text") # method to fetch text
            input_channel = self.name() # method to fetch input channel
            metadata = self.get_metadata(request) # method to get metadata
            collector = CollectingOutputChannel()
            tracker = request.app.agent.tracker_store.get_or_create_tracker(sender_id)
            is_auth = tracker.get_slot('is_auth')


            if not is_auth: #change user text to 
                
                show_without_authentication = ['help_login','auth_true']
                payload = {"text": text}
                intent = await self.teste("http://localhost:5005/model/parse",json.dumps(payload))
                intent = intent["intent"]["name"]

                if intent not in show_without_authentication:
                   text = "/please_make_login" 

            await on_new_message(
                UserMessage(
                    text,
                    collector,
                    sender_id,
                    metadata,
                    input_channel=input_channel,
                )
            )
            return response.json(collector.messages)

        return custom_webhook

rasa2-8_auth_custom_channel.zip (16.6 KB)