예제 #1
0
    def delete(self, trip_id: int, user: User = None):
        """

        @api {DELETE} /api/v1/trips/trip_id Trip deletion
        @apiVersion 1.0.0

        @apiName DeleteTrip
        @apiGroup Trips

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {}

        @apiError (NotFound 404) {Object} NoSuchTrip                        Such trip doesn't exist
        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            db_instance = TripsDatabase()
            deleted_trip = db_instance.trip_delete(user.id, trip_id)
            db_instance.close_connection()

            if not deleted_trip:
                return response_404("NoSuchTrip", "Such trip doesn't exist")

            return jsonify({})

        except Exception as e:
            print(e)
            return response_500()
예제 #2
0
def login():
    """

    @api {POST} /api/v1/token User login
    @apiVersion 1.0.0

    @apiName UserLogin
    @apiGroup Authentication

    @apiParam {String} username User's username.
    @apiParam {String} password User's password.

    @apiSuccess {String} token User's jwt.

    @apiSuccess {Object} user_info              User's information.
    @apiSuccess {String} user_info.username     User's username
    @apiSuccess {String} user_info.email        User's email

    @apiSuccessExample {json} Success-Response:
    HTTP/1.1 200 OK
    {
        "token": "eyJ0eXA...",
        "user_info": {
            "username": "******",
            "email": "*****@*****.**"
        }
    }

    @apiError (Unauthorized 401) {Object} InvalidLogin Username or password is incorrect.
    @apiError (InternalServerError 500) {Object} InternalServerError

    """

    try:
        # tries to get the value if none provided returns an emtpy string
        username = request.json.get('username', '')
        password = request.json.get('password', '')

        db_instance = UserDatabase()
        user = db_instance.verify_user(username, password)
        db_instance.close_connection()

        if not user:
            return response_401('username or password incorrect')

        token_payload = {
            'id': user.id,
            'iat': datetime.datetime.now().astimezone(),
            'exp': datetime.datetime.now().astimezone() + datetime.timedelta(days=30)
        }
        token = jwt.encode(token_payload, SECRET_KEY, algorithm='HS256')

        return jsonify({
            'token': token.decode('ascii'),
            'user_info': user.user_info()
        })

    except Exception as e:
        print(e)
        return response_500()
예제 #3
0
    def get_trips_list(self, user):
        """

        @api {GET} /api/v1/trips Trips List
        @apiVersion 1.0.0

        @apiName TripsList
        @apiGroup Trips

        @apiSuccess {Object[]} trips                List with trips
        @apiSuccess {Integer} trips.id              Trip's id
        @apiSuccess {String} trips.name             Trip's name
        @apiSuccess {Integer} trips.user_id         Trip's user_id
        @apiSuccess {Integer} trips.max_trip_days   Trip's max_trip_days
        @apiSuccess {Boolean} trips.is_guided       Trip's is_guided
        @apiSuccess {Boolean} trips.in_group        Trip's in_group
        @apiSuccess {Integer} trips.max_price       Trip's max_price

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {
            "trips":
            [
                {
                    "id": 1,
                    "name": "Short Travel",
                    "user_id": 1,
                    "max_trip_days": 20,
                    "is_guided": True,
                    "in_group": False,
                    "max_price": 10 000
                },
                {
                    "id": 2,
                    "name": "Dream Trip",
                    "user_id": 1,
                    "max_trip_days": 30,
                    "is_guided": True,
                    "in_group": True,
                    "max_price": 200 000
                }
            ]
         }

        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            db_instance = TripsDatabase()
            trips_list = db_instance.trips_list(user.id)
            db_instance.close_connection()

            return jsonify({
                "trips": [trip.serialize() for trip in trips_list]
            })

        except:
            return response_500()
예제 #4
0
def verify_token():
    """

    @api {POST} /api/v1/token/verify Token Verification
    @apiVersion 1.0.0

    @apiName VerifyToken
    @apiGroup Authentication

    @apiParam {String} token User's token.

    @apiSuccess {Object} user_info User's information
    @apiSuccess {String} user_info.username User's username
    @apiSuccess {String} user_info.email User's email

    @apiSuccessExample {json} Success-Response:
    HTTP/1.1 200 OK
     {
        "user_info": {
            "username": "******",
            "email": "*****@*****.**"
        }
    }

   @apiError (Unauthorized 401 ) {Object} InvalidToken
   @apiError (Unauthorized 401 ) {Object} ExpiredToken
   @apiError (InternalServerError 500) {Object} InternalServerError

    """

    try:
        # tries to get the value if none provided returns an emtpy string
        token = request.json.get('token', '')

        payload = jwt.decode(token, SECRET_KEY, verify=True)
        user_id = payload["id"]

        db_instance = UserDatabase()
        user = db_instance.get_user_by_id(user_id)
        db_instance.close_connection()

        if not user:
            return response_401('Please provide a valid token')

        return jsonify({'user_info': user.user_info()})

    except jwt.ExpiredSignatureError:
        return response_401('ExpiredToken')

    except Exception as e:
        print(e)
        return response_500()
예제 #5
0
    def get_trip_info(self, user, trip_id):
        """

        @api {GET} /api/v1/trips/<trip_id> Trip information
        @apiVersion 1.0.0

        @apiName TripInfo
        @apiGroup Trips

        @apiSuccess {Integer}   id              Trip's id
        @apiSuccess {String}    name            Trip's name
        @apiSuccess {Integer}   user_id         Trip's user_id
        @apiSuccess {Integer}   max_trip_days   Trip's max_trip_days
        @apiSuccess {Boolean}   is_guided       Trip's is_guided
        @apiSuccess {Boolean}   in_group        Trip's in_group
        @apiSuccess {Integer}   max_price       Trip's max_price

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {
            "id": 1,
            "name": "Short Travel",
            "user_id": 1,
            "max_trip_days": 20,
            "is_guided": True,
            "in_group": False,
            "max_price": 10000
         }

        @apiError (NotFound 404) {Object} NoSuchTrip
        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            db_instance = TripsDatabase()
            trip_info = db_instance.trip_info(user.id, trip_id)
            db_instance.close_connection()

            if not trip_info:
                return response_404("NoSuchTrip", "Such trip doesn't exist")

            return jsonify(trip_info.serialize())

        except Exception as e:
            print(e)
            return response_500()
    def get(self):
        """

        @api {GET} /api/v1/types/ Get Attraction Types
        @apiVersion 1.0.0

        @apiName AttractionTypes
        @apiGroup Attractions

        @apiSuccess {Object[]} attraction_types             List with all attraction types
        @apiSuccess {Integer} attraction_types.type_id      Attraction type id
        @apiSuccess {String} attraction_types.type_name     Attraction type name

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {
           "attraction_types": [
                {
                    "type_id": 1,
                    "type_name": "temples"
                },
                {
                    "type_id": 2,
                    "type_name": "shrines"
                }
            ]
        }

        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            db_instance = AttractionsDatabase()
            attraction_types_list = db_instance.get_attraction_types()
            db_instance.close_connection()

            return jsonify({"attraction_types": attraction_types_list})
        except Exception as e:
            print(e)
            return response_500()
예제 #7
0
    def get(self):
        """
        @api {GET} /api/v1/cities Get Cities
        @apiVersion 1.0.0

        @apiName GetCities
        @apiGroup Attractions

        @apiSuccess {Object[]} cities      List with all cities
        @apiSuccess {Integer} city_id      City id
        @apiSuccess {String} city_name     City name

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {
           "cities": [
                {
                    "city_id": 1,
                    "city_name": "Tokyo"
                },
                {
                    "city_id": 2,
                    "city_name": "Osaka"
                }
            ]
        }

        @apiError (InternalServerError 500) {Object} InternalServerError
        """
        try:
            db_instance = AttractionsDatabase()
            cities_list = db_instance.get_cities()
            db_instance.close_connection()

            return jsonify({"cities": cities_list})
        except Exception as e:
            print(e)
            return response_500()
예제 #8
0
def register():
    """

    @api {POST} /api/v1/users User registration
    @apiVersion 1.0.0

    @apiName UserRegistration
    @apiGroup Authentication

    @apiParam {String{2..25}} username User's username.
    @apiParam {String{8..}} password User's password.
    @apiParam {String} email User's email.

    @apiSuccessExample {json} Success-Response:
    HTTP/1.1 200 OK
    {}

    @apiError (Bad Request 400) {Object} InvalidUsername        Username should have at least 2 characters and maximum 25, it can contain any char except white space.
    @apiError (Bad Request 400) {Object} InvalidPassword        Password should have at least 8 characters and can contain any char except white space.
    @apiError (Bad Request 400) {Object} UnavailableUsername    Username is unavailable.
    @apiError (Bad Request 400) {Object} InvalidEmailFormat     Email should have an "@" sign and a email domain name with a domain ending of at least 2 characters.
    @apiError (InternalServerError 500) {Object} InternalServerError

    """

    try:
        # tries to get the value if none provided returns an emtpy string
        username = request.json.get('username', '')
        password = request.json.get('password', '')
        email = request.json.get('email', '')

        # checks that the passed values are valid
        if not re.match(r'^[\S]{2,25}$', username):
            return response_400('InvalidUsername',
                                'Ussername should have at least 2 characters and maximum 25, it can contain any char '
                                'except white space.')

        if not re.match(r"^[\S]{8,}$", password):
            return response_400('InvalidPassword',
                                'Password should have at least 8 characters and can contain any char except '
                                'white space.')

        if not email or not re.fullmatch(r'([\w\.\-]+)@([\w]+)\.([\w]+){2,}', email):
            return response_400('InvalidEmailFormat',
                                'Email should have an "@" sign and a email domain name with a domain ending of at'
                                ' least 2 characters.')

        db_instance = UserDatabase()
        db_instance.create_user(username, email.lower(), password)
        db_instance.close_connection()

        welcome_email(email)

        return jsonify({})

    except IntegrityError as e:
        return response_400('UnavailableUsername', 'Username is unavailable.')

    except Exception as e:
        print(e)
        return response_500()
예제 #9
0
    def get(self):
        """

        @api {GET} /api/v1/attractions Search Attractions
        @apiVersion 1.0.0

        @apiName SearchAttractions
        @apiGroup Attractions

        @apiParam {String} text                    User input which will be checked against the attraction's name
        @apiParam {Integer} attraction_type_id     Shows a specific category of attractions
        @apiParam {Integer} city_id                Shows attractions in a city
        @apiParam {Integer} max_price              Shows attractions up to a max price


        @apiSuccess {Object[]} attractions                      List with attractions
        @apiSuccess {String} attractions.id                     Attraction's id
        @apiSuccess {String} attractions.attraction_name        Attraction's name
        @apiSuccess {String} attractions.description            Attraction's description
        @apiSuccess {Integer} attractions.price                 Attraction's price
        @apiSuccess {String} attractions.web_link               Attraction's web_link
        @apiSuccess {String} attractions.picture_url            Attraction's picture_url
        @apiSuccess {Object} attractions.city                   Attraction's city dictionary
        @apiSuccess {Integer} city.id                           Attraction's city id
        @apiSuccess {String} city.name                          Attraction's city name

        @apiSuccessExample {json} Success-Response:
        # todo add proper url examples
        HTTP/1.1 200 OK
        {
            "attractions": [
                {
                    "id": 1,
                    "attraction_name": "Fuji Mountain",
                    "description": "Highest mountain in Japan.",
                    "price": 200,
                    "web_link": "",
                    "picture_url": "",
                    "city": {
                        "id": 1,
                        "name": "Tokyo"
                            }
                },
                {
                    "id": 1,
                    "attraction_name": "Osaka Tower",
                    "description": "The tower was 160 meters (525 feet) high.",
                    "price": 130,
                    "web_link": "",
                    "picture_url": "",
                    "city": {
                        "id": 2,
                        "name": "Osaka"
                            }
                }
            ]
         }

        @apiError (NotFound 404) {Object} NoSuchTrip    Such trip doesn't exist.
        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            text = request.args.get('text', None)
            attraction_type_id = request.args.get('attraction_type_id', None)
            city_id = request.args.get('city_id', None)
            max_price = request.args.get('max_price', None)

            db_instance = AttractionsDatabase()
            attractions_list = db_instance.get_attractions(
                text, attraction_type_id, city_id, max_price)
            db_instance.close_connection()

            return jsonify(
                {"attractions": [e.serialize() for e in attractions_list]})
        except Exception as e:
            print(e)
            return response_500()
예제 #10
0
    def patch(self, trip_id, user: User = None):
        """

        @api {PATCH} /api/v1/trips/trip_id Trip update
        @apiVersion 1.0.0

        @apiName TripUpdate
        @apiGroup Trips

        @apiParam {String}  [name]                Trip's name
        @apiParam {Integer} [max_trip_days]       Trip's max_trip_days
        @apiParam {Boolean} [is_guided]           Trip's is_guided
        @apiParam {Boolean} [in_group]            Trip's in_group
        @apiParam {Integer} [max_price]           Trip's max_price
        @apiParam {Boolean} [finalised]           If true is passed in the user will receive an offer.

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {}

        @apiError (BadRequest 400) {Object} NoParameter                     Please provide a parameter.
        @apiError (BadRequest 400) {Object} InvalidName                     Name should have at least 2 characters and maximum 25.
        @apiError (BadRequest 400) {Object} InvalidDaysNumber               Please provide valid max_trip_days value.
        @apiError (BadRequest 400) {Object} InvalidPriceNumber              Please provide a valid max_price value.
        @apiError (NotFound 404) {Object} NoSuchTrip                        Such trip doesn't exist
        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:

            # finalised is a fictional value in my database.
            # if a trip is finalised then the user will get emails with matching offers to their trip from tourist
            # agencies.
            finalised = request.json.get("finalised", None)

            # send dummy email on trip finalised as an offer example
            if finalised:
                offer_email(user.email)
                return jsonify({})

            changed_fields = {}

            for key in ["name", "is_guided", "max_trip_days", "in_group", "max_price"]:
                value = request.json.get(key, None)

                if value is not None:
                    changed_fields[key] = value

            if len(changed_fields) == 0:
                return response_400("NoParameter", "Please provide a parameter")

            # checks that the passed values are valid
            if not re.match(r'^[\S\s]{2,25}$', changed_fields["name"]):
                return response_400('InvalidName', 'Name should have at least 2 characters and maximum 25.')

            if "max_trip_days" in changed_fields and int(changed_fields["max_trip_days"]) < 1 or int(changed_fields[
                                                                                                         "max_trip_days"]) > 30:
                return response_400("InvalidDaysNumber", "Please provide valid max_trip_days value")

            if "max_price" in changed_fields and int(changed_fields["max_price"]) < 1 or int(changed_fields[
                                                                                                 "max_price"]) > 1000000:
                return response_400("InvalidPriceNumber", "Please provide a valid max_price value")

            db_instance = TripsDatabase()
            updated_trip = db_instance.update_trip(trip_id, user.id, changed_fields)
            db_instance.close_connection()

            if not updated_trip:
                return response_404("NoSuchTrip", "Such trip doesn't exist")

            return jsonify({})

        except Exception as e:
            print(e)
            return response_500()
예제 #11
0
    def post(self, user: User = None):
        """

        @api {POST} /api/v1/trips Trip creation
        @apiVersion 1.0.0

        @apiName CreateTrip
        @apiGroup Trips

        @apiParam {String} name                 Trip's name
        @apiParam {Integer} max_trip_days       Trip's max_trip_days
        @apiParam {Boolean} is_guided           Trip's is_guided
        @apiParam {Boolean} in_group            Trip's in_group
        @apiParam {Integer} max_price           Trip's max_price

        @apiSuccess {Integer} trip_id           The id of the created trip

        @apiSuccessExample {json} Success-Response:
        HTTP/1.1 200 OK
        {
            "id": 1,
            "name": "Short Travel",
            "user_id": 1,
            "max_trip_days": 20,
            "is_guided": True,
            "in_group": False,
            "max_price": 10000
         }

        @apiError (BadRequest 400) {Object} InvalidName                     Name should have at least 2 characters and maximum 25.
        @apiError (BadRequest 400) {Object} InvalidDaysNumber               Please provide valid max_trip_days value.
        @apiError (BadRequest 400) {Object} InvalidPriceNumber              Please provide a valid max_price value.
        @apiError (BadRequest 400) {Object} InvalidDataEntry
        @apiError (BadRequest 400) {Object} ParameterError                  Please provide all the parameters
        @apiError (InternalServerError 500) {Object} InternalServerError

        """
        try:
            name = request.json['name']
            max_trip_days = int(request.json['max_trip_days'])
            is_guided = bool(request.json['is_guided'])
            in_group = bool(request.json['in_group'])
            max_price = int(request.json['max_price'])

            # checks that the passed values are valid
            if not re.match(r'^[\S\s]{2,25}$', name):
                return response_400('InvalidName', 'Name should have at least 2 characters and maximum 25.')

            if max_trip_days < 1 or max_trip_days > 30:
                return response_400("InvalidDaysNumber", "Please provide valid max_trip_days value.")

            if max_price < 1 or max_price > 1000000:
                return response_400("InvalidPriceNumber", "Please provide a valid max_price value.")

            db_instance = TripsDatabase()
            new_trip = db_instance.trip_create(name, user.id, max_trip_days, is_guided, in_group, max_price)
            db_instance.close_connection()
            if not new_trip:
                return response_400("BadRequest", "Invalid data entry")

            return jsonify(new_trip.serialize())

        except KeyError:
            return response_400("ParameterError", "Please provide all the parameters")
        except Exception as e:
            print(e)
            return response_500()