Giter Site home page Giter Site logo

cro-http-session-red's Introduction

NAME

Cro::HTTP::Session::Red - Plugin for Cro to use Red as session manager

SYNOPSIS

# service.raku

use Cro::HTTP::Log::File;
use Cro::HTTP::Server;
use Red;
use Routes;

red-defaults "SQLite";

User.^create-table: :if-not-exists;
UserSession.^create-table: :if-not-exists;

try User.^create: :name<CookieMonster>, :email<[email protected]>, :password("1234");

my Cro::Service $http = Cro::HTTP::Server.new(
    http => <1.1>,
    host => %*ENV<CLASSIFIED_HOST> ||
        die("Missing CLASSIFIED_HOST in environment"),
    port => %*ENV<CLASSIFIED_PORT> ||
        die("Missing CLASSIFIED_PORT in environment"),
    application => routes(),
    after => [
        Cro::HTTP::Log::File.new(logs => $*OUT, errors => $*ERR)
    ]
);
$http.start;
say "Listening at http://%*ENV<CLASSIFIED_HOST>:%*ENV<CLASSIFIED_PORT>";
react {
    whenever signal(SIGINT) {
        say "Shutting down...";
        $http.stop;
        done;
    }
}


# lib/Routes.rakumod

use Cro::HTTP::Router;
use Cro::HTTP::Session::Red;
use Red;

model UserSession { ... }

model User is table<account> {
    has UInt            $!id       is serial;
    has Str             $.name     is column;
    has Str             $.email    is column{ :unique };
    has Str             $.password is column;
    has UserSession     @.sessions is relationship{ .uid }

    method check-password($password) {
        $password eq $!password
    }
}

model UserSession is table<logged_user> does Cro::HTTP::Auth {
    has Str  $.id         is id;
    has UInt $.uid        is referencing(*.id, :model(User));
    has User $.user       is relationship{ .uid } is rw;
}

subset LoggedInSession is sub-model of UserSession where .user.defined;

sub routes is export {
    route {
        before Cro::HTTP::Session::Red[UserSession].new: cookie-name => 'MY_SESSION_COOKIE_NAME';
        get -> LoggedInSession $session (User :$user, |) {
            content 'text/html', "<h1> Logged User: { $user.name } </h1>";
        }

        get {
            redirect '/login', :see-other;
        }

        get -> 'login' {
            content 'text/html', q:to/HTML/;
                <form method="POST" action="/login">
                    <div>
                        Username: <input type="text" name="email" />
                    </div>
                    <div>
                        Password: <input type="password" name="password" />
                    </div>
                    <input type="submit" value="Log In" />
                </form>
            HTML
        }

        post -> UserSession $session, 'login' {
            request-body -> (Str() :$email, Str() :$password, *%) {
                given User.^load: :$email {
                    if .?check-password: $password {
                        $session.user = $_;
                        $session.^save;
                        redirect '/', :see-other;
                    }
                    else {
                        content 'text/html', "Bad username/password";
                    }
                }
            }
        }
    }
}

DESCRIPTION

Cro::HTTP::Session::Red is a Plugin for Cro to use Red as session manager. You can create any custom Red model to store the Cro session, but its id must be a Str and the generated session string will be used as the id.

AUTHOR

Fernando Correa de Oliveira [email protected]

COPYRIGHT AND LICENSE

Copyright 2019 Fernando Correa de Oliveira

This library is free software; you can redistribute it and/or modify it under the Artistic License 2.0.

cro-http-session-red's People

Contributors

fco avatar vrurg avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

cro-http-session-red's Issues

Not able to create subset directly

Because a Red::Model isn't quite the right type of, er, type the pattern suggested in the https://cro.services/docs/http-auth-and-sessions to create subsets of the UserSession object like:

subset Admin of My::App::Session where .is-admin;
subset LoggedIn of My::App::Session where .is-logged-in;

Won't work directly (giving The 'of' type of a subset must either be a valid nominal type or a type that can provide one ) so one has to make an intermediate subset instead like:

subset UserSession of Cro::HTTP::Auth where * ~~ My::App::Session;
subset Admin of  UserSession where .is-admin;
subset LoggedIn of UserSession where .is-logged-in;

(Assuming My::App::Session is your Red model.)

I don't think this can easily be fixed given the way Red works (and would have to be done in Red itself besides,) but is probably worth noting in the documentation to avoid a future issue.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.