Skip to content

Instantly share code, notes, and snippets.

@stevepiercy
Forked from jolle-c/jc_session.lasso
Last active August 29, 2015 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stevepiercy/6c045023fbe13a1b4d77 to your computer and use it in GitHub Desktop.
Save stevepiercy/6c045023fbe13a1b4d77 to your computer and use it in GitHub Desktop.
[
/**!
jc_session
Lasso 9 type to handle cookie based sessions
Requires that Ke Carltons DS is installed
https://github.com/zeroloop/ds
Before first use create the needed table and set the proper values for
ds_sessionDB and jc_session_name
Create query for Mysql:
CREATE TABLE `jc_session` (
`id` bigint(10) NOT NULL AUTO_INCREMENT,
`expire` int(10) DEFAULT NULL,
`session_name` varchar(100) DEFAULT NULL,
`cookie_id` char(36) DEFAULT NULL,
`fk_user_id` char(36) DEFAULT NULL,
`user_permission` text,
`user_data` text,
`updated_datetime` datetime DEFAULT NULL,
`updated_ip` varchar(100) DEFAULT NULL,
`created_datetime` datetime DEFAULT NULL,
`created_ip` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `cookie_id` (`cookie_id`),
KEY `fk_user_id` (`fk_user_id`),
KEY `expire` (`expire`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
EXAMPLE USAGE
On wherever you handle user logins place this code after you have successfully verified that it is a legit user logging in.
jc_session -> addsession(
'user_id', // this should NOT be a hardcoded value, instead use the proper user id as established by the login process
map(// here you set the permissions this user is trusted with, one item in the map for each permission. Permissions can later be expanded or revoked if need be
'some_permission' = true,
'another_permission' = true
),
map(// here you set possible data you want to store in this users session. Could be for example the users name, email etc. Data can later be added to or removed if need be
'some_data' = 'Some Value',
'another_data' = 'Another Value'
),
30 // this is the expire value in minutes
)
To add some session data to the session
jc_session -> data('one_more_key', 'More Data')
Note that whatever session data you add must be compatible with the json format. Complex data types are not allowed
To remove a data item
jc_session -> removedata('the_key')
To add a permission
jc_session -> permission('permission_key', true)
To revoke a permission
jc_session -> permission('permission_key', false)
To retrieve some data stored in the session
jc_session -> data('a_key')
This will return the value stored for the key. If there's no matching key it will return void
To check for a specific permission
jc_session -> permission('permission_key')
Will return true or false
To check if the user has any of a set of permissions use a staticarray
jc_session -> permission((:'a_permission', 'another_permission'))
Will return true if one of the keys match a permission or else false
To expire a session
jc_session -> expire
To get an array of all available keys for data stored in a session
jc_session -> keys
To get the session status
jc_session -> status
Can return any of 'not initiated', 'new', 'load', 'expired', 'not found'
VERSION HISTORY
2014-10-20 JC Added missing data method
2014-10-17 JC First published version, based on an internally used type
*/
/**!
ds_jc_sessionDB
Stores the DS database object used for session storage
*/
define ds_jc_sessionDB => ds('Replace_with_DB_name')
/**!
ds_jc_session
Stores the DS table object used for session storage
*/
define ds_jc_session() => ds_jc_sessionDB -> table(::jc_session)
/**!
jc_session_name
Stores the session name used for sessions
*/
define jc_session_name => var(__jc_session_name) || $__jc_session_name := 'Replace with your preferred session name here' // you could also have a suitable session name stored in some site wide setting and fetch it here
/**!
jc_session
Method that acts as a wrapper for the actual session object. This is the method to call whenever interacting with a session
*/
define jc_session => var(__jc_session) or $__jc_session := jc_sessionhandler -> init(jc_session_name)
// if you need to handle multiple sessions in the same thread, create multiple jc_session methods each with a unique method name and unique session name
/**!
jc_sessionhandler
The actual session type. Should never be called directly. Instead use jc_session
*/
define jc_sessionhandler => type {
parent activerow
public ds => ds_jc_session
public created_column => 'created_datetime'
public modified_column => 'updated_datetime'
data
public sessionname::string,
public permissions::map = map,
public user_data::map = map,
public expiredatetime,
public expireval::integer = 20,
public cookie_id::string,
public sessionvalid::boolean = false,
public sessionstatus::string = 'not initiated'
public asstring => .sessionvalid
public status => .sessionstatus
public addsession(
user_id::string,
permissions::map = map,
user_data::map = map,
expireval::integer = .expireval
) => {
local(
expiredatetime = date -> asinteger + (#expireval * 60),
cookie_id = lasso_uniqueid
)
.expireval = #expireval
.expiredatetime = #expiredatetime
.cookie_id = #cookie_id
.permissions = #permissions
.user_data = #user_data
.updatedata(map(
'expire' = #expiredatetime,
'session_name' = .sessionname,
'cookie_id' = #cookie_id,
'fk_user_id' = #user_id,
'user_permission' = json_serialize(#permissions),
'user_data' = json_serialize(#user_data),
'updated_datetime' = date,
'updated_ip' = string(client_ip),
'created_datetime' = date,
'created_ip' = string(client_ip),
))
.ds -> keycolumn('id')
.create()
.sessionvalid = true
.sessionstatus = 'new'
cookie_set(.sessionname = #cookie_id, -domain = server_name, -path='/')
return self
} // addsession
public init(
name::string
) => {
local(
cookie_id = cookie(#name),
cutoff = date -> asinteger
)
.sessionname = #name
.row = .ds -> getrow('cookie_id' = #cookie_id)
if(.row and integer(.row -> find('expire') ) > #cutoff) => {
.expiredatetime = #cutoff + (.expireval * 60)
.permissions = json_deserialize(.row -> find('user_permission') or map)
.user_data = json_deserialize(.row -> find('user_data') or map)
.cookie_id = #cookie_id
.sessionvalid = true
.sessionstatus = 'load'
.row -> update('expire' = .expiredatetime, 'updated_datetime' = date)
else(.row) // session found but has expired
.permissions = map
.user_data = map
.cookie_id = string
.sessionvalid = false
.sessionstatus = 'expired'
else // no session found
.permissions = map
.user_data = map
.cookie_id = string
.sessionvalid = false
.sessionstatus = 'not found'
}
return self
} // init
public expire() => {
local(
cookie_id = cookie(.sessionname)
)
.expiredatetime = date -> asinteger
.row = .ds -> getrow('cookie_id' = #cookie_id)
if(.row and .row -> cols -> size) => {
.row -> update('expire' = .expiredatetime, 'updated_datetime' = date)
}
.permissions = map
.user_data = map
.cookie_id = string
.sessionvalid = false
.sessionstatus = 'expired'
} // expire
public removedata(param::string) => {
.user_data -> remove(#param)
.row = .ds -> getrow('cookie_id' = .cookie_id)
if(.row) => {
.row -> update(
'user_data' = json_serialize(.user_data),
'updated_datetime' = date,
'updated_ip' = string(client_ip),
)
else
return false
}
}
public data(param::string) => .user_data -> find(#param)
public data(param::integer) => .user_data -> find(string(#param))
public data(param::string, value::any) => {
fail_if(not(.cookie_id), -1, 'No cookie id present')
.user_data -> insert(#param = #value)
.row = .ds -> getrow('cookie_id' = .cookie_id)
if(.row) => {
.row -> update(
'user_data' = json_serialize(.user_data),
'updated_datetime' = date,
'updated_ip' = string(client_ip),
)
else
return false
}
}
public keys => .user_data -> keys
public permission(param::string) => .permissions -> find(#param) or false
public permission(params::staticarray) => {
with param in #params do {
.permissions -> find(#param) ? return true
}
return false
}
public permission(param::string, value::boolean) => {
fail_if(not(.cookie_id), -1, 'No cookie id present')
.permissions -> insert(#param = #value)
.row = .ds -> getrow('cookie_id' = .cookie_id)
if(.row) => {
.row -> update(
'user_permission' = json_serialize(.permissions),
'updated_datetime' = date,
'updated_ip' = string(client_ip),
)
else
return false
}
}
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment