Compare commits
14 Commits
blog_ewf_v
...
ewf_v1_aut
| Author | SHA1 | Date | |
|---|---|---|---|
| c3133c65a1 | |||
|
|
9e51df1e01 | ||
| 967871e427 | |||
| 73e0098c4d | |||
| b4407378db | |||
| f619727997 | |||
| e37dbb0a62 | |||
|
|
afced59b0c | ||
|
|
18732a9532 | ||
|
|
f652aa8a15 | ||
|
|
e188625c43 | ||
|
|
96ba3c35a2 | ||
|
|
181c32a895 | ||
|
|
032cc5bdcb |
@@ -28,6 +28,7 @@
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html-safe.ecf" readonly="false"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
10
cms.ecf
10
cms.ecf
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="cms" uuid="8CC0D052-57D1-4CAA-AFF1-448FA290734B" library_target="cms">
|
||||
<description>ROC CMS library</description>
|
||||
<target name="cms">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
@@ -12,6 +13,8 @@
|
||||
</option>
|
||||
<mapping old_name="CMS_LAYOUT" new_name="CMS_ENVIRONMENT"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms_app_env" location=".\library\app_env\app_env.ecf"/>
|
||||
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="config" location=".\library\configuration\config.ecf"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf" readonly="false"/>
|
||||
@@ -19,15 +22,14 @@
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http.ecf"/>
|
||||
<library name="i18n" location="$ISE_LIBRARY\library\i18n\i18n.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location=".\library\app_env\app_env.ecf"/>
|
||||
<library name="cms_model" location=".\library\model\cms_model.ecf" readonly="false"/>
|
||||
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty.ecf" readonly="false"/>
|
||||
<library name="text_filter" location="$ISE_LIBRARY\unstable\library\text\text_filter\text_filter.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<library name="uri_template" location="$ISE_LIBRARY\contrib\library\text\parser\uri_template\uri_template.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf.ecf"/>
|
||||
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension.ecf" readonly="false"/>
|
||||
<library name="wsf_html" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf_html\wsf_html.ecf" readonly="false"/>
|
||||
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf"/>
|
||||
<cluster name="src" location=".\src\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
<library name="cms_blog_module" location="modules\blog\cms_blog_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_demo_module" location="modules\demo\cms_demo_module-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="..\..\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="cms_login_module" location="..\..\modules\login\login-safe.ecf" readonly="false"/>
|
||||
<library name="cms_node_module" location="..\..\modules\node\node-safe.ecf" readonly="false"/>
|
||||
<library name="persistence_sqlite" location="..\..\library\persistence\sqlite\persistence_sqlite-safe.ecf" readonly="false"/>
|
||||
<library name="persistence_store_mysql" location="..\..\library\persistence\store_mysql\store_mysql-safe.ecf" readonly="false"/>
|
||||
<library name="persistence_store_odbc" location="..\..\library\persistence\store_odbc\store_odbc-safe.ecf" readonly="false"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="wsf_extension" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf_extension-safe.ecf" readonly="false"/>
|
||||
</target>
|
||||
@@ -38,6 +40,7 @@
|
||||
<option debug="true">
|
||||
<debug name="dbglog" enabled="true"/>
|
||||
</option>
|
||||
<variable name="httpd_ssl_disabled" value="true"/><!-- for now ... due to issue with libcurl+eiffelnet ssl -->
|
||||
<setting name="concurrency" value="thread"/>
|
||||
<library name="default_standalone" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\default\standalone-safe.ecf"/>
|
||||
<cluster name="launcher" location=".\launcher\default\" recursive="true"/>
|
||||
|
||||
@@ -68,10 +68,10 @@ feature {CMS_API} -- Module management
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
if not l_sql_storage.sql_table_exists ("blog_post_nodes") then
|
||||
sql := "[
|
||||
CREATE TABLE "blog_post_nodes"(
|
||||
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||
"revision" INTEGER,
|
||||
"tags" VARCHAR(255)
|
||||
CREATE TABLE blog_post_nodes(
|
||||
`nid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK("nid">=0),
|
||||
`revision` INTEGER,
|
||||
`tags` VARCHAR(255)
|
||||
);
|
||||
]"
|
||||
l_sql_storage.sql_execute_script (sql)
|
||||
|
||||
@@ -63,10 +63,10 @@ feature {CMS_API} -- Module management
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
if not l_sql_storage.sql_table_exists ("tb_demo") then
|
||||
sql := "[
|
||||
CREATE TABLE "tb_demo"(
|
||||
"demo_id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("demo_id">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"value" TEXT
|
||||
CREATE TABLE tb_demo(
|
||||
`demo_id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK("demo_id">=0),
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`value` TEXT
|
||||
);
|
||||
]"
|
||||
l_sql_storage.sql_execute_script (sql)
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
{
|
||||
"database": {
|
||||
"datasource": {
|
||||
"driver": "sqlite",
|
||||
"environment": "sqlite"
|
||||
"driver": "odbc",
|
||||
"environment": "odbc-sqlite"
|
||||
},
|
||||
"environments": {
|
||||
"sqlite": {
|
||||
"odbc-sqlite": {
|
||||
"connection_string":"Driver=SQLite3 ODBC Driver;Database=./site/database.sqlite;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;"
|
||||
},
|
||||
"test": {
|
||||
"connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;"
|
||||
"odbc-mysql": {
|
||||
"connection_string":"Driver=mysql ODBC Driver;Server=localhost;Port=3306;Database=roc;Uid=roc;Pwd=roc;"
|
||||
},
|
||||
"mysql": {
|
||||
"connection_string":"Driver=mysql;Server=localhost;Port=3306;Database=roc;Uid=roc;Pwd=roc;"
|
||||
},
|
||||
"development": {
|
||||
"connection_string":"Server=localhost;Port=3306;Database=cms_dev;Uid=root;Pwd=;"
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Activation</title>
|
||||
<meta name="description" content="Activation">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Thank you for registering at <a href="$host">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your registration, please click on this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>New Password</title>
|
||||
<meta name="description" content="New Password">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have required a new password at <a href="...">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your request, please click on this link to genereate a new password:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,18 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>New Activation</title>
|
||||
<meta name="description" content="New Activation token">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have request a new activation token at<a href="...">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your registration, please click on this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
13
examples/demo/site/config/modules/login/account_welcome.html
Normal file
13
examples/demo/site/config/modules/login/account_welcome.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Welcome</title>
|
||||
<meta name="description" content="Welcome">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
<body>
|
||||
<p>Welcome to<a href="...">ROC CMS</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
8
examples/demo/site/config/modules/login/login.json
Normal file
8
examples/demo/site/config/modules/login/login.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"email": "webmaster@example.com",
|
||||
"subjet_register": "Thank you for regitering with us, activate account",
|
||||
"subjet_activate": "New account ativation token",
|
||||
"subjet_password": "Password Recovery!!!",
|
||||
"subjet_oauth": "Welcome",
|
||||
"smtp": "127.0.0.1"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"api_secret":"ADD_YOUR_SECRET_KEY",
|
||||
"api_key":"ADD_YOUR_PUBLIC_KEY",
|
||||
"scope": "email",
|
||||
"api_revoke":"https://accounts.google.com/o/oauth2/revoke?token=$ACCESS_TOKEN",
|
||||
"protected_resource_url":"https://www.googleapis.com/plus/v1/people/me"
|
||||
}
|
||||
@@ -1,28 +1,23 @@
|
||||
BEGIN;
|
||||
|
||||
|
||||
CREATE TABLE "logs"(
|
||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("id">=0),
|
||||
"category" VARCHAR(255) NOT NULL,
|
||||
"level" INTEGER NOT NULL CHECK("level">=1),
|
||||
"uid" INTEGER,
|
||||
"message" TEXT NOT NULL,
|
||||
"info" TEXT,
|
||||
"link" TEXT,
|
||||
"date" DATETIME NOT NULL
|
||||
CREATE TABLE `logs`(
|
||||
`id` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`category` VARCHAR(255) NOT NULL,
|
||||
`level` INTEGER NOT NULL,
|
||||
`uid` INTEGER,
|
||||
`message` TEXT NOT NULL,
|
||||
`info` TEXT,
|
||||
`link` TEXT,
|
||||
`date` DATETIME NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE "custom_values"(
|
||||
"type" VARCHAR(255) NOT NULL,
|
||||
"name" VARCHAR(255) NOT NULL,
|
||||
"value" TEXT
|
||||
CREATE TABLE `custom_values`(
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`value` TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE "path_aliases"(
|
||||
"pid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("pid">=0),
|
||||
"source" VARCHAR(255) NOT NULL,
|
||||
"alias" VARCHAR(255) NOT NULL,
|
||||
"lang" VARCHAR(12)
|
||||
CREATE TABLE `path_aliases`(
|
||||
`pid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`source` VARCHAR(255) NOT NULL,
|
||||
`alias` VARCHAR(255) NOT NULL,
|
||||
`lang` VARCHAR(12)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,24 +1,22 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE "nodes" (
|
||||
"nid" INTEGER NOT NULL CHECK("nid" > 0) PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||
"revision" INTEGER,
|
||||
"type" TEXT NOT NULL,
|
||||
"title" VARCHAR(255) NOT NULL,
|
||||
"summary" TEXT,
|
||||
"content" TEXT,
|
||||
"format" VARCHAR(128),
|
||||
"author" INTEGER,
|
||||
"publish" DATETIME,
|
||||
"created" DATETIME NOT NULL,
|
||||
"changed" DATETIME NOT NULL,
|
||||
"status" INTEGER
|
||||
CREATE TABLE nodes (
|
||||
`nid` INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT UNIQUE,
|
||||
`revision` INTEGER,
|
||||
`type` TEXT NOT NULL,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`summary` TEXT,
|
||||
`content` TEXT,
|
||||
`format` VARCHAR(128),
|
||||
`author` INTEGER,
|
||||
`publish` DATETIME,
|
||||
`created` DATETIME NOT NULL,
|
||||
`changed` DATETIME NOT NULL,
|
||||
`status` INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE page_nodes(
|
||||
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||
"revision" INTEGER,
|
||||
"parent" INTEGER
|
||||
`nid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`revision` INTEGER,
|
||||
`parent` INTEGER
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
18
examples/demo/site/scripts/oauth2_consumers.sql
Normal file
18
examples/demo/site/scripts/oauth2_consumers.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
CREATE TABLE `oauth2_consumers`(
|
||||
`cid` INTEGER PRIMARY KEY NOT NULL CHECK(`cid`>=0),
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`api_secret` TEXT NOT NULL,
|
||||
`api_key` TEXT NOT NULL,
|
||||
`scope` VARCHAR (100) NOT NULL,
|
||||
`protected_resource_url` VARCHAR (255) NOT NULL,
|
||||
`callback_name` VARCHAR(255) NOT NULL,
|
||||
`extractor` VARCHAR(50) NOT NULL,
|
||||
`authorize_url` VARCHAR (255) NOT NULL,
|
||||
`endpoint` VARCHAR (255) NOT NULL,
|
||||
CONSTRAINT `cid`
|
||||
UNIQUE(`cid`),
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Change the values `TO_COMPLETE` based on your API.
|
||||
-- API SECTET KEY AND API PUBLIC KEY
|
||||
|
||||
INSERT INTO `oauth2_consumers` ("name", "api_secret", "api_key", "scope", "protected_resource_url", "callback_name", "extractor", "authorize_url", "endpoint")
|
||||
VALUES ("google", 'TO-COMPLETE', 'TO-COMPLETE', 'email', 'https://www.googleapis.com/plus/v1/people/me', "callback_google", "json","https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI","https://accounts.google.com/o/oauth2/token");
|
||||
INSERT INTO "oauth2_consumers" ("name", "api_secret", "api_key", "scope", "protected_resource_url", "callback_name", "extractor", "authorize_url", "endpoint" )
|
||||
VALUES ("facebook", 'TO-COMPLETE', 'TO-COMPLETE', 'email', 'https://graph.facebook.com/me', "callback_facebook","text","https://www.facebook.com/dialog/oauth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI","https://graph.facebook.com/oauth/access_token");
|
||||
10
examples/demo/site/scripts/oauth2_template.sql
Normal file
10
examples/demo/site/scripts/oauth2_template.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
CREATE TABLE :table_name (
|
||||
`uid` INTEGER PRIMARY KEY NOT NULL CHECK(`uid`>=0),
|
||||
`access_token` TEXT NOT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`details` TEXT NOT NULL,
|
||||
CONSTRAINT `uid`
|
||||
UNIQUE(`uid`)
|
||||
);
|
||||
|
||||
@@ -1,34 +1,48 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE "users"(
|
||||
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"password" VARCHAR(100) NOT NULL,
|
||||
"salt" VARCHAR(100) NOT NULL,
|
||||
"email" VARCHAR(250) NOT NULL,
|
||||
"status" INTEGER,
|
||||
CREATE TABLE `users`(
|
||||
`uid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`password` VARCHAR(100) NOT NULL,
|
||||
`salt` VARCHAR(100) NOT NULL,
|
||||
`email` VARCHAR(250) NOT NULL,
|
||||
`status` INTEGER,
|
||||
`created` DATETIME NOT NULL,
|
||||
`signed` DATETIME,
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `roles`(
|
||||
`rid` INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT `name`
|
||||
UNIQUE(`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `users_roles`(
|
||||
`uid` INTEGER NOT NULL CHECK(`uid`>=0),
|
||||
`rid` INTEGER NOT NULL CHECK(`rid`>=0)
|
||||
);
|
||||
|
||||
CREATE TABLE `role_permissions`(
|
||||
`rid` INTEGER NOT NULL,
|
||||
`permission` VARCHAR(255) NOT NULL,
|
||||
`module` VARCHAR(255)
|
||||
);
|
||||
|
||||
CREATE TABLE "users_activations" (
|
||||
"aid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK ("aid" >= 0),
|
||||
"token" VARCHAR(255) NOT NULL,
|
||||
"uid" INTEGER NOT NULL CHECK ("uid" >= 0),
|
||||
"created" DATETIME NOT NULL,
|
||||
"signed" DATETIME,
|
||||
CONSTRAINT "name"
|
||||
UNIQUE("name")
|
||||
CONSTRAINT "token" UNIQUE ("token")
|
||||
);
|
||||
|
||||
CREATE TABLE "roles"(
|
||||
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT "name"
|
||||
UNIQUE("name")
|
||||
CREATE TABLE "users_password_recovery" (
|
||||
"aid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK ("aid" >= 0),
|
||||
"token" VARCHAR(255) NOT NULL,
|
||||
"uid" INTEGER NOT NULL CHECK ("uid" >= 0),
|
||||
"created" DATETIME NOT NULL,
|
||||
CONSTRAINT "token" UNIQUE ("token")
|
||||
);
|
||||
|
||||
CREATE TABLE "users_roles"(
|
||||
"uid" INTEGER NOT NULL CHECK("uid">=0),
|
||||
"rid" INTEGER NOT NULL CHECK("rid">=0)
|
||||
);
|
||||
|
||||
CREATE TABLE "role_permissions"(
|
||||
"rid" INTEGER NOT NULL CHECK("rid">=0),
|
||||
"permission" VARCHAR(255) NOT NULL,
|
||||
"module" VARCHAR(255)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
var ROC_AUTH = ROC_AUTH || { };
|
||||
|
||||
var loginURL = "/login";
|
||||
var logoutURL = "/logoff";
|
||||
var loginURL = "/basic_auth_login";
|
||||
var logoutURL = "/basic_auth_logoff";
|
||||
|
||||
var userAgent = navigator.userAgent.toLowerCase();
|
||||
var firstLogIn = true;
|
||||
|
||||
@@ -305,3 +306,16 @@ ROC_AUTH.create_form = function() {
|
||||
};
|
||||
|
||||
|
||||
var password = document.getElementById("password")
|
||||
, confirm_password = document.getElementById("confirm_password");
|
||||
|
||||
ROC_AUTH.validatePassword =function(){
|
||||
if(password.value != confirm_password.value) {
|
||||
confirm_password.setCustomValidity("Passwords Don't Match");
|
||||
} else {
|
||||
confirm_password.setCustomValidity('');
|
||||
}
|
||||
}
|
||||
|
||||
password.onchange = ROC_AUTH.validatePassword();
|
||||
confirm_password.onkeyup = ROC_AUTH.validatePassword;
|
||||
@@ -0,0 +1,34 @@
|
||||
<div class="primary-tabs">
|
||||
{unless isset="$user"}
|
||||
<h3>Login or <a href="/account/roc-register">Register</a></h3>
|
||||
<div>
|
||||
<div>
|
||||
<form action method="POST">
|
||||
<div>
|
||||
<input type="text" name="username" required>
|
||||
<label>Username</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="password" name="password" required>
|
||||
<label>Password</label>
|
||||
</div>
|
||||
|
||||
<button type="button" onclick="ROC_AUTH.login();">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<p>
|
||||
<a href="/account/new-password">Forgot password?</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{foreach item="item" from="$oauth_consumers"}
|
||||
<a href="/account/login-with-oauth/{$item/}">Login with {$item/}</a><br>
|
||||
{/foreach}
|
||||
</div>
|
||||
{/unless}
|
||||
</div>
|
||||
@@ -0,0 +1,16 @@
|
||||
<div>
|
||||
<form action="/account/new-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Require new password</legend>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<label for="email">Email</label>
|
||||
{if isset="$error_email"}
|
||||
<span><i>{$error_email/}</i></span> <br>
|
||||
{/if}
|
||||
<br>
|
||||
</div>
|
||||
<button type="submit">Send</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>We have send you a new token code, check your email to generate a new password</p>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>We have send you a new activation code, check your email to activate your account.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>Thanks for register, check your email to activate your account.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
<div>
|
||||
<p>You new password has been saved!</p>
|
||||
</div>
|
||||
@@ -0,0 +1,19 @@
|
||||
<div>
|
||||
<form action="/account/reactivate" method="post">
|
||||
<fieldset>
|
||||
<legend>Reactivate Form</legend>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<label for="email">Email</label>
|
||||
{if isset="$error_email"}
|
||||
<span><i>{$error_email/}</i></span> <br>
|
||||
{/if}
|
||||
<br>
|
||||
{if isset="$is_active"}
|
||||
<span><i>{$is_active/}</i></span> <br>
|
||||
{/if}
|
||||
</div>
|
||||
<button type="submit">Reactivate</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
<div>
|
||||
<form action="/account/roc-register" method="post">
|
||||
<fieldset>
|
||||
<legend>Register Form</legend>
|
||||
<div>
|
||||
<input type="text" id="name" name="name" value="{$name/}" required autofocus />
|
||||
<label for="name">Name</label>
|
||||
{if isset="$error_name"}
|
||||
<span><i>{$error_name/}</i></span> <br>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" id="password" name="password" value="" required/>
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="email" id="email" name="email" value="{$email/}" required/>
|
||||
<label for="email">Email</label>
|
||||
{if isset="$error_email"}
|
||||
<span><i>{$error_email/}</i></span> <br>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
<button type="submit">Register</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -0,0 +1,28 @@
|
||||
<div>
|
||||
<form action="/account/reset-password" method="post">
|
||||
<fieldset>
|
||||
<legend>Generate New Password Form</legend>
|
||||
<div>
|
||||
<input type="text" id="token" name="token" value="{$token/}" required />
|
||||
<label for="token">Token</label>
|
||||
{if isset="$error_token"}
|
||||
<span><i>{$error_token/}</i></span> <br>
|
||||
{/if}
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" id="password" name="password" value="" required/>
|
||||
<label for="password">Password</label>
|
||||
</div>
|
||||
<div>
|
||||
<input type="password" id="confirm_password" name="confirm_password" value="" required/>
|
||||
<label for="password">Confirm Password</label>
|
||||
</div>
|
||||
|
||||
<button type="submit">Confirm</button>
|
||||
{if isset="$error_password"}
|
||||
<span><i>{$error_password/}</i></span> <br>
|
||||
{/if}
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
@@ -61,7 +61,7 @@
|
||||
<!-- Main Content Section -->
|
||||
{unless isempty="$page_title"}<h1 class="page-title">{$page_title/}</h1>{/unless}
|
||||
{$page.region_content/}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
@@ -46,8 +46,8 @@ feature -- CMS setup
|
||||
debug ("refactor_fixme")
|
||||
to_implement ("To implement custom storage")
|
||||
end
|
||||
-- a_setup.storage_drivers.force (create {CMS_STORAGE_MYSQL_BUILDER}.make, "mysql")
|
||||
a_setup.storage_drivers.force (create {CMS_STORAGE_SQLITE_BUILDER}.make, "sqlite")
|
||||
-- a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_MYSQL_BUILDER}.make, "mysql")
|
||||
a_setup.storage_drivers.force (create {CMS_STORAGE_STORE_ODBC_BUILDER}.make, "odbc")
|
||||
end
|
||||
|
||||
setup_modules (a_setup: CMS_SETUP)
|
||||
@@ -59,6 +59,10 @@ feature -- CMS setup
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {CMS_AUTHENTICATION_MODULE} m.make
|
||||
m.enable
|
||||
a_setup.register_module (m)
|
||||
|
||||
create {BASIC_AUTH_MODULE} m.make
|
||||
if not a_setup.module_with_same_type_registered (m) then
|
||||
m.enable
|
||||
|
||||
@@ -27,6 +27,7 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
ensure
|
||||
name_set: name = a_name
|
||||
status_not_active: status = not_active
|
||||
end
|
||||
|
||||
make_with_id (a_id: INTEGER_64)
|
||||
@@ -38,11 +39,13 @@ feature {NONE} -- Initialization
|
||||
initialize
|
||||
ensure
|
||||
id_set: id = a_id
|
||||
status_not_active: status = not_active
|
||||
end
|
||||
|
||||
initialize
|
||||
do
|
||||
create creation_date.make_now_utc
|
||||
mark_not_active
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
@@ -71,6 +74,13 @@ feature -- Access
|
||||
last_login_date: detachable DATE_TIME
|
||||
-- User last login.
|
||||
|
||||
status: INTEGER
|
||||
-- Associated status for the current user.
|
||||
-- default: not_active
|
||||
-- active
|
||||
-- trashed
|
||||
|
||||
|
||||
feature -- Roles
|
||||
|
||||
roles: detachable LIST [CMS_USER_ROLE]
|
||||
@@ -118,6 +128,12 @@ feature -- Status report
|
||||
Result := other /= Void and then id = other.id
|
||||
end
|
||||
|
||||
is_active: BOOLEAN
|
||||
-- is the current user active?
|
||||
do
|
||||
Result := status = {CMS_USER}.active
|
||||
end
|
||||
|
||||
feature -- Change element
|
||||
|
||||
set_id (a_id: like id)
|
||||
@@ -225,6 +241,52 @@ feature -- Change element: data
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status change
|
||||
|
||||
mark_not_active
|
||||
-- Set status to not_active
|
||||
do
|
||||
set_status (not_active)
|
||||
ensure
|
||||
status_not_active: status = not_active
|
||||
end
|
||||
|
||||
mark_active
|
||||
-- Set status to active.
|
||||
do
|
||||
set_status (active)
|
||||
ensure
|
||||
status_active: status = active
|
||||
end
|
||||
|
||||
mark_trashed
|
||||
-- Set status to trashed.
|
||||
do
|
||||
set_status (trashed)
|
||||
ensure
|
||||
status_trash: status = trashed
|
||||
end
|
||||
|
||||
set_status (a_status: like status)
|
||||
-- Assign `status' with `a_status'.
|
||||
do
|
||||
status := a_status
|
||||
ensure
|
||||
status_set: status = a_status
|
||||
end
|
||||
|
||||
|
||||
feature -- User status
|
||||
|
||||
not_active: INTEGER = 0
|
||||
-- The user is not active.
|
||||
|
||||
active: INTEGER = 1
|
||||
-- The user is active
|
||||
|
||||
Trashed: INTEGER = -1
|
||||
-- The user is trashed (soft delete), ready to be deleted/destroyed from storage.
|
||||
|
||||
invariant
|
||||
|
||||
id_or_name_set: id > 0 or else not name.is_whitespace
|
||||
|
||||
@@ -8,16 +8,16 @@ deferred class
|
||||
|
||||
feature -- Database access
|
||||
|
||||
hostname: STRING = ""
|
||||
default_hostname: STRING = ""
|
||||
-- Database hostname.
|
||||
|
||||
username: STRING = ""
|
||||
default_username: STRING = ""
|
||||
-- Database username.
|
||||
|
||||
password: STRING = ""
|
||||
default_password: STRING = ""
|
||||
-- Database password.
|
||||
|
||||
database_name: STRING = "EiffelDB"
|
||||
default_database_name: STRING = "EiffelDB"
|
||||
-- Database name.
|
||||
|
||||
is_keep_connection: BOOLEAN
|
||||
|
||||
@@ -12,27 +12,7 @@ inherit
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_common
|
||||
-- Create a database handler with common settings.
|
||||
deferred
|
||||
ensure
|
||||
db_application_not_void: db_application /= Void
|
||||
db_control_not_void: db_control /= Void
|
||||
end
|
||||
|
||||
make_basic ( a_database_name: STRING)
|
||||
-- Create a database handler with common settings and
|
||||
-- set database_name with `a_database_name'.
|
||||
require
|
||||
database_name_not_void: a_database_name /= Void
|
||||
database_name_not_empty: not a_database_name.is_empty
|
||||
deferred
|
||||
ensure
|
||||
db_application_not_void: db_application /= Void
|
||||
db_control_not_void: db_control /= Void
|
||||
end
|
||||
|
||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
|
||||
-- Create a database handler with user `a_username', password `a_password',
|
||||
-- host `a_hostname', database_name `a_database_name', and keep_connection `connection'.
|
||||
@@ -59,6 +39,26 @@ feature {NONE} -- Initialization
|
||||
db_control_not_void: db_control /= Void
|
||||
end
|
||||
|
||||
login_with_default
|
||||
-- Create a database handler with common settings.
|
||||
deferred
|
||||
ensure
|
||||
db_application_not_void: db_application /= Void
|
||||
db_control_not_void: db_control /= Void
|
||||
end
|
||||
|
||||
login_with_database_name ( a_database_name: STRING)
|
||||
-- Create a database handler with common settings and
|
||||
-- set database_name with `a_database_name'.
|
||||
require
|
||||
database_name_not_void: a_database_name /= Void
|
||||
database_name_not_empty: not a_database_name.is_empty
|
||||
deferred
|
||||
ensure
|
||||
db_application_not_void: db_application /= Void
|
||||
db_control_not_void: db_control /= Void
|
||||
end
|
||||
|
||||
feature -- Database Setup
|
||||
|
||||
db_application: DATABASE_APPL [DATABASE]
|
||||
@@ -168,7 +168,7 @@ feature -- Error Handling
|
||||
|
||||
database_error_handler: DATABASE_ERROR_HANDLER
|
||||
-- Error handler.
|
||||
|
||||
|
||||
feature -- Status Report
|
||||
|
||||
has_error: BOOLEAN
|
||||
@@ -179,11 +179,11 @@ feature -- Status Report
|
||||
|
||||
feature -- Helper
|
||||
|
||||
exception_as_error (a_e: like {EXCEPTION_MANAGER}.last_exception)
|
||||
-- Record exception as an error.
|
||||
exception_as_error (a_exception: like {EXCEPTION_MANAGER}.last_exception)
|
||||
-- Record exception `a_exception' as an error.
|
||||
do
|
||||
if attached a_e as l_e and then attached l_e.trace as l_trace then
|
||||
database_error_handler.add_error_details (l_e.code, once "Exception", l_trace.as_string_32)
|
||||
if a_exception /= Void and then attached a_exception.trace as l_trace then
|
||||
database_error_handler.add_error_details (a_exception.code, once "Exception", l_trace)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -15,11 +15,11 @@ inherit
|
||||
end
|
||||
|
||||
create
|
||||
make, make_common, make_basic
|
||||
login, login_with_default, login_with_database_name
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make_common
|
||||
login_with_default
|
||||
-- Create a database handler for ODBC with common settings.
|
||||
do
|
||||
create database_error_handler.make
|
||||
@@ -30,18 +30,18 @@ feature -- Initialization
|
||||
create db_control.make
|
||||
end
|
||||
|
||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
|
||||
-- Create a database handler for ODBC.
|
||||
do
|
||||
make_common
|
||||
login_with_default
|
||||
end
|
||||
|
||||
make_basic (a_database_name: STRING)
|
||||
login_with_database_name (a_database_name: STRING)
|
||||
|
||||
-- Create a database handler for ODBC.
|
||||
do
|
||||
make_common
|
||||
login_with_default
|
||||
end
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ feature -- Initialization
|
||||
-- Login with `a_connection_string'
|
||||
-- and immediately connect to database.
|
||||
do
|
||||
make_common
|
||||
login_with_default
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -7,117 +7,97 @@ class
|
||||
DATABASE_CONNECTION_ODBC
|
||||
|
||||
inherit
|
||||
|
||||
DATABASE_CONNECTION
|
||||
redefine
|
||||
db_application
|
||||
end
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make, make_common, make_basic, login_with_connection_string
|
||||
login, login_with_default, login_with_database_name, login_with_connection_string
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make_common
|
||||
-- Create a database handler for ODBC with common settings.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
create db_application.login (username, password)
|
||||
create database_error_handler.make
|
||||
if not l_retried then
|
||||
db_application.set_hostname (hostname)
|
||||
db_application.set_data_source (database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
end
|
||||
rescue
|
||||
create db_control.make
|
||||
-- set_last_error_from_exception ("Connection execution")
|
||||
-- write_critical_log (generator + ".make_common:" + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
make_basic (a_database_name: STRING)
|
||||
-- Create a database handler and
|
||||
-- set database_name to `a_database_name'.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
create db_application.login (username, password)
|
||||
create database_error_handler.make
|
||||
if not l_retried then
|
||||
db_application.set_hostname (hostname)
|
||||
db_application.set_data_source (a_database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
end
|
||||
rescue
|
||||
create db_control.make
|
||||
-- set_last_error_from_exception ("Connection execution")
|
||||
-- write_critical_log (generator + ".make_common:" + last_error_message)
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; a_keep_connection: BOOLEAN)
|
||||
|
||||
-- Create a database handler for ODBC and set `username' to `a_username',
|
||||
-- `password' to `a_password'
|
||||
-- `database_name' to `a_database_name'
|
||||
-- `connection' to `a_connection'
|
||||
-- `keep_connection' to `a_keep_connection'
|
||||
local
|
||||
retried: BOOLEAN
|
||||
l_database_error_handler: detachable like database_error_handler
|
||||
do
|
||||
create database_error_handler.make
|
||||
create l_database_error_handler.make
|
||||
database_error_handler := l_database_error_handler
|
||||
create db_application.login (a_username, a_password)
|
||||
db_application.set_hostname (a_hostname)
|
||||
db_application.set_data_source (a_database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := connection
|
||||
if keep_connection then
|
||||
connect
|
||||
if not retried then
|
||||
db_application.set_hostname (a_hostname)
|
||||
db_application.set_data_source (a_database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := a_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
end
|
||||
rescue
|
||||
if l_database_error_handler = Void then
|
||||
create l_database_error_handler.make
|
||||
end
|
||||
database_error_handler := l_database_error_handler
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
login_with_default
|
||||
-- Create a database handler for ODBC with common settings.
|
||||
do
|
||||
login_with_database_name (default_database_name)
|
||||
end
|
||||
|
||||
login_with_database_name (a_database_name: STRING)
|
||||
-- Create a database handler and
|
||||
-- set database_name to `a_database_name'.
|
||||
do
|
||||
login (default_username, default_password, default_hostname, default_database_name, is_keep_connection)
|
||||
end
|
||||
|
||||
login_with_connection_string (a_string: STRING)
|
||||
-- Login with `a_connection_string'and immediately connect to database.
|
||||
local
|
||||
retried: BOOLEAN
|
||||
l_database_error_handler: detachable like database_error_handler
|
||||
do
|
||||
write_debug_log (generator +".login_with_connection_string")
|
||||
create l_database_error_handler.make
|
||||
database_error_handler := l_database_error_handler
|
||||
create db_application.login_with_connection_string (a_string)
|
||||
create database_error_handler.make
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
write_debug_log (generator +".login_with_connection_string, is_keep_connection? "+ is_keep_connection.out )
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
if not db_control.is_ok then
|
||||
write_critical_log (generator +".login_with_connection_string:"+ db_control.error_code.out )
|
||||
write_critical_log (generator +".login_with_connection_string:"+ db_control.error_message_32 )
|
||||
if not retried then
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
if is_connected then
|
||||
disconnect
|
||||
end
|
||||
write_debug_log (generator +".login_with_connection_string, After connect, is_connected? "+ is_connected.out)
|
||||
end
|
||||
rescue
|
||||
if l_database_error_handler = Void then
|
||||
create l_database_error_handler.make
|
||||
end
|
||||
database_error_handler := l_database_error_handler
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
feature -- Databse Connection
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="persistence_mysql">
|
||||
<target name="persistence_mysql">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true" void_safety="none">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf" readonly="false"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="layout" location="..\..\layout\layout.ecf"/>
|
||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||
<library name="model" location="..\..\model\cms_model.ecf"/>
|
||||
<library name="mysql" location="$ISE_LIBRARY\library\store\dbms\rdbms\mysql\mysql.ecf"/>
|
||||
<library name="store" location="$ISE_LIBRARY\library\store\store.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="common" location="..\implementation\store\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/database/database_connection_odbc.e</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="persistence_mysql" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -1,3 +0,0 @@
|
||||
To build the MySQL schema use the schema.sql script.
|
||||
The other script will be deleted soon.
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
Added Stored Procedures
|
||||
30
library/persistence/mysql/scripts/core.sql
Normal file
30
library/persistence/mysql/scripts/core.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `logs` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`category` VARCHAR(255) NOT NULL,
|
||||
`level` int(11) NOT NULL,
|
||||
`uid` int(11) DEFAULT NULL,
|
||||
`message` text NOT NULL,
|
||||
`info` text,
|
||||
`link` text,
|
||||
`date` datetime NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
CREATE TABLE `custom_values` (
|
||||
`type` VARCHAR(255) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`value` VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE `path_aliases` (
|
||||
`pid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`source` varchar(255) NOT NULL,
|
||||
`alias` varchar(255) NOT NULL,
|
||||
`lang` varchar(12) DEFAULT NULL,
|
||||
PRIMARY KEY (`pid`)
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Schema mydb
|
||||
-- -----------------------------------------------------
|
||||
-- -----------------------------------------------------
|
||||
-- Schema cms_dev
|
||||
-- -----------------------------------------------------
|
||||
CREATE SCHEMA IF NOT EXISTS `cms_dev` DEFAULT CHARACTER SET latin1 ;
|
||||
USE `cms_dev` ;
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`users`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`users` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`username` VARCHAR(100) NOT NULL,
|
||||
`password` VARCHAR(100) NOT NULL,
|
||||
`salt` VARCHAR(100) NOT NULL,
|
||||
`email` VARCHAR(250) NOT NULL,
|
||||
`creation_date` DATETIME NULL DEFAULT NULL,
|
||||
`last_login_date` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `username` (`username` ASC))
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 2
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`nodes`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`nodes` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`publication_date` DATE NOT NULL,
|
||||
`creation_date` DATE NOT NULL,
|
||||
`modification_date` DATE NOT NULL,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`summary` TEXT NOT NULL,
|
||||
`content` MEDIUMTEXT NOT NULL,
|
||||
`author_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||
`version` INT(10) UNSIGNED ZEROFILL NULL DEFAULT NULL,
|
||||
`editor_id` INT(10) UNSIGNED NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `fk_nodes_users1_idx` (`author_id` ASC),
|
||||
INDEX `fk_nodes_users2_idx` (`editor_id` ASC),
|
||||
CONSTRAINT `fk_nodes_users1`
|
||||
FOREIGN KEY (`author_id`)
|
||||
REFERENCES `cms_dev`.`users` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION,
|
||||
CONSTRAINT `fk_nodes_users2`
|
||||
FOREIGN KEY (`editor_id`)
|
||||
REFERENCES `cms_dev`.`users` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
AUTO_INCREMENT = 11
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`roles`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`roles` (
|
||||
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`role` VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `role` (`role` ASC))
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`permissions`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`permissions` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(45) NOT NULL,
|
||||
`roles_id` INT(10) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `name_UNIQUE` (`name` ASC),
|
||||
INDEX `fk_permissions_roles1_idx` (`roles_id` ASC),
|
||||
CONSTRAINT `fk_permissions_roles1`
|
||||
FOREIGN KEY (`roles_id`)
|
||||
REFERENCES `cms_dev`.`roles` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`profiles`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`profiles` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`key` VARCHAR(45) NOT NULL,
|
||||
`value` VARCHAR(100) NULL DEFAULT NULL,
|
||||
`users_id` INT(10) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `key_UNIQUE` (`key` ASC),
|
||||
INDEX `fk_profiles_users1_idx` (`users_id` ASC),
|
||||
CONSTRAINT `fk_profiles_users1`
|
||||
FOREIGN KEY (`users_id`)
|
||||
REFERENCES `cms_dev`.`users` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`users_nodes`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`users_nodes` (
|
||||
`users_id` INT(10) UNSIGNED NOT NULL,
|
||||
`nodes_id` INT(10) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`users_id`, `nodes_id`),
|
||||
INDEX `fk_users_has_nodes_nodes1_idx` (`nodes_id` ASC),
|
||||
INDEX `fk_users_has_nodes_users_idx` (`users_id` ASC),
|
||||
CONSTRAINT `fk_users_has_nodes_nodes1`
|
||||
FOREIGN KEY (`nodes_id`)
|
||||
REFERENCES `cms_dev`.`nodes` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION,
|
||||
CONSTRAINT `fk_users_has_nodes_users`
|
||||
FOREIGN KEY (`users_id`)
|
||||
REFERENCES `cms_dev`.`users` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `cms_dev`.`users_roles`
|
||||
-- -----------------------------------------------------
|
||||
CREATE TABLE IF NOT EXISTS `cms_dev`.`users_roles` (
|
||||
`users_id` INT(10) UNSIGNED NOT NULL,
|
||||
`roles_id` INT(10) UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`users_id`, `roles_id`),
|
||||
INDEX `fk_users_has_roles_roles1_idx` (`roles_id` ASC),
|
||||
INDEX `fk_users_has_roles_users1_idx` (`users_id` ASC),
|
||||
CONSTRAINT `fk_users_has_roles_roles1`
|
||||
FOREIGN KEY (`roles_id`)
|
||||
REFERENCES `cms_dev`.`roles` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION,
|
||||
CONSTRAINT `fk_users_has_roles_users1`
|
||||
FOREIGN KEY (`users_id`)
|
||||
REFERENCES `cms_dev`.`users` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION)
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
SET SQL_MODE=@OLD_SQL_MODE;
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
24
library/persistence/mysql/scripts/node.sql
Normal file
24
library/persistence/mysql/scripts/node.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE nodes (
|
||||
nid INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK( nid >=0),
|
||||
revision INTEGER,
|
||||
type TEXT NOT NULL,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
summary TEXT,
|
||||
content MEDIUMTEXT NOT NULL,
|
||||
format VARCHAR(255),
|
||||
author INTEGER,
|
||||
publish DATETIME,
|
||||
created DATETIME NOT NULL,
|
||||
changed DATETIME NOT NULL,
|
||||
status INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE page_nodes(
|
||||
nid INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL CHECK( nid >=0),
|
||||
revision INTEGER,
|
||||
parent INTEGER
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
@@ -1,72 +0,0 @@
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Schema mydb
|
||||
-- -----------------------------------------------------
|
||||
-- -----------------------------------------------------
|
||||
-- Schema roc_cms
|
||||
-- -----------------------------------------------------
|
||||
DROP SCHEMA IF EXISTS `roc_cms` ;
|
||||
CREATE SCHEMA IF NOT EXISTS `roc_cms` DEFAULT CHARACTER SET latin1 ;
|
||||
USE `roc_cms` ;
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `roc_cms`.`nodes`
|
||||
-- -----------------------------------------------------
|
||||
DROP TABLE IF EXISTS `roc_cms`.`nodes` ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `roc_cms`.`nodes` (
|
||||
`nid` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`version` INT(11) NULL DEFAULT NULL,
|
||||
`type` INT(11) NULL DEFAULT NULL,
|
||||
`title` VARCHAR(255) NOT NULL,
|
||||
`summary` TEXT NOT NULL,
|
||||
`content` MEDIUMTEXT NOT NULL,
|
||||
`author` INT(11) NULL DEFAULT NULL,
|
||||
`publish` DATETIME NULL DEFAULT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`changed` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`nid`))
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `roc_cms`.`users`
|
||||
-- -----------------------------------------------------
|
||||
DROP TABLE IF EXISTS `roc_cms`.`users` ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `roc_cms`.`users` (
|
||||
`uid` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`password` VARCHAR(100) NOT NULL,
|
||||
`salt` VARCHAR(100) NOT NULL,
|
||||
`email` VARCHAR(250) NOT NULL,
|
||||
`status` INT(11) NULL DEFAULT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
`signed` DATETIME NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`uid`),
|
||||
UNIQUE INDEX `name` (`name` ASC))
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
-- -----------------------------------------------------
|
||||
-- Table `roc_cms`.`users_roles`
|
||||
-- -----------------------------------------------------
|
||||
DROP TABLE IF EXISTS `roc_cms`.`users_roles` ;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `roc_cms`.`users_roles` (
|
||||
`rid` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`role` VARCHAR(100) NOT NULL,
|
||||
PRIMARY KEY (`rid`),
|
||||
UNIQUE INDEX `role` (`role` ASC))
|
||||
ENGINE = InnoDB
|
||||
DEFAULT CHARACTER SET = latin1;
|
||||
|
||||
|
||||
SET SQL_MODE=@OLD_SQL_MODE;
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
@@ -1,14 +0,0 @@
|
||||
DROP TABLE IF EXISTS nodes;
|
||||
|
||||
CREATE TABLE nodes
|
||||
(
|
||||
id smallint unsigned NOT NULL auto_increment,
|
||||
publication_date date NOT NULL, #When the article was published
|
||||
creation_date date NOT NULL, #When the article was created
|
||||
modification_date date NOT NULL, #When the article was updated
|
||||
title varchar(255) NOT NULL, #Full title of the article
|
||||
summary text NOT NULL, #A short summary of the articule
|
||||
content mediumtext NOT NULL, #The HTML content of the article
|
||||
|
||||
PRIMARY KEY (ID)
|
||||
);
|
||||
@@ -1,8 +0,0 @@
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER update_editor
|
||||
AFTER INSERT ON `users_nodes` FOR EACH ROW
|
||||
UPDATE Nodes
|
||||
SET editor_id = NEW.users_id
|
||||
WHERE id = NEW.nodes_id;
|
||||
$$
|
||||
DELIMITER ;
|
||||
66
library/persistence/mysql/scripts/user.sql
Normal file
66
library/persistence/mysql/scripts/user.sql
Normal file
@@ -0,0 +1,66 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`uid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`password` varchar(100) NOT NULL,
|
||||
`salt` varchar(100) NOT NULL,
|
||||
`email` varchar(250) NOT NULL,
|
||||
`status` int(11) DEFAULT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
`signed` datetime DEFAULT NULL,
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`uid`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
);
|
||||
|
||||
CREATE TABLE `roles` (
|
||||
`rid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
CHECK (`rid` >= 0),
|
||||
PRIMARY KEY (`rid`),
|
||||
UNIQUE KEY `name` (`name`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_roles` (
|
||||
`uid` int(11) NOT NULL,
|
||||
`rid` int(11) NOT NULL,
|
||||
CHECK (`uid` >= 0),
|
||||
CHECK (`rid` >= 0)
|
||||
);
|
||||
|
||||
CREATE TABLE `role_permissions` (
|
||||
`rid` int(11) NOT NULL,
|
||||
`permission` varchar(255) NOT NULL,
|
||||
`module` varchar(255) DEFAULT NULL,
|
||||
CHECK (`rid` >= 0)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_activations` (
|
||||
`aid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`uid` int(11) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
CHECK (`aid` >= 0),
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`aid`),
|
||||
UNIQUE KEY `token` (`token`)
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE `users_password_recovery` (
|
||||
`aid` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`token` varchar(255) NOT NULL,
|
||||
`uid` int(11) NOT NULL,
|
||||
`created` datetime NOT NULL,
|
||||
CHECK (`aid` >= 0),
|
||||
CHECK (`uid` >= 0),
|
||||
PRIMARY KEY (`aid`),
|
||||
UNIQUE KEY `token` (`token`)
|
||||
);
|
||||
|
||||
|
||||
|
||||
COMMIT;
|
||||
@@ -1,29 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {CMS_STORAGE_MYSQL}."
|
||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||
revision: "$Revision: 96596 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_MYSQL
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL
|
||||
|
||||
CMS_CORE_STORAGE_SQL_I
|
||||
|
||||
CMS_USER_STORAGE_SQL_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Status report
|
||||
|
||||
is_initialized: BOOLEAN
|
||||
-- Is storage initialized?
|
||||
do
|
||||
Result := has_user
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,100 +0,0 @@
|
||||
note
|
||||
description: "Summary description for {ROLE_TEST_SET}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
ROLE_TEST_SET
|
||||
inherit
|
||||
EQA_TEST_SET
|
||||
redefine
|
||||
on_prepare,
|
||||
on_clean
|
||||
select
|
||||
default_create
|
||||
end
|
||||
ABSTRACT_DB_TEST
|
||||
rename
|
||||
default_create as default_db_test
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Events
|
||||
|
||||
on_prepare
|
||||
-- <Precursor>
|
||||
do
|
||||
(create {CLEAN_DB}).clean_db(connection)
|
||||
end
|
||||
|
||||
on_clean
|
||||
-- <Precursor>
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Test routines
|
||||
|
||||
test_roles_empty
|
||||
do
|
||||
assert ("Not elements",role_provider.roles.after)
|
||||
assert ("Count = 0", role_provider.count = 0)
|
||||
end
|
||||
|
||||
test_roles_by_id_not_exist
|
||||
do
|
||||
assert ("Void", role_provider.role (1) = Void)
|
||||
end
|
||||
|
||||
test_roles_by_name_not_exist
|
||||
do
|
||||
assert ("Void", role_provider.role_by_name ("admin") = Void)
|
||||
end
|
||||
|
||||
test_new_role
|
||||
do
|
||||
assert ("Count = 0", role_provider.count = 0)
|
||||
role_provider.new_role ("admin")
|
||||
assert ("Count = 1", role_provider.count = 1)
|
||||
assert ("Expected role", attached role_provider.role (1) as l_role and then l_role.name ~ "admin")
|
||||
assert ("Expected role", attached role_provider.role_by_name ("admin") as l_role and then l_role.id = 1)
|
||||
end
|
||||
|
||||
test_permissions_empty_not_exist_role
|
||||
do
|
||||
assert ("Not elements",role_provider.permission_by_role (1).after)
|
||||
end
|
||||
|
||||
test_permissions_empty_exist_role
|
||||
do
|
||||
assert ("Count = 0", role_provider.count = 0)
|
||||
role_provider.new_role ("admin")
|
||||
assert ("Count = 1", role_provider.count = 1)
|
||||
assert ("Exist role",not role_provider.roles.after)
|
||||
assert ("Not permission by role 1 elements",role_provider.permission_by_role (1).after)
|
||||
end
|
||||
|
||||
test_new_role_with_permissions
|
||||
do
|
||||
assert ("Count = 0", role_provider.count = 0)
|
||||
role_provider.new_role ("admin")
|
||||
role_provider.save_role_permission (1, "Create Page")
|
||||
role_provider.save_role_permission (1, "Edit Page")
|
||||
role_provider.save_role_permission (1, "Delete Page")
|
||||
assert ("Count = 1", role_provider.count = 1)
|
||||
assert ("Exist role",not role_provider.roles.after)
|
||||
assert ("Exist role permissions",not role_provider.permission_by_role (1).after)
|
||||
assert ("Not Exist role permissions, for id 2",role_provider.permission_by_role (2).after)
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
role_provider: ROLE_DATA_PROVIDER
|
||||
-- role provider.
|
||||
once
|
||||
create Result.make (connection)
|
||||
end
|
||||
end
|
||||
@@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_sqlite" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_sqlite">
|
||||
<target name="persistence_sqlite">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true" void_safety="none">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
</option>
|
||||
<setting name="console_application" value="true"/>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||
<library name="cms" location="..\..\..\cms.ecf"/>
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder.ecf"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error.ecf"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json.ecf" readonly="false"/>
|
||||
<library name="layout" location="..\..\layout\layout.ecf"/>
|
||||
<library name="logging" location="$ISE_LIBRARY\library\runtime\logging\logging.ecf"/>
|
||||
<library name="model" location="..\..\model\cms_model.ecf"/>
|
||||
<library name="odbc" location="$ISE_LIBRARY\library\store\dbms\rdbms\odbc\odbc.ecf"/>
|
||||
<library name="store" location="$ISE_LIBRARY\library\store\store.ecf" readonly="false"/>
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||
<cluster name="common" location="..\implementation\store\" recursive="true"/>
|
||||
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
</target>
|
||||
</system>
|
||||
@@ -1 +0,0 @@
|
||||
Added Stored Procedures
|
||||
@@ -1,36 +0,0 @@
|
||||
PRAGMA foreign_keys = OFF;
|
||||
|
||||
BEGIN;
|
||||
CREATE TABLE "users"(
|
||||
"uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("uid">=0),
|
||||
"name" VARCHAR(100) NOT NULL,
|
||||
"password" VARCHAR(100) NOT NULL,
|
||||
"salt" VARCHAR(100) NOT NULL,
|
||||
"email" VARCHAR(250) NOT NULL,
|
||||
"status" INTEGER,
|
||||
"created" DATETIME NOT NULL,
|
||||
"signed" DATETIME,
|
||||
CONSTRAINT "name"
|
||||
UNIQUE("name")
|
||||
);
|
||||
|
||||
CREATE TABLE "users_roles"(
|
||||
"rid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("rid">=0),
|
||||
"role" VARCHAR(100) NOT NULL,
|
||||
CONSTRAINT "role"
|
||||
UNIQUE("role")
|
||||
);
|
||||
|
||||
CREATE TABLE "nodes"(
|
||||
"nid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL CHECK("nid">=0),
|
||||
"version" INTEGER,
|
||||
"type" INTEGER,
|
||||
"title" VARCHAR(255) NOT NULL,
|
||||
"summary" TEXT NOT NULL,
|
||||
"content" MEDIUMTEXT NOT NULL,
|
||||
"author" INTEGER,
|
||||
"publish" DATETIME,
|
||||
"created" DATETIME NOT NULL,
|
||||
"changed" DATETIME NOT NULL
|
||||
);
|
||||
COMMIT;
|
||||
@@ -1,68 +0,0 @@
|
||||
note
|
||||
description: "[
|
||||
Interface responsible to instantiate CMS_STORAGE_SQLITE object.
|
||||
]"
|
||||
author: "$Author: jfiat $"
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_SQLITE_BUILDER
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL_BUILDER
|
||||
|
||||
GLOBAL_SETTINGS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Factory
|
||||
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_SQLITE
|
||||
local
|
||||
s: STRING
|
||||
conn: detachable DATABASE_CONNECTION
|
||||
do
|
||||
if
|
||||
attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config
|
||||
then
|
||||
s := "Driver=SQLite3 ODBC Driver;Database="
|
||||
if attached l_database_config.database_name as db_name then
|
||||
s.append (db_name)
|
||||
end
|
||||
s.append (";LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||
if attached reuseable_connection.item as d then
|
||||
if s.same_string (d.name) then
|
||||
conn := d.connection
|
||||
end
|
||||
end
|
||||
if conn = Void or else not conn.is_connected then
|
||||
create {DATABASE_CONNECTION_ODBC} conn.login_with_connection_string (s)
|
||||
reuseable_connection.replace ([s, conn])
|
||||
end
|
||||
if conn.is_connected then
|
||||
create Result.make (conn)
|
||||
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default.
|
||||
if Result.is_available then
|
||||
if not Result.is_initialized then
|
||||
initialize (a_setup, Result)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reuseable_connection: CELL [detachable TUPLE [name: STRING; connection: DATABASE_CONNECTION]]
|
||||
once
|
||||
create Result.put (Void)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,10 +1,10 @@
|
||||
note
|
||||
description: "Summary description for {CMS_STORAGE_SQLITE}."
|
||||
description: "Summary description for {CMS_STORAGE_STORE_MYSQL}."
|
||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||
revision: "$Revision: 96596 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_SQLITE
|
||||
CMS_STORAGE_STORE_MYSQL
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL
|
||||
@@ -26,4 +26,12 @@ feature -- Status report
|
||||
Result := has_user
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
sql_statement (a_statement: STRING): STRING
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := a_statement
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,13 +1,13 @@
|
||||
note
|
||||
description: "[
|
||||
Interface responsible to instantiate CMS_STORAGE_MYSQL object.
|
||||
Interface responsible to instantiate CMS_STORAGE_STORE_MYSQL object.
|
||||
]"
|
||||
author: "$Author: jfiat $"
|
||||
date: "$Date: 2015-01-27 19:15:02 +0100 (mar., 27 janv. 2015) $"
|
||||
revision: "$Revision: 96542 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_MYSQL_BUILDER
|
||||
CMS_STORAGE_STORE_MYSQL_BUILDER
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL_BUILDER
|
||||
@@ -26,7 +26,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
feature -- Factory
|
||||
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_MYSQL
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_MYSQL
|
||||
local
|
||||
conn: DATABASE_CONNECTION
|
||||
do
|
||||
@@ -14,66 +14,24 @@ inherit
|
||||
end
|
||||
|
||||
create
|
||||
make, make_common, make_basic, login_with_connection_string, login_with_schema
|
||||
login, login_with_default, login_with_database_name, login_with_connection_string, login_with_schema
|
||||
|
||||
feature -- Initialization
|
||||
|
||||
make_common
|
||||
login_with_default
|
||||
-- Create a database handler for MYSQL with common settings.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
create database_error_handler.make
|
||||
create db_application.login (username, password)
|
||||
|
||||
if not l_retried then
|
||||
db_application.set_hostname (hostname)
|
||||
db_application.set_data_source (database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
end
|
||||
rescue
|
||||
create database_error_handler.make
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
l_retried := True
|
||||
retry
|
||||
login_with_database_name (default_database_name)
|
||||
end
|
||||
|
||||
make_basic (a_database_name: STRING)
|
||||
login_with_database_name (a_database_name: STRING)
|
||||
-- Create a database handler and
|
||||
-- set database_name to `a_database_name'.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
create database_error_handler.make
|
||||
create db_application.login (username, password)
|
||||
|
||||
if not l_retried then
|
||||
db_application.set_hostname (hostname)
|
||||
db_application.set_data_source (a_database_name)
|
||||
db_application.set_base
|
||||
create db_control.make
|
||||
keep_connection := is_keep_connection
|
||||
if keep_connection then
|
||||
connect
|
||||
end
|
||||
else
|
||||
create db_control.make
|
||||
end
|
||||
rescue
|
||||
create database_error_handler.make
|
||||
exception_as_error ((create {EXCEPTION_MANAGER}).last_exception)
|
||||
l_retried := True
|
||||
retry
|
||||
login (default_username, default_password, default_hostname, a_database_name, is_keep_connection)
|
||||
end
|
||||
|
||||
make (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
login (a_username: STRING; a_password: STRING; a_hostname: STRING; a_database_name: STRING; connection: BOOLEAN)
|
||||
|
||||
-- Create a database handler for ODBC and set `username' to `a_username',
|
||||
-- `password' to `a_password'
|
||||
@@ -93,26 +51,23 @@ feature -- Initialization
|
||||
end
|
||||
|
||||
login_with_connection_string (a_string: STRING)
|
||||
-- Login with `a_connection_string'and immediately connect to database.
|
||||
-- Login with `a_connection_string' and immediately connect to database.
|
||||
local
|
||||
l_string: LIST[STRING]
|
||||
l_server: STRING
|
||||
l_port: STRING
|
||||
l_schema: STRING
|
||||
l_database: STRING
|
||||
l_user: STRING
|
||||
l_password: STRING
|
||||
do
|
||||
create database_error_handler.make
|
||||
|
||||
l_string := a_string.split (';')
|
||||
l_server := l_string.at (2).split ('=').at (2)
|
||||
l_port := l_string.at (3).split ('=').at (2)
|
||||
l_schema := l_string.at (4).split ('=').at (2)
|
||||
l_user := l_string.at (5).split ('=').at (2)
|
||||
l_password := l_string.at (6).split ('=').at (2)
|
||||
l_server := connection_string_item (a_string, "Server", default_hostname)
|
||||
l_database := connection_string_item (a_string, "Database", default_database_name)
|
||||
l_port := connection_string_item (a_string, "Port", "3306")
|
||||
l_user := connection_string_item (a_string, "Uid", default_username)
|
||||
l_password := connection_string_item (a_string, "Pwd", default_password)
|
||||
|
||||
create db_application
|
||||
db_application.set_application (l_schema)
|
||||
db_application.set_application (l_database)
|
||||
db_application.set_hostname (l_server + ":" + l_port)
|
||||
db_application.login_and_connect (l_user, l_password)
|
||||
db_application.set_base
|
||||
@@ -120,6 +75,26 @@ feature -- Initialization
|
||||
keep_connection := is_keep_connection
|
||||
end
|
||||
|
||||
connection_string_item (a_connection_string: STRING; k: STRING; dft: STRING): STRING
|
||||
local
|
||||
i,j: INTEGER
|
||||
do
|
||||
i := a_connection_string.substring_index (k + "=", 1)
|
||||
if i = 0 then
|
||||
i := a_connection_string.substring_index (k.as_lower + "=", 1)
|
||||
end
|
||||
if i > 0 then
|
||||
i := i + k.count + 1
|
||||
j := a_connection_string.index_of (';', i)
|
||||
if j = 0 then
|
||||
j := a_connection_string.count + 1
|
||||
end
|
||||
Result := a_connection_string.substring (i, j - 1)
|
||||
else
|
||||
Result := dft
|
||||
end
|
||||
end
|
||||
|
||||
login_with_schema (a_schema: STRING; a_username: STRING; a_password: STRING)
|
||||
-- Login with `a_connection_string'and immediately connect to database.
|
||||
do
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="persistence_mysql">
|
||||
<target name="persistence_mysql">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="store_mysql" uuid="DC757CBD-D8C4-44D6-A07F-C1148D8D233E" library_target="store_mysql">
|
||||
<target name="store_mysql">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true" void_safety="all">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
@@ -24,7 +24,7 @@
|
||||
<exclude>/database/database_connection_odbc.e</exclude>
|
||||
</file_rule>
|
||||
</cluster>
|
||||
<cluster name="persistence_mysql" location=".\src\" recursive="true">
|
||||
<cluster name="persistence_store_mysql" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
@@ -24,7 +24,7 @@ feature {NONE} -- Initialization
|
||||
|
||||
(create {CLEAN_DB}).clean_db(connection)
|
||||
|
||||
create {CMS_STORAGE_MYSQL} storage.make (connection)
|
||||
create {CMS_STORAGE_STORE_MYSQL} storage.make (connection)
|
||||
l_node := custom_node ("Content", "Summary", "Title")
|
||||
storage.new_user (default_user)
|
||||
storage.new_user (custom_user ("u2", "p2", "e2"))
|
||||
@@ -11,7 +11,7 @@
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
||||
<library name="module_node" location="..\..\..\..\modules\node\node-safe.ecf"/>
|
||||
<library name="persitence_mysql" location="..\persistence_mysql-safe.ecf" readonly="false"/>
|
||||
<library name="persitence_store_mysql" location="..\store_mysql-safe.ecf" readonly="false"/>
|
||||
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||
<cluster name="tests" location=".\" recursive="true">
|
||||
@@ -15,7 +15,7 @@ feature -- Database connection
|
||||
create Result.login_with_schema ("cms_dev", "root", "")
|
||||
end
|
||||
|
||||
storage: CMS_STORAGE_MYSQL
|
||||
storage: CMS_STORAGE_STORE_MYSQL
|
||||
once
|
||||
create Result.make (connection)
|
||||
end
|
||||
82
library/persistence/store_odbc/src/cms_storage_store_odbc.e
Normal file
82
library/persistence/store_odbc/src/cms_storage_store_odbc.e
Normal file
@@ -0,0 +1,82 @@
|
||||
note
|
||||
description: "Summary description for {CMS_STORAGE_STORE_ODBC}."
|
||||
date: "$Date: 2015-02-09 22:29:56 +0100 (lun., 09 févr. 2015) $"
|
||||
revision: "$Revision: 96596 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_STORE_ODBC
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL
|
||||
redefine
|
||||
make
|
||||
end
|
||||
|
||||
CMS_CORE_STORAGE_SQL_I
|
||||
|
||||
CMS_USER_STORAGE_SQL_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make,
|
||||
make_with_driver
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_connection: DATABASE_CONNECTION)
|
||||
-- <Precursor>
|
||||
do
|
||||
Precursor (a_connection)
|
||||
create odbc_driver.make_from_string_general ("odbc")
|
||||
end
|
||||
|
||||
make_with_driver (a_connection: DATABASE_CONNECTION; a_driver: detachable READABLE_STRING_GENERAL)
|
||||
require
|
||||
is_connected: a_connection.is_connected
|
||||
do
|
||||
make (a_connection)
|
||||
if a_driver /= Void then
|
||||
create odbc_driver.make_from_string_general (a_driver)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Status report
|
||||
|
||||
odbc_driver: IMMUTABLE_STRING_32
|
||||
-- Database's driver name.
|
||||
-- sqlite, mysql, ...
|
||||
|
||||
is_initialized: BOOLEAN
|
||||
-- Is storage initialized?
|
||||
do
|
||||
Result := has_user
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
sql_statement (a_statement: STRING): STRING
|
||||
-- <Precursor>.
|
||||
local
|
||||
i: INTEGER
|
||||
do
|
||||
Result := a_statement
|
||||
if odbc_driver.same_caseless_characters_general ("sqlite3", 1, 5, 1) then
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i = 0
|
||||
loop
|
||||
i := a_statement.substring_index ("AUTO_INCREMENT", i)
|
||||
if i > 0 then
|
||||
if Result = a_statement then
|
||||
create Result.make_from_string (a_statement)
|
||||
end
|
||||
Result.remove (i + 4)
|
||||
i := i + 14
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,68 @@
|
||||
note
|
||||
description: "[
|
||||
Interface responsible to instantiate CMS_STORAGE_STORE_ODBC object.
|
||||
]"
|
||||
author: "$Author: jfiat $"
|
||||
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
|
||||
revision: "$Revision: 96616 $"
|
||||
|
||||
class
|
||||
CMS_STORAGE_STORE_ODBC_BUILDER
|
||||
|
||||
inherit
|
||||
CMS_STORAGE_STORE_SQL_BUILDER
|
||||
|
||||
GLOBAL_SETTINGS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Initialize `Current'.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Factory
|
||||
|
||||
storage (a_setup: CMS_SETUP): detachable CMS_STORAGE_STORE_ODBC
|
||||
local
|
||||
s: detachable STRING
|
||||
conn: detachable DATABASE_CONNECTION
|
||||
do
|
||||
if
|
||||
attached (create {APPLICATION_JSON_CONFIGURATION_HELPER}).new_database_configuration (a_setup.environment.application_config_path) as l_database_config
|
||||
then
|
||||
if l_database_config.driver.is_case_insensitive_equal ("odbc") then
|
||||
s := l_database_config.database_string
|
||||
if attached reuseable_connection.item as d then
|
||||
if s.same_string (d.name) then
|
||||
conn := d.connection
|
||||
end
|
||||
end
|
||||
if conn = Void or else not conn.is_connected then
|
||||
create {DATABASE_CONNECTION_ODBC} conn.login_with_connection_string (s)
|
||||
reuseable_connection.replace ([s, conn])
|
||||
end
|
||||
if conn.is_connected then
|
||||
create Result.make_with_driver (conn, l_database_config.item ("Driver"))
|
||||
set_map_zero_null_value (False) --| This way we map 0 to 0, instead of Null as default.
|
||||
if Result.is_available then
|
||||
if not Result.is_initialized then
|
||||
initialize (a_setup, Result)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Wrong mapping between storage name and storage builder!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reuseable_connection: CELL [detachable TUPLE [name: STRING; connection: DATABASE_CONNECTION]]
|
||||
once
|
||||
create Result.put (Void)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_sqlite" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_sqlite">
|
||||
<target name="persistence_sqlite">
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="persistence_store_odbc" uuid="8FD9D3B3-5FC1-495F-A05D-0205EC966841" library_target="persistence_store_odbc">
|
||||
<target name="persistence_store_odbc">
|
||||
<root all_classes="true"/>
|
||||
<option warning="true" void_safety="all">
|
||||
<assertions precondition="true" postcondition="true" check="true" invariant="true" loop="true" supplier_precondition="true"/>
|
||||
@@ -20,7 +20,7 @@
|
||||
<library name="thread" location="$ISE_LIBRARY\library\thread\thread-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<cluster name="common" location="..\implementation\store\" recursive="true"/>
|
||||
<cluster name="persistence_sqlite" location=".\src\" recursive="true">
|
||||
<cluster name="persistence_store_odbc" location=".\src\" recursive="true">
|
||||
<file_rule>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/CVS$</exclude>
|
||||
@@ -17,11 +17,11 @@ feature {NONE} -- Initialization
|
||||
make
|
||||
-- Run application.
|
||||
local
|
||||
storage: CMS_STORAGE_SQLITE
|
||||
storage: CMS_STORAGE_STORE_ODBC
|
||||
do
|
||||
-- Change the path.
|
||||
create connection.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=./cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||
create storage.make (connection)
|
||||
create storage.make_with_driver (connection, "sqlite3")
|
||||
end
|
||||
|
||||
connection: DATABASE_CONNECTION_ODBC
|
||||
@@ -11,7 +11,7 @@
|
||||
<library name="crypto" location="$ISE_LIBRARY\unstable\library\text\encryption\crypto\crypto-safe.ecf"/>
|
||||
<library name="model" location="..\..\..\model\cms_model-safe.ecf"/>
|
||||
<library name="module_node" location="..\..\..\..\modules\node\node-safe.ecf"/>
|
||||
<library name="persitence_sqlite" location="..\persistence_sqlite-safe.ecf" readonly="false"/>
|
||||
<library name="persitence_store_odbc" location="..\store_odbc-safe.ecf" readonly="false"/>
|
||||
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
||||
<library name="testing" location="$ISE_LIBRARY\library\testing\testing-safe.ecf"/>
|
||||
<cluster name="tests" location=".\" recursive="true">
|
||||
@@ -12,8 +12,8 @@ feature -- Database connection
|
||||
connection: DATABASE_CONNECTION_ODBC
|
||||
-- odbc database connection
|
||||
once
|
||||
create Result.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=cms_lite.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||
-- create Result.make_basic ("cms_lite.db")
|
||||
create Result.login_with_connection_string ("Driver=SQLite3 ODBC Driver;Database=test_roc.db;LongNames=0;Timeout=1000;NoTXN=0;SyncPragma=NORMAL;StepAPI=0;")
|
||||
-- create Result.make_basic ("test_roc.db")
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
@@ -21,7 +21,7 @@ feature {NONE} -- Implementation
|
||||
storage: CMS_STORAGE
|
||||
-- node provider.
|
||||
once
|
||||
create {CMS_STORAGE_SQLITE} Result.make (connection)
|
||||
create {CMS_STORAGE_STORE_ODBC} Result.make_with_driver (connection, "sqlite3")
|
||||
end
|
||||
|
||||
feature {NONE} -- Fixture Factory: Users
|
||||
@@ -108,14 +108,14 @@ feature -- Hooks
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
do
|
||||
if attached a_response.current_user (a_response.request) as u then
|
||||
create lnk.make (u.name + " (Logout)", "basic_auth_logoff?destination=" + a_response.request.request_uri)
|
||||
else
|
||||
create lnk.make ("Login", "basic_auth_login?destination=" + a_response.request.request_uri)
|
||||
end
|
||||
-- if attached a_response.current_user (a_response.request) as u then
|
||||
-- create lnk.make (u.name + " (Logout)", "basic_auth_logoff?destination=" + a_response.request.request_uri)
|
||||
-- else
|
||||
-- create lnk.make ("Login", "basic_auth_login?destination=" + a_response.request.request_uri)
|
||||
-- end
|
||||
-- if not a_menu_system.primary_menu.has (lnk) then
|
||||
lnk.set_weight (99)
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
-- lnk.set_weight (99)
|
||||
-- a_menu_system.primary_menu.extend (lnk)
|
||||
-- end
|
||||
end
|
||||
|
||||
|
||||
@@ -55,21 +55,62 @@ feature -- HTTP Methods
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api)
|
||||
unset_current_user (req)
|
||||
l_page.set_status_code ({HTTP_STATUS_CODE}.found) -- Note: can not use {HTTP_STATUS_CODE}.unauthorized for redirection
|
||||
if attached {WSF_STRING} req.query_parameter ("destination") as l_uri then
|
||||
l_url := req.absolute_script_url (l_uri.url_encoded_value)
|
||||
else
|
||||
l_url := req.absolute_script_url ("")
|
||||
end
|
||||
l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized) -- Note: can not use {HTTP_STATUS_CODE}.unauthorized for redirection
|
||||
l_url := req.absolute_script_url ("")
|
||||
i := l_url.substring_index ("://", 1)
|
||||
if i > 0 then
|
||||
-- Note: this is a hack to have the logout effective on various browser
|
||||
-- (firefox requires this).
|
||||
l_url.replace_substring ("://_logout_basic_auth_@", i, i + 2)
|
||||
end
|
||||
l_page.set_redirection (l_url)
|
||||
if
|
||||
attached req.http_user_agent as l_user_agent and then
|
||||
browser_name (l_user_agent).is_case_insensitive_equal_general ("Firefox")
|
||||
then
|
||||
-- Set status to refirect
|
||||
-- and redirect to the host page.
|
||||
l_page.set_status_code ({HTTP_STATUS_CODE}.found)
|
||||
l_page.set_redirection (l_url)
|
||||
end
|
||||
l_page.execute
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
browser_name (a_user_agent: READABLE_STRING_8): READABLE_STRING_32
|
||||
-- Browser name.
|
||||
-- Must contain Must not contain
|
||||
-- Firefox Firefox/xyz Seamonkey/xyz
|
||||
-- Seamonkey Seamonkey/xyz
|
||||
-- Chrome Chrome/xyz Chromium/xyz
|
||||
-- Chromium Chromium/xyz
|
||||
-- Safari Safari/xyz Chrome/xyz
|
||||
-- Chromium/xyz
|
||||
-- Opera OPR/xyz [1]
|
||||
-- Opera/xyz [2]
|
||||
-- Internet Explorer ;MSIE xyz; Internet Explorer doesn't put its name in the BrowserName/VersionNumber format
|
||||
|
||||
do
|
||||
if
|
||||
a_user_agent.has_substring ("Firefox") and then
|
||||
not a_user_agent.has_substring ("Seamonkey")
|
||||
then
|
||||
Result := "Firefox"
|
||||
elseif a_user_agent.has_substring ("Seamonkey") then
|
||||
Result := "Seamonkey"
|
||||
elseif a_user_agent.has_substring ("Chrome") and then not a_user_agent.has_substring ("Chromium")then
|
||||
Result := "Chrome"
|
||||
elseif a_user_agent.has_substring ("Chromium") then
|
||||
Result := "Chromiun"
|
||||
elseif a_user_agent.has_substring ("Safari") and then not (a_user_agent.has_substring ("Chrome") or else a_user_agent.has_substring ("Chromium")) then
|
||||
Result := "Safari"
|
||||
elseif a_user_agent.has_substring ("OPR") or else a_user_agent.has_substring ("Opera") then
|
||||
Result := "Opera"
|
||||
elseif a_user_agent.has_substring ("MSIE") or else a_user_agent.has_substring ("Trident")then
|
||||
Result := "Internet Explorer"
|
||||
else
|
||||
Result := "Unknown"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
13
modules/login/cms_authentication_constants.e
Normal file
13
modules/login/cms_authentication_constants.e
Normal file
@@ -0,0 +1,13 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_CONSTANTS}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_CONSTANTS
|
||||
|
||||
feature -- Access
|
||||
|
||||
oauth_session: STRING = "EWF_ROC_OAUTH_TOKEN_"
|
||||
|
||||
end
|
||||
268
modules/login/cms_authentication_email_service_parameters.e
Normal file
268
modules/login/cms_authentication_email_service_parameters.e
Normal file
@@ -0,0 +1,268 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
|
||||
|
||||
inherit
|
||||
EMAIL_SERVICE_PARAMETERS
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_cms_api: CMS_API)
|
||||
local
|
||||
utf: UTF_CONVERTER
|
||||
l_site_name: READABLE_STRING_8
|
||||
s: detachable READABLE_STRING_32
|
||||
l_contact_email, l_subject_register, l_subject_activate, l_subject_password, l_subject_oauth: detachable READABLE_STRING_8
|
||||
do
|
||||
setup := a_cms_api.setup
|
||||
-- Use global smtp setting if any, otherwise "localhost"
|
||||
smtp_server := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.text_item_or_default ("smtp", "localhost"))
|
||||
l_site_name := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.site_name)
|
||||
admin_email := a_cms_api.setup.site_email
|
||||
|
||||
if not admin_email.has ('<') then
|
||||
admin_email := l_site_name + " <" + admin_email +">"
|
||||
end
|
||||
|
||||
if attached {CONFIG_READER} a_cms_api.module_configuration ("login", Void) as cfg then
|
||||
if attached cfg.text_item ("smtp") as l_smtp then
|
||||
-- Overwrite global smtp setting if any.
|
||||
smtp_server := utf.utf_32_string_to_utf_8_string_8 (l_smtp)
|
||||
end
|
||||
s := cfg.text_item ("email")
|
||||
if s /= Void then
|
||||
l_contact_email := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
s := cfg.text_item ("subject_register")
|
||||
if s /= Void then
|
||||
l_subject_register := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
s := cfg.text_item ("subject_activate")
|
||||
if s /= Void then
|
||||
l_subject_register := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
s := cfg.text_item ("subject_password")
|
||||
if s /= Void then
|
||||
l_subject_register := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
s := cfg.text_item ("subject_oauth")
|
||||
if s /= Void then
|
||||
l_subject_oauth := utf.utf_32_string_to_utf_8_string_8 (s)
|
||||
end
|
||||
|
||||
end
|
||||
if l_contact_email /= Void then
|
||||
if not l_contact_email.has ('<') then
|
||||
l_contact_email := l_site_name + " <" + l_contact_email + ">"
|
||||
end
|
||||
contact_email := l_contact_email
|
||||
else
|
||||
contact_email := admin_email
|
||||
end
|
||||
if l_subject_register /= Void then
|
||||
contact_subject_register := l_subject_register
|
||||
else
|
||||
contact_subject_register := "Thank you for registering with us."
|
||||
end
|
||||
|
||||
if l_subject_activate /= Void then
|
||||
contact_subject_activate := l_subject_activate
|
||||
else
|
||||
contact_subject_activate := "New account activation token."
|
||||
end
|
||||
if l_subject_password /= Void then
|
||||
contact_subject_password := l_subject_password
|
||||
else
|
||||
contact_subject_password := "Password Recovery."
|
||||
end
|
||||
if l_subject_oauth /= Void then
|
||||
contact_subject_oauth := l_subject_oauth
|
||||
else
|
||||
contact_subject_oauth := "Welcome."
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
smtp_server: IMMUTABLE_STRING_8
|
||||
|
||||
admin_email: IMMUTABLE_STRING_8
|
||||
|
||||
contact_email: IMMUTABLE_STRING_8
|
||||
-- Contact email.
|
||||
|
||||
contact_subject_register: IMMUTABLE_STRING_8
|
||||
contact_subject_activate: IMMUTABLE_STRING_8
|
||||
contact_subject_password: IMMUTABLE_STRING_8
|
||||
contact_subject_oauth: IMMUTABLE_STRING_8
|
||||
|
||||
|
||||
|
||||
account_activation: STRING
|
||||
-- Account activation template email message.
|
||||
local
|
||||
p: PATH
|
||||
do
|
||||
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_activation.html")
|
||||
if attached read_template_file (p) as l_content then
|
||||
Result := l_content
|
||||
else
|
||||
create Result.make_from_string (template_account_activation)
|
||||
end
|
||||
end
|
||||
|
||||
account_re_activation: STRING
|
||||
-- Account re_activation template email message.
|
||||
local
|
||||
p: PATH
|
||||
do
|
||||
p := setup.environment.config_path.extended ("modules").extended ("login").extended("accunt_re_activation.html")
|
||||
if attached read_template_file (p) as l_content then
|
||||
Result := l_content
|
||||
else
|
||||
create Result.make_from_string (template_account_re_activation)
|
||||
end
|
||||
end
|
||||
|
||||
account_password: STRING
|
||||
-- Account password template email message.
|
||||
local
|
||||
p: PATH
|
||||
do
|
||||
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_new_password.html")
|
||||
if attached read_template_file (p) as l_content then
|
||||
Result := l_content
|
||||
else
|
||||
create Result.make_from_string (template_account_new_password)
|
||||
end
|
||||
end
|
||||
|
||||
account_welcome: STRING
|
||||
-- Account welcome template email message.
|
||||
local
|
||||
p: PATH
|
||||
do
|
||||
p := setup.environment.config_path.extended ("modules").extended ("login").extended("account_welcome.html")
|
||||
if attached read_template_file (p) as l_content then
|
||||
Result := l_content
|
||||
else
|
||||
create Result.make_from_string (template_account_welcome)
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
setup: CMS_SETUP
|
||||
|
||||
|
||||
read_template_file (a_path: PATH): detachable STRING
|
||||
-- Read the content of the file at path `a_path'.
|
||||
local
|
||||
l_file: FILE
|
||||
do
|
||||
create {PLAIN_TEXT_FILE} l_file.make_with_path (a_path)
|
||||
if l_file.exists and then l_file.is_readable then
|
||||
l_file.open_read
|
||||
l_file.read_stream (l_file.count)
|
||||
Result := l_file.last_string
|
||||
l_file.close
|
||||
else
|
||||
-- Error
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature {NONE} -- Message email
|
||||
|
||||
template_account_activation: STRING= "[
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Activation</title>
|
||||
<meta name="description" content="Activation">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Thank you for registering at <a href="...">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your registration, please click on this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
]"
|
||||
|
||||
|
||||
template_account_re_activation: STRING= "[
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>New Activation</title>
|
||||
<meta name="description" content="New Activation token">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have request a new activation token at<a href="...">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your registration, please click on this link to activate your account:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
]"
|
||||
|
||||
|
||||
|
||||
template_account_new_password: STRING= "[
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>New Password</title>
|
||||
<meta name="description" content="New Password">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>You have required a new password at <a href="...">ROC CMS</a></p>
|
||||
|
||||
<p>To complete your request, please click on this link to genereate a new password:<p>
|
||||
|
||||
<p><a href="$link">$link</a></p>
|
||||
</body>
|
||||
</html>
|
||||
]"
|
||||
|
||||
|
||||
template_account_welcome: STRING= "[
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Welcome</title>
|
||||
<meta name="description" content="Welcome">
|
||||
<meta name="author" content="ROC CMS">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>Welcome to<a href="...">ROC CMS</a></p>
|
||||
<p>Thank you for joining us.</p>
|
||||
</body>
|
||||
</html>
|
||||
]"
|
||||
|
||||
end
|
||||
890
modules/login/cms_authentication_module.e
Normal file
890
modules/login/cms_authentication_module.e
Normal file
@@ -0,0 +1,890 @@
|
||||
note
|
||||
description: "Module Logging supporting different authentication strategies"
|
||||
date: "$Date: 2015-05-20 06:50:50 -0300 (mi. 20 de may. de 2015) $"
|
||||
revision: "$Revision: 97328 $"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATION_MODULE
|
||||
|
||||
inherit
|
||||
CMS_MODULE
|
||||
rename
|
||||
module_api as user_oauth_api
|
||||
redefine
|
||||
filters,
|
||||
register_hooks,
|
||||
initialize,
|
||||
is_installed,
|
||||
install,
|
||||
user_oauth_api
|
||||
end
|
||||
|
||||
|
||||
CMS_HOOK_BLOCK
|
||||
|
||||
CMS_HOOK_AUTO_REGISTER
|
||||
|
||||
CMS_HOOK_MENU_SYSTEM_ALTER
|
||||
|
||||
CMS_HOOK_VALUE_TABLE_ALTER
|
||||
|
||||
SHARED_EXECUTION_ENVIRONMENT
|
||||
export
|
||||
{NONE} all
|
||||
end
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
CMS_REQUEST_UTIL
|
||||
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make
|
||||
-- Create current module
|
||||
do
|
||||
name := "login"
|
||||
version := "1.0"
|
||||
description := "Eiffel login module"
|
||||
package := "login"
|
||||
|
||||
create root_dir.make_current
|
||||
cache_duration := 0
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module Initialization
|
||||
|
||||
initialize (a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_user_auth_api: like user_oauth_api
|
||||
l_user_auth_storage: CMS_OAUTH_20_STORAGE_I
|
||||
do
|
||||
Precursor (a_api)
|
||||
|
||||
-- Storage initialization
|
||||
if attached {CMS_STORAGE_SQL_I} a_api.storage as l_storage_sql then
|
||||
create {CMS_OAUTH_20_STORAGE_SQL} l_user_auth_storage.make (l_storage_sql)
|
||||
else
|
||||
-- FIXME: in case of NULL storage, should Current be disabled?
|
||||
create {CMS_OAUTH_20_STORAGE_NULL} l_user_auth_storage
|
||||
end
|
||||
|
||||
-- Node API initialization
|
||||
create l_user_auth_api.make_with_storage (a_api, l_user_auth_storage)
|
||||
user_oauth_api := l_user_auth_api
|
||||
ensure then
|
||||
user_oauth_api_set: user_oauth_api /= Void
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
is_installed (api: CMS_API): BOOLEAN
|
||||
-- Is Current module installed?
|
||||
do
|
||||
Result := attached api.storage.custom_value ("is_initialized", "module-" + name) as v and then v.is_case_insensitive_equal_general ("yes")
|
||||
end
|
||||
|
||||
install (api: CMS_API)
|
||||
local
|
||||
l_setup: CMS_SETUP
|
||||
l_params: detachable STRING_TABLE [detachable ANY]
|
||||
l_consumers: LIST [STRING]
|
||||
do
|
||||
l_setup := api.setup
|
||||
|
||||
-- Schema
|
||||
if attached {CMS_STORAGE_SQL_I} api.storage as l_sql_storage then
|
||||
if not l_sql_storage.sql_table_exists ("oauth2_consumers") then
|
||||
--| Schema
|
||||
l_sql_storage.sql_execute_file_script (l_setup.environment.path.extended ("scripts").extended ("oauth2_consumers.sql"))
|
||||
|
||||
if l_sql_storage.has_error then
|
||||
api.logger.put_error ("Could not initialize database for blog module", generating_type)
|
||||
end
|
||||
-- TODO workaround.
|
||||
l_sql_storage.sql_execute_file_script (l_setup.environment.path.extended ("scripts").extended ("oauth2_consumers_initialize.sql"))
|
||||
end
|
||||
|
||||
-- TODO workaround, until we have an admin module
|
||||
l_sql_storage.sql_query ("SELECT name FROM oauth2_consumers;", Void)
|
||||
if l_sql_storage.has_error then
|
||||
api.logger.put_error ("Could not initialize database for differnent consumerns", generating_type)
|
||||
else
|
||||
from
|
||||
l_sql_storage.sql_start
|
||||
create {ARRAYED_LIST[STRING]} l_consumers.make (2)
|
||||
until
|
||||
l_sql_storage.sql_after
|
||||
loop
|
||||
if attached l_sql_storage.sql_read_string (1) as l_name then
|
||||
l_consumers.force ("oauth2_"+l_name)
|
||||
end
|
||||
l_sql_storage.sql_forth
|
||||
end
|
||||
across l_consumers as ic loop
|
||||
if not l_sql_storage.sql_table_exists (ic.item) then
|
||||
create l_params.make (1)
|
||||
l_params.force (ic.item, "table_name")
|
||||
l_sql_storage.sql_execute_file_script_with_params (l_setup.environment.path.extended ("scripts").extended ("oauth2_template.sql"), l_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
api.storage.set_custom_value ("is_initialized", "module-" + name, "yes")
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Access: API
|
||||
|
||||
user_oauth_api: detachable CMS_OAUTH_20_API
|
||||
-- <Precursor>
|
||||
|
||||
feature -- Filters
|
||||
|
||||
filters (a_api: CMS_API): detachable LIST [WSF_FILTER]
|
||||
-- Possibly list of Filter's module.
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (1)
|
||||
if attached user_oauth_api as l_user_oauth_api then
|
||||
Result.extend (create {CMS_OAUTH_20_FILTER}.make (a_api, l_user_oauth_api))
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access: docs
|
||||
|
||||
root_dir: PATH
|
||||
|
||||
cache_duration: INTEGER
|
||||
-- Caching duration
|
||||
--| 0: disable
|
||||
--| -1: cache always valie
|
||||
--| nb: cache expires after nb seconds.
|
||||
|
||||
cache_disabled: BOOLEAN
|
||||
do
|
||||
Result := cache_duration = 0
|
||||
end
|
||||
|
||||
feature -- Router
|
||||
|
||||
|
||||
setup_router (a_router: WSF_ROUTER; a_api: CMS_API)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached user_oauth_api as l_user_oauth_api then
|
||||
configure_web (a_api, l_user_oauth_api, a_router)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
configure_web (a_api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API; a_router: WSF_ROUTER)
|
||||
do
|
||||
a_router.handle ("/account/roc-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation (a_api, ?, ?)), a_router.methods_head_get)
|
||||
a_router.handle ("/account/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/login-with-oauth/{callback}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_login_with_oauth (a_api,a_user_oauth_api, ?, ?)), a_router.methods_get_post)
|
||||
a_router.handle ("/account/{callback}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_callback_oauth (a_api, a_user_oauth_api, ?, ?)), a_router.methods_get_post)
|
||||
end
|
||||
|
||||
|
||||
feature -- Hooks configuration
|
||||
|
||||
register_hooks (a_response: CMS_RESPONSE)
|
||||
-- Module hooks configuration.
|
||||
do
|
||||
auto_subscribe_to_hooks (a_response)
|
||||
a_response.subscribe_to_block_hook (Current)
|
||||
a_response.subscribe_to_value_table_alter_hook (Current)
|
||||
end
|
||||
|
||||
feature -- Hooks
|
||||
|
||||
value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE)
|
||||
-- <Precursor>
|
||||
do
|
||||
if attached current_user (a_response.request) as l_user then
|
||||
a_value.force (l_user, "user")
|
||||
end
|
||||
end
|
||||
|
||||
menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE)
|
||||
-- Hook execution on collection of menu contained by `a_menu_system'
|
||||
-- for related response `a_response'.
|
||||
local
|
||||
lnk: CMS_LOCAL_LINK
|
||||
do
|
||||
if attached a_response.current_user (a_response.request) as u then
|
||||
create lnk.make (u.name + " (Logout)", "account/roc-logout" )
|
||||
else
|
||||
create lnk.make ("Login", "account/roc-login")
|
||||
end
|
||||
a_menu_system.primary_menu.extend (lnk)
|
||||
lnk.set_weight (98)
|
||||
end
|
||||
|
||||
block_list: ITERABLE [like {CMS_BLOCK}.name]
|
||||
local
|
||||
l_string: STRING
|
||||
do
|
||||
Result := <<"login","register","reactivate","new_password", "reset_password">>
|
||||
create l_string.make_empty
|
||||
across Result as ic loop
|
||||
l_string.append (ic.item)
|
||||
l_string.append_character (' ')
|
||||
end
|
||||
write_debug_log (generator + ".block_list:" + l_string )
|
||||
end
|
||||
|
||||
get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if
|
||||
a_block_id.is_case_insensitive_equal_general ("login") and then
|
||||
a_response.request.path_info.starts_with ("/account/roc-login")
|
||||
then
|
||||
get_block_view_login (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("register") and then
|
||||
a_response.request.path_info.starts_with ("/account/roc-register")
|
||||
then
|
||||
get_block_view_register (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reactivate") and then
|
||||
a_response.request.path_info.starts_with ("/account/reactivate")
|
||||
then
|
||||
get_block_view_reactivate (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("new_password") and then
|
||||
a_response.request.path_info.starts_with ("/account/new-password")
|
||||
then
|
||||
get_block_view_new_password (a_block_id, a_response)
|
||||
elseif
|
||||
a_block_id.is_case_insensitive_equal_general ("reset_password") and then
|
||||
a_response.request.path_info.starts_with ("/account/reset-password")
|
||||
then
|
||||
get_block_view_reset_password (a_block_id, a_response)
|
||||
end
|
||||
end
|
||||
|
||||
handle_login (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Login", "optional_content_type")
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_logout (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_url: STRING
|
||||
l_cookie: WSF_COOKIE
|
||||
do
|
||||
if
|
||||
attached {WSF_STRING} req.cookie ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session) as l_cookie_token and then
|
||||
attached {CMS_USER} current_user (req) as l_user
|
||||
then
|
||||
-- Logout gmail
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session, l_cookie_token.value)
|
||||
l_cookie.set_path ("/")
|
||||
l_cookie.set_max_age (-1)
|
||||
res.add_cookie (l_cookie)
|
||||
unset_current_user (req)
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
r.execute
|
||||
else
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_status_code ({HTTP_CONSTANTS}.found)
|
||||
l_url := req.absolute_script_url ("")
|
||||
l_url.append ("/basic_auth_logoff")
|
||||
r.set_redirection (l_url)
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
handle_register (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
u: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_exist: BOOLEAN
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
l_link: STRING
|
||||
l_token: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_value ("Register", "optional_content_type")
|
||||
if req.is_post_request_method then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("name") as l_name and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("email") as l_email
|
||||
then
|
||||
l_user_api := api.user_api
|
||||
|
||||
if attached l_user_api.user_by_name (l_name.value) then
|
||||
-- Username already exist.
|
||||
r.values.force ("The user name exist!", "error_name")
|
||||
l_exist := True
|
||||
end
|
||||
if attached l_user_api.user_by_email (l_email.value) then
|
||||
-- Emails already exist.
|
||||
r.values.force ("The email exist!", "error_email")
|
||||
l_exist := True
|
||||
end
|
||||
|
||||
if not l_exist then
|
||||
-- New user
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1)
|
||||
l_roles.force (l_user_api.authenticated_user_role)
|
||||
|
||||
create u.make (l_name.value)
|
||||
u.set_email (l_email.value)
|
||||
u.set_password (l_password.value)
|
||||
u.set_roles (l_roles)
|
||||
l_user_api.new_user (u)
|
||||
|
||||
-- Create activation token
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, u.id)
|
||||
create l_link.make_from_string (req.server_url)
|
||||
l_link.append ("/account/activate/")
|
||||
l_link.append (l_token)
|
||||
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_email")
|
||||
es.send_contact_email (l_email.value, l_link)
|
||||
|
||||
else
|
||||
r.values.force (l_name.value, "name")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_activation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE
|
||||
do
|
||||
l_user_api := api.user_api
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if attached {WSF_STRING} req.path_parameter ("token") as l_token then
|
||||
|
||||
if attached {CMS_USER} l_user_api.user_by_activation_token (l_token.value) as l_user then
|
||||
-- Valid user_id
|
||||
l_user.mark_active
|
||||
l_user_api.update_user (l_user)
|
||||
l_user_api.remove_activation (l_token.value)
|
||||
r.set_value ("Account activated", "optional_content_type")
|
||||
r.set_main_content ("<p> Your account <i>"+ l_user.name +"</i> has been activated</p>")
|
||||
else
|
||||
-- the token does not exist, or it was already used.
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
r.set_value ("Account not activated", "optional_content_type")
|
||||
r.set_main_content ("<p>The token <i>"+ l_token.value +"</i> is not valid <a href=%"/account/reactivate%">Reactivate Account</a></p>" )
|
||||
|
||||
end
|
||||
r.execute
|
||||
else
|
||||
create l_ir.make (req, res, api)
|
||||
l_ir.execute
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
l_user_api: CMS_USER_API
|
||||
l_token: STRING
|
||||
l_link: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if req.is_post_request_method then
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("email") as l_email
|
||||
then
|
||||
l_user_api := api.user_api
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
if l_user.is_active then
|
||||
r.values.force ("The asociated user to the given email " + l_email.value + " , is already active", "is_active")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
else
|
||||
l_token := new_token
|
||||
l_user_api.new_activation (l_token, l_user.id)
|
||||
create l_link.make_from_string (req.server_url)
|
||||
l_link.append ("/account/activate/")
|
||||
l_link.append (l_token)
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_activation_email")
|
||||
es.send_contact_activation_email (l_email.value, l_link)
|
||||
end
|
||||
else
|
||||
r.values.force ("The email does not exist or !", "error_email")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
r.execute
|
||||
end
|
||||
|
||||
handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
l_user_api: CMS_USER_API
|
||||
l_token: STRING
|
||||
l_link: STRING
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
if req.is_post_request_method then
|
||||
l_user_api := api.user_api
|
||||
if attached {WSF_STRING} req.form_parameter ("email") as l_email then
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then
|
||||
-- User exist create a new token and send a new email.
|
||||
l_token := new_token
|
||||
l_user_api.new_password (l_token, l_user.id)
|
||||
create l_link.make_from_string (req.server_url)
|
||||
l_link.append ("/account/reset-password?token=")
|
||||
l_link.append (l_token)
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_password_email")
|
||||
es.send_contact_password_email (l_email.value, l_link)
|
||||
else
|
||||
r.values.force ("The email does not exist !", "error_email")
|
||||
r.values.force (l_email.value, "email")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
|
||||
handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_user_api: CMS_USER_API
|
||||
do
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
l_user_api := api.user_api
|
||||
if attached {WSF_STRING} req.query_parameter ("token") as l_token then
|
||||
r.values.force (l_token.value, "token")
|
||||
if l_user_api.user_by_password_token (l_token.value) = Void then
|
||||
r.values.force ("The token " + l_token.value + " is not valid, click <a href=%"/account/new-password%">here</a> to generate a new token.", "error_token")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
if req.is_post_request_method then
|
||||
|
||||
if
|
||||
attached {WSF_STRING} req.form_parameter ("token") as l_token and then
|
||||
attached {WSF_STRING} req.form_parameter ("password") as l_password and then
|
||||
attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password
|
||||
then
|
||||
-- Does the passwords match?
|
||||
if l_password.value.same_string (l_confirm_password.value) then
|
||||
-- is the token valid?
|
||||
if attached {CMS_USER} l_user_api.user_by_password_token (l_token.value) as l_user then
|
||||
l_user.set_password (l_password.value)
|
||||
l_user_api.update_user (l_user)
|
||||
l_user_api.remove_password (l_token.value)
|
||||
end
|
||||
else
|
||||
r.values.force ("Passwords Don't Match", "error_password")
|
||||
r.values.force (l_token.value, "token")
|
||||
r.set_status_code ({HTTP_CONSTANTS}.bad_request)
|
||||
end
|
||||
end
|
||||
end
|
||||
r.execute
|
||||
end
|
||||
|
||||
feature {NONE} -- Helpers
|
||||
|
||||
template_block (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK
|
||||
-- Smarty content block for `a_block_id'
|
||||
local
|
||||
p: detachable PATH
|
||||
do
|
||||
create p.make_from_string ("templates")
|
||||
p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl")
|
||||
p := a_response.module_resource_path (Current, p)
|
||||
if p /= Void then
|
||||
if attached p.entry as e then
|
||||
create Result.make (a_block_id, Void, p.parent, e)
|
||||
else
|
||||
create Result.make (a_block_id, Void, p.parent, p)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Block views
|
||||
|
||||
get_block_view_login (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
local
|
||||
vals: CMS_VALUE_TABLE
|
||||
do
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
create vals.make (1)
|
||||
-- add the variable to the block
|
||||
value_table_alter (vals, a_response)
|
||||
across
|
||||
vals as ic
|
||||
loop
|
||||
l_tpl_block.set_value (ic.item, ic.key)
|
||||
end
|
||||
if
|
||||
attached user_oauth_api as l_auth_api and then
|
||||
attached l_auth_api.oauth2_consumers as l_list
|
||||
then
|
||||
l_tpl_block.set_value (l_list, "oauth_consumers")
|
||||
end
|
||||
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
l_tpl_block.set_value (a_response.values.item ("name"), "name")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
if attached template_block ("post_register", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
get_block_view_reactivate (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_email") or else a_response.values.has ("is_active") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
if attached template_block ("post_reactivate", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_block_view_new_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_email") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email")
|
||||
l_tpl_block.set_value (a_response.values.item ("email"), "email")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
if attached template_block ("post_password", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
get_block_view_reset_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE)
|
||||
do
|
||||
if a_response.request.is_get_request_method then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
elseif a_response.request.is_post_request_method then
|
||||
if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then
|
||||
if attached template_block (a_block_id, a_response) as l_tpl_block then
|
||||
l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token")
|
||||
l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password")
|
||||
l_tpl_block.set_value (a_response.values.item ("token"), "token")
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
else
|
||||
if attached template_block ("post_reset", a_response) as l_tpl_block then
|
||||
a_response.add_block (l_tpl_block, "content")
|
||||
else
|
||||
debug ("cms")
|
||||
a_response.add_warning_message ("Error with block [" + a_block_id + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- OAuth2 Login with google.
|
||||
|
||||
handle_login_with_oauth (api: CMS_API; a_oauth_api: CMS_OAUTH_20_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_oauth: CMS_OAUTH_20_WORKFLOW
|
||||
do
|
||||
if
|
||||
attached {WSF_STRING} req.path_parameter ("callback") as p_consumer and then
|
||||
attached {CMS_OAUTH_20_CONSUMER} a_oauth_api.oauth_consumer_by_name (p_consumer.value) as l_consumer
|
||||
then
|
||||
create l_oauth.make (req.server_url, l_consumer)
|
||||
if attached l_oauth.authorization_url as l_authorization_url then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_redirection (l_authorization_url)
|
||||
r.execute
|
||||
else
|
||||
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_main_content ("Bad request")
|
||||
r.execute
|
||||
end
|
||||
else
|
||||
create {BAD_REQUEST_ERROR_CMS_RESPONSE} r.make (req, res, api)
|
||||
r.set_main_content ("Bad request")
|
||||
r.execute
|
||||
end
|
||||
end
|
||||
|
||||
handle_callback_oauth (api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API; req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
local
|
||||
r: CMS_RESPONSE
|
||||
l_auth: CMS_OAUTH_20_WORKFLOW
|
||||
l_user_api: CMS_USER_API
|
||||
l_user: CMS_USER
|
||||
l_roles: LIST [CMS_USER_ROLE]
|
||||
l_cookie: WSF_COOKIE
|
||||
es: CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
do
|
||||
if attached {WSF_STRING} req.path_parameter ("callback") as l_callback and then
|
||||
attached {CMS_OAUTH_20_CONSUMER} a_user_oauth_api.oauth_consumer_by_callback (l_callback.value) as l_consumer and then
|
||||
attached {WSF_STRING} req.query_parameter ("code") as l_code
|
||||
then
|
||||
create l_auth.make (req.server_url, l_consumer)
|
||||
l_auth.sign_request (l_code.value)
|
||||
if
|
||||
attached l_auth.access_token as l_access_token and then
|
||||
attached l_auth.user_profile as l_user_profile
|
||||
then
|
||||
create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api)
|
||||
-- extract user email
|
||||
-- check if the user exist
|
||||
l_user_api := api.user_api
|
||||
-- 1 if the user exit put it in the context
|
||||
if
|
||||
attached l_auth.user_email as l_email
|
||||
then
|
||||
if attached {CMS_USER} l_user_api.user_by_email (l_email) as p_user then
|
||||
-- User with email exist
|
||||
if attached {CMS_USER} a_user_oauth_api.user_oauth2_by_id (p_user.id, l_consumer.name) then
|
||||
-- Update oauth entry
|
||||
a_user_oauth_api.update_user_oauth2 (l_access_token.token, l_user_profile, p_user, l_consumer.name )
|
||||
else
|
||||
-- create a oauth entry
|
||||
a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, p_user, l_consumer.name )
|
||||
end
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session, l_access_token.token)
|
||||
l_cookie.set_max_age (l_access_token.expires_in)
|
||||
l_cookie.set_path ("/")
|
||||
res.add_cookie (l_cookie)
|
||||
else
|
||||
|
||||
create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1)
|
||||
l_roles.force (l_user_api.authenticated_user_role)
|
||||
|
||||
-- Create a new user and oauth entry
|
||||
create l_user.make (l_email)
|
||||
l_user.set_email (l_email)
|
||||
l_user.set_password (new_token) -- generate a random password.
|
||||
l_user.set_roles (l_roles)
|
||||
l_user.mark_active
|
||||
l_user_api.new_user (l_user)
|
||||
|
||||
-- Add oauth entry
|
||||
a_user_oauth_api.new_user_oauth2 (l_access_token.token, l_user_profile, l_user, l_consumer.name )
|
||||
create l_cookie.make ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session, l_access_token.token)
|
||||
l_cookie.set_max_age (l_access_token.expires_in)
|
||||
l_cookie.set_path ("/")
|
||||
res.add_cookie (l_cookie)
|
||||
set_current_user (req, l_user)
|
||||
|
||||
|
||||
-- Send Email
|
||||
create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api))
|
||||
write_debug_log (generator + ".handle register: send_contact_welcome_email")
|
||||
es.send_contact_welcome_email (l_email, "")
|
||||
end
|
||||
else
|
||||
end
|
||||
r.set_redirection (req.absolute_script_url (""))
|
||||
r.execute
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
feature {NONE} -- Token Generation
|
||||
|
||||
new_token: STRING
|
||||
-- Generate a new token activation token
|
||||
local
|
||||
l_token: STRING
|
||||
l_security: SECURITY_PROVIDER
|
||||
l_encode: URL_ENCODER
|
||||
do
|
||||
create l_security
|
||||
l_token := l_security.token
|
||||
create l_encode
|
||||
from until l_token.same_string (l_encode.encoded_string (l_token)) loop
|
||||
-- Loop ensure that we have a security token that does not contain characters that need encoding.
|
||||
-- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token
|
||||
-- but the user will need to use an unencoded token if activation has to be done manually.
|
||||
l_token := l_security.token
|
||||
end
|
||||
Result := l_token
|
||||
end
|
||||
|
||||
|
||||
|
||||
feature {NONE} -- Implementation: date and time
|
||||
|
||||
http_date_format_to_date (s: READABLE_STRING_8): detachable DATE_TIME
|
||||
local
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create d.make_from_string (s)
|
||||
if not d.has_error then
|
||||
Result := d.date_time
|
||||
end
|
||||
end
|
||||
|
||||
file_date (p: PATH): DATE_TIME
|
||||
require
|
||||
path_exists: (create {FILE_UTILITIES}).file_path_exists (p)
|
||||
local
|
||||
f: RAW_FILE
|
||||
do
|
||||
create f.make_with_path (p)
|
||||
Result := timestamp_to_date (f.date)
|
||||
end
|
||||
|
||||
timestamp_to_date (n: INTEGER): DATE_TIME
|
||||
local
|
||||
d: HTTP_DATE
|
||||
do
|
||||
create d.make_from_timestamp (n)
|
||||
Result := d.date_time
|
||||
end
|
||||
|
||||
|
||||
note
|
||||
copyright: "Copyright (c) 1984-2013, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||
Telephone 805-685-1006, Fax 805-685-6869
|
||||
Website http://www.eiffel.com
|
||||
Customer support http://support.eiffel.com
|
||||
]"
|
||||
end
|
||||
88
modules/login/cms_authenticaton_email_service.e
Normal file
88
modules/login/cms_authenticaton_email_service.e
Normal file
@@ -0,0 +1,88 @@
|
||||
note
|
||||
description: "Summary description for {CMS_AUTHENTICATON_EMAIL_SERVICE}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_AUTHENTICATON_EMAIL_SERVICE
|
||||
|
||||
inherit
|
||||
EMAIL_SERVICE
|
||||
redefine
|
||||
initialize,
|
||||
parameters
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
initialize
|
||||
do
|
||||
Precursor
|
||||
contact_email := parameters.contact_email
|
||||
end
|
||||
|
||||
parameters: CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS
|
||||
-- Associated parameters.
|
||||
|
||||
feature -- Access
|
||||
|
||||
contact_email: IMMUTABLE_STRING_8
|
||||
-- contact email.
|
||||
|
||||
feature -- Basic Operations
|
||||
|
||||
send_contact_email (a_to, a_content: READABLE_STRING_8)
|
||||
-- Send successful contact message `a_token' to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_activation)
|
||||
l_message.replace_substring_all ("$link", a_content)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_register, l_message)
|
||||
end
|
||||
|
||||
|
||||
send_contact_activation_email (a_to, a_content: READABLE_STRING_8)
|
||||
-- Send successful contact message `a_token' to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_re_activation)
|
||||
l_message.replace_substring_all ("$link", a_content)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_activate, l_message)
|
||||
end
|
||||
|
||||
|
||||
send_contact_password_email (a_to, a_content: READABLE_STRING_8)
|
||||
-- Send successful contact message `a_token' to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_password)
|
||||
l_message.replace_substring_all ("$link", a_content)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_password, l_message)
|
||||
end
|
||||
|
||||
send_contact_welcome_email (a_to, a_content: READABLE_STRING_8)
|
||||
-- Send successful contact message `a_token' to `a_to'.
|
||||
require
|
||||
attached_to: a_to /= Void
|
||||
local
|
||||
l_message: STRING
|
||||
do
|
||||
create l_message.make_from_string (parameters.account_welcome)
|
||||
l_message.replace_substring_all ("$link", a_content)
|
||||
send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
95
modules/login/cms_oauth_20_api.e
Normal file
95
modules/login/cms_oauth_20_api.e
Normal file
@@ -0,0 +1,95 @@
|
||||
note
|
||||
description: "[
|
||||
API to manage CMS User OAuth authentication.
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_API
|
||||
|
||||
inherit
|
||||
CMS_MODULE_API
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create {CMS_AUTHENTICATION_MODULE}
|
||||
make_with_storage
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make_with_storage (a_api: CMS_API; a_oauth_storage: CMS_OAUTH_20_STORAGE_I)
|
||||
-- Create an object with api `a_api' and storage `a_oauth_storage'.
|
||||
do
|
||||
oauth_20_storage := a_oauth_storage
|
||||
make (a_api)
|
||||
ensure
|
||||
oauht_20_storage_set: oauth_20_storage = a_oauth_storage
|
||||
end
|
||||
|
||||
feature {CMS_MODULE} -- Access: User oauth storage.
|
||||
|
||||
oauth_20_storage: CMS_OAUTH_20_STORAGE_I
|
||||
-- storage interface.
|
||||
|
||||
feature -- Access: User Oauth20
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_32): detachable CMS_USER
|
||||
-- Retrieve a user by id `a_uid' for the consumer `a_consumer', if aby.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_by_id (a_uid, a_consumer)
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_32; a_consumer: READABLE_STRING_32): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' for the consumer `a_consumer'.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_by_token (a_token, a_consumer)
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
|
||||
do
|
||||
Result := oauth_20_storage.user_oauth2_without_consumer_by_token (a_token)
|
||||
end
|
||||
|
||||
feature -- Access: Consumers OAuth20
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
-- List of Oauth_20 consumers, if any, empty in other case.
|
||||
do
|
||||
Result := oauth_20_storage.oauth2_consumers
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
do
|
||||
Result := oauth_20_storage.oauth_consumer_by_name (a_name)
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
do
|
||||
Result := oauth_20_storage.oauth_consumer_by_callback (a_callback)
|
||||
end
|
||||
|
||||
feature -- Change: User OAuth20
|
||||
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32)
|
||||
-- Add a new user with oauth20 using the consumer `a_consumer'.
|
||||
require
|
||||
has_id: a_user.has_id
|
||||
do
|
||||
oauth_20_storage.new_user_oauth2 (a_token, a_user_profile, a_user, a_consumer)
|
||||
end
|
||||
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
|
||||
-- Updaate user `a_user' with oauth2 for the consumer `a_consumer'.
|
||||
require
|
||||
has_id: a_user.has_id
|
||||
do
|
||||
oauth_20_storage.update_user_oauth2 (a_token, a_user_profile, a_user, a_consumer_table)
|
||||
end
|
||||
|
||||
end
|
||||
152
modules/login/cms_oauth_20_consumer.e
Normal file
152
modules/login/cms_oauth_20_consumer.e
Normal file
@@ -0,0 +1,152 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_CONSUMER}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_CONSUMER
|
||||
|
||||
inherit
|
||||
|
||||
ANY
|
||||
redefine
|
||||
default_create
|
||||
end
|
||||
|
||||
create
|
||||
default_create
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
default_create
|
||||
do
|
||||
set_endpoint ("")
|
||||
set_authorize_url ("")
|
||||
set_extractor ("")
|
||||
set_callback_name ("")
|
||||
set_protected_resource_url ("")
|
||||
set_scope ("")
|
||||
set_api_key ("")
|
||||
set_api_secret ("")
|
||||
set_name ("")
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
endpoint: READABLE_STRING_32
|
||||
-- Url that receives the access token request.
|
||||
|
||||
authorize_url: READABLE_STRING_32
|
||||
--
|
||||
|
||||
extractor: READABLE_STRING_32
|
||||
-- text, json
|
||||
|
||||
|
||||
callback_name: READABLE_STRING_32
|
||||
-- consumer callback name
|
||||
|
||||
protected_resource_url: READABLE_STRING_32
|
||||
-- consumer resource url
|
||||
|
||||
scope: READABLE_STRING_32
|
||||
-- consumer scope
|
||||
|
||||
api_key: READABLE_STRING_32
|
||||
-- consumer public key
|
||||
|
||||
api_secret: READABLE_STRING_32
|
||||
-- consumer secret.
|
||||
|
||||
name: READABLE_STRING_32
|
||||
-- consumer name.
|
||||
|
||||
id: INTEGER_64
|
||||
-- unique identifier.
|
||||
|
||||
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_extractor (a_extractor: like extractor)
|
||||
-- Assign `extractor' with `a_extractor'.
|
||||
do
|
||||
extractor := a_extractor
|
||||
ensure
|
||||
extractor_assigned: extractor = a_extractor
|
||||
end
|
||||
|
||||
set_authorize_url (a_authorize_url: like authorize_url)
|
||||
-- Assign `authorize_url' with `a_authorize_url'.
|
||||
do
|
||||
authorize_url := a_authorize_url
|
||||
ensure
|
||||
authorize_url_assigned: authorize_url = a_authorize_url
|
||||
end
|
||||
|
||||
set_endpoint (a_endpoint: like endpoint)
|
||||
-- Assign `endpoint' with `a_endpoint'.
|
||||
do
|
||||
endpoint := a_endpoint
|
||||
ensure
|
||||
endpoint_assigned: endpoint = a_endpoint
|
||||
end
|
||||
|
||||
set_callback_name (a_callback_name: like callback_name)
|
||||
-- Assign `callback_name' with `a_callback_name'.
|
||||
do
|
||||
callback_name := a_callback_name
|
||||
ensure
|
||||
callback_name_assigned: callback_name = a_callback_name
|
||||
end
|
||||
|
||||
set_protected_resource_url (a_protected_resource_url: like protected_resource_url)
|
||||
-- Assign `protected_resource_url' with `a_protected_resource_url'.
|
||||
do
|
||||
protected_resource_url := a_protected_resource_url
|
||||
ensure
|
||||
protected_resource_url_assigned: protected_resource_url = a_protected_resource_url
|
||||
end
|
||||
|
||||
set_scope (a_scope: like scope)
|
||||
-- Assign `scope' with `a_scope'.
|
||||
do
|
||||
scope := a_scope
|
||||
ensure
|
||||
scope_assigned: scope = a_scope
|
||||
end
|
||||
|
||||
set_api_key (an_api_key: like api_key)
|
||||
-- Assign `api_key' with `an_api_key'.
|
||||
do
|
||||
api_key := an_api_key
|
||||
ensure
|
||||
api_key_assigned: api_key = an_api_key
|
||||
end
|
||||
|
||||
set_api_secret (an_api_secret: like api_secret)
|
||||
-- Assign `api_secret' with `an_api_secret'.
|
||||
do
|
||||
api_secret := an_api_secret
|
||||
ensure
|
||||
api_secret_assigned: api_secret = an_api_secret
|
||||
end
|
||||
|
||||
set_name (a_name: like name)
|
||||
-- Assign `name' with `a_name'.
|
||||
do
|
||||
name := a_name
|
||||
ensure
|
||||
name_assigned: name = a_name
|
||||
end
|
||||
|
||||
set_id (an_id: like id)
|
||||
-- Assign `id' with `an_id'.
|
||||
do
|
||||
id := an_id
|
||||
ensure
|
||||
id_assigned: id = an_id
|
||||
end
|
||||
|
||||
end
|
||||
133
modules/login/cms_oauth_20_workflow.e
Normal file
133
modules/login/cms_oauth_20_workflow.e
Normal file
@@ -0,0 +1,133 @@
|
||||
note
|
||||
description: "OAuth workflow"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_WORKFLOW
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_host: READABLE_STRING_32; a_consumer: CMS_OAUTH_20_CONSUMER)
|
||||
-- Create an object with the host `a_host'.
|
||||
do
|
||||
initilize (a_consumer)
|
||||
create config.make_default (a_consumer.api_key, a_consumer.api_secret)
|
||||
config.set_callback (a_host + "/account/"+ a_consumer.callback_name)
|
||||
config.set_scope (a_consumer.scope)
|
||||
--Todo create a generic OAUTH_20_GENERIC_API
|
||||
create oauth_api.make (a_consumer.endpoint, a_consumer.authorize_url, a_consumer.extractor)
|
||||
api_service := oauth_api.create_service (config)
|
||||
end
|
||||
|
||||
initilize (a_consumer: CMS_OAUTH_20_CONSUMER)
|
||||
do
|
||||
--Use configuration values if any if not defaul
|
||||
api_key := a_consumer.api_key
|
||||
api_secret := a_consumer.api_secret
|
||||
scope := a_consumer.scope
|
||||
protected_resource_url := a_consumer.protected_resource_url
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
authorization_url: detachable READABLE_STRING_32
|
||||
-- Obtain the Authorization URL.
|
||||
do
|
||||
-- Obtain the Authorization URL
|
||||
write_debug_log (generator + ".authorization_url Fetching the Authorization URL..!")
|
||||
if attached api_service.authorization_url (empty_token) as l_authorization_url then
|
||||
write_debug_log (generator + ".authorization_url: Got the Authorization URL!")
|
||||
write_debug_log (generator + ".authorization_url:" + l_authorization_url)
|
||||
Result := l_authorization_url.as_string_32
|
||||
end
|
||||
end
|
||||
|
||||
sign_request (a_code: READABLE_STRING_32)
|
||||
-- Sign request with code `a_code'.
|
||||
--! To get the code `a_code' you need to do a request
|
||||
--! using the authorization_url
|
||||
local
|
||||
request: OAUTH_REQUEST
|
||||
do
|
||||
-- Get the access token.
|
||||
write_debug_log (generator + ".sign_request Fetching the access token with code [" + a_code + "]")
|
||||
access_token := api_service.access_token_post (empty_token, create {OAUTH_VERIFIER}.make (a_code))
|
||||
if attached access_token as l_access_token then
|
||||
write_debug_log (generator + ".sign_request Got the Access Token [" + l_access_token.debug_output + "]")
|
||||
-- Get the user email
|
||||
--! at the moment the scope is mail, but we can change it to get more information.
|
||||
create request.make ("GET", protected_resource_url)
|
||||
request.add_header ("Authorization", "Bearer " + l_access_token.token)
|
||||
api_service.sign_request (l_access_token, request)
|
||||
if attached {OAUTH_RESPONSE} request.execute as l_response then
|
||||
write_debug_log (generator + ".sign_request Sign_request response [" + l_response.status.out + "]")
|
||||
if attached l_response.body as l_body then
|
||||
user_profile := l_body
|
||||
write_debug_log (generator + ".sign_request User profile [" + l_body + "]")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
user_email: detachable READABLE_STRING_32
|
||||
-- Retrieve user email if any.
|
||||
local
|
||||
l_json: JSON_CONFIG
|
||||
do
|
||||
if attached user_profile as l_profile then
|
||||
create l_json.make_from_string (l_profile)
|
||||
if
|
||||
attached {JSON_ARRAY} l_json.item ("emails") as l_array and then
|
||||
attached {JSON_OBJECT} l_array.i_th (1) as l_object and then
|
||||
attached {JSON_STRING} l_object.item ("value") as l_email
|
||||
then
|
||||
Result := l_email.item
|
||||
elseif attached {JSON_STRING} l_json.item ("email") as l_email then
|
||||
Result := l_email.unescaped_string_32
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Access
|
||||
|
||||
access_token: detachable OAUTH_TOKEN
|
||||
-- JSON representing the access token.
|
||||
|
||||
user_profile: detachable READABLE_STRING_32
|
||||
-- JSON representing the user profiles.
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
oauth_api: CMS_OAUTH_20_GENERIC_API
|
||||
-- OAuth 2.0 Google API.
|
||||
|
||||
config: OAUTH_CONFIG
|
||||
-- configuration.
|
||||
|
||||
api_service: OAUTH_SERVICE_I
|
||||
-- Service.
|
||||
|
||||
api_key: STRING
|
||||
-- public key.
|
||||
|
||||
api_secret: STRING
|
||||
-- secret key.
|
||||
|
||||
scope: STRING
|
||||
-- api scope to access protected resources.
|
||||
|
||||
protected_resource_url: STRING
|
||||
-- Resource url.
|
||||
|
||||
empty_token: detachable OAUTH_TOKEN
|
||||
-- fake token.
|
||||
|
||||
end
|
||||
58
modules/login/filter/cms_oauth_20_filter.e
Normal file
58
modules/login/filter/cms_oauth_20_filter.e
Normal file
@@ -0,0 +1,58 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_FILTER}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_FILTER
|
||||
|
||||
inherit
|
||||
WSF_URI_TEMPLATE_HANDLER
|
||||
CMS_HANDLER
|
||||
rename
|
||||
make as make_handler
|
||||
end
|
||||
|
||||
WSF_FILTER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_api: CMS_API; a_user_oauth_api: CMS_OAUTH_20_API)
|
||||
do
|
||||
make_handler (a_api)
|
||||
user_oauth_api := a_user_oauth_api
|
||||
end
|
||||
|
||||
user_oauth_api: CMS_OAUTH_20_API
|
||||
|
||||
feature -- Basic operations
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute the filter.
|
||||
local
|
||||
do
|
||||
api.logger.put_debug (generator + ".execute ", Void)
|
||||
-- if attached req.raw_header_data as l_raw_data then
|
||||
-- api.logger.put_debug (generator + ".execute " + utf.escaped_utf_32_string_to_utf_8_string_8 (l_raw_data), Void)
|
||||
-- end
|
||||
-- A valid user
|
||||
if
|
||||
attached {WSF_STRING} req.cookie ({CMS_AUTHENTICATION_CONSTANTS}.oauth_session) as l_roc_auth_session_token
|
||||
then
|
||||
if attached {CMS_USER} user_oauth_api.user_oauth2_without_consumer_by_token (l_roc_auth_session_token.value) as l_user then
|
||||
set_current_user (req, l_user)
|
||||
execute_next (req, res)
|
||||
else
|
||||
api.logger.put_error (generator + ".execute login_valid failed for: " + l_roc_auth_session_token.value , Void)
|
||||
execute_next (req, res)
|
||||
end
|
||||
else
|
||||
api.logger.put_debug (generator + ".execute without authentication", Void)
|
||||
execute_next (req, res)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
30
modules/login/login-safe.ecf
Normal file
30
modules/login/login-safe.ecf
Normal file
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="login" uuid="AAB9EE7D-A671-4727-8658-D417A48B2B57" library_target="login">
|
||||
<target name="login">
|
||||
<root all_classes="true"/>
|
||||
<file_rule>
|
||||
<exclude>/.git$</exclude>
|
||||
<exclude>/EIFGENs$</exclude>
|
||||
<exclude>/.svn$</exclude>
|
||||
</file_rule>
|
||||
<option warning="true" full_class_checking="true" is_attached_by_default="true" void_safety="all" syntax="standard">
|
||||
</option>
|
||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||
<library name="cms" location="$ISE_LIBRARY\unstable\library\web\cms\cms-safe.ecf" readonly="false"/>
|
||||
<library name="cms_app_env" location="$ISE_LIBRARY\unstable\library\web\cms\library\app_env\app_env-safe.ecf" readonly="false"/>
|
||||
<library name="cms_model" location="$ISE_LIBRARY\unstable\library\web\cms\library\model\cms_model-safe.ecf" readonly="false"/>
|
||||
<library name="config" location="$ISE_LIBRARY\unstable\library\web\cms\library\configuration\config-safe.ecf"/>
|
||||
<library name="encoder" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\text\encoder\encoder-safe.ecf"/>
|
||||
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
|
||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>
|
||||
<library name="error" location="$ISE_LIBRARY\contrib\library\utility\general\error\error-safe.ecf"/>
|
||||
|
||||
<library name="apis" location="$ISE_LIBRARY\contrib\library\web\communication\oauth\cypress\consumer\apis\apis.ecf" readonly="false"/>
|
||||
<library name="cypress_consumer" location="$ISE_LIBRARY\contrib\library\web\communication\oauth\cypress\consumer\cypress_consumer-safe.ecf" readonly="false"/>
|
||||
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
|
||||
|
||||
|
||||
<cluster name="src" location=".\" recursive="true"/>
|
||||
</target>
|
||||
</system>
|
||||
94
modules/login/persistence/cms_oauth_20_generic_api.e
Normal file
94
modules/login/persistence/cms_oauth_20_generic_api.e
Normal file
@@ -0,0 +1,94 @@
|
||||
note
|
||||
description: "Generic OAUTH2 API"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_GENERIC_API
|
||||
|
||||
inherit
|
||||
|
||||
OAUTH_20_API
|
||||
redefine
|
||||
access_token_extractor,
|
||||
access_token_verb
|
||||
end
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialize
|
||||
|
||||
make (a_endpoint: READABLE_STRING_8; a_authorize_url: READABLE_STRING_8; a_extractor: READABLE_STRING_8)
|
||||
do
|
||||
endpoint := a_endpoint
|
||||
authorize_url := a_authorize_url
|
||||
extractor := a_extractor
|
||||
ensure
|
||||
endpoint_set: endpoint = a_endpoint
|
||||
authorize_url_set: authorize_url = a_authorize_url
|
||||
extractor_set: extractor = a_authorize_url
|
||||
end
|
||||
|
||||
endpoint: READABLE_STRING_8
|
||||
-- Url that receives the access token request.
|
||||
|
||||
authorize_url: READABLE_STRING_8
|
||||
--
|
||||
|
||||
extractor: READABLE_STRING_8
|
||||
-- text, json
|
||||
|
||||
feature -- Access
|
||||
|
||||
access_token_extractor: ACCESS_TOKEN_EXTRACTOR
|
||||
-- Return token extractor, by default TOKEN_EXTRACTOR_20.
|
||||
do
|
||||
if extractor.is_case_insensitive_equal_general ("json") then
|
||||
create {JSON_TOKEN_EXTRACTOR} Result
|
||||
else
|
||||
create {TOKEN_EXTRACTOR_20} Result
|
||||
end
|
||||
end
|
||||
|
||||
access_token_verb: STRING_8
|
||||
do
|
||||
Result := "POST"
|
||||
end
|
||||
|
||||
access_token_endpoint: STRING_8
|
||||
-- Url that receives the access token request
|
||||
do
|
||||
create Result.make_from_string (endpoint)
|
||||
end
|
||||
|
||||
authorization_url (config: OAUTH_CONFIG): detachable STRING_8
|
||||
-- Url where you should redirect your users to authneticate
|
||||
local
|
||||
l_result: STRING_8
|
||||
do
|
||||
if attached config.scope as l_scope then
|
||||
create l_result.make_from_string (authorize_url + SCOPED_AUTHORIZE_URL)
|
||||
l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
|
||||
if attached config.callback as l_callback then
|
||||
l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_8))
|
||||
end
|
||||
if attached config.callback as l_callback then
|
||||
l_result.replace_substring_all ("$SCOPE", (create {OAUTH_ENCODER}).encoded_string (l_scope.as_STRING_8))
|
||||
Result := l_result
|
||||
end
|
||||
else
|
||||
create l_result.make_from_string (authorize_url + SCOPED_AUTHORIZE_URL)
|
||||
l_result.replace_substring_all ("$CLIENT_ID", config.api_key.as_string_8)
|
||||
if attached config.callback as l_callback then
|
||||
l_result.replace_substring_all ("$REDIRECT_URI", (create {OAUTH_ENCODER}).encoded_string (l_callback.as_string_8))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Implementation
|
||||
|
||||
Scoped_authorize_url: STRING = "&scope=$SCOPE";
|
||||
|
||||
|
||||
end
|
||||
66
modules/login/persistence/cms_oauth_20_storage_i.e
Normal file
66
modules/login/persistence/cms_oauth_20_storage_i.e
Normal file
@@ -0,0 +1,66 @@
|
||||
note
|
||||
description: "[
|
||||
API to handle OAUTH storage
|
||||
]"
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
deferred class
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
inherit
|
||||
SHARED_LOGGER
|
||||
|
||||
feature -- Error Handling
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: Users
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
|
||||
-- Retrieve a user by id `a_uid' for the consumer `a_consumer', if aby.
|
||||
deferred
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' for the consumer `a_consumer'.
|
||||
deferred
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Access: Consumers
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
deferred
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
deferred
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: User Oauth2
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
deferred
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
69
modules/login/persistence/cms_oauth_20_storage_null.e
Normal file
69
modules/login/persistence/cms_oauth_20_storage_null.e
Normal file
@@ -0,0 +1,69 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_STORAGE_NULL}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_STORAGE_NULL
|
||||
|
||||
inherit
|
||||
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
|
||||
feature -- Error handler
|
||||
|
||||
error_handler: ERROR_HANDLER
|
||||
-- Error handler.
|
||||
do
|
||||
create Result.make
|
||||
end
|
||||
|
||||
feature -- Access: Users
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
|
||||
-- CMS User with Oauth credential by id if any.
|
||||
do
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_32; a_consumer_table: READABLE_STRING_32): detachable CMS_USER
|
||||
-- -- CMS User with Oauth credential by access token `a_token' if any.
|
||||
do
|
||||
end
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Access: Consumers
|
||||
|
||||
oauth2_consumers: LIST [STRING]
|
||||
do
|
||||
create {ARRAYED_LIST[STRING]} Result.make (0)
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
do
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Change: User Oauth2
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
do
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer_table: READABLE_STRING_32 )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
do
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
293
modules/login/persistence/cms_oauth_20_storage_sql.e
Normal file
293
modules/login/persistence/cms_oauth_20_storage_sql.e
Normal file
@@ -0,0 +1,293 @@
|
||||
note
|
||||
description: "Summary description for {CMS_OAUTH_20_STORAGE_SQL}."
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
class
|
||||
CMS_OAUTH_20_STORAGE_SQL
|
||||
|
||||
inherit
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
CMS_PROXY_STORAGE_SQL
|
||||
|
||||
CMS_OAUTH_20_STORAGE_I
|
||||
|
||||
CMS_STORAGE_SQL_I
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access User Outh
|
||||
|
||||
user_oauth2_without_consumer_by_token (a_token: READABLE_STRING_32 ): detachable CMS_USER
|
||||
-- Retrieve a user by token `a_token' searching in all the registered consumers in the system.
|
||||
local
|
||||
l_list: LIST[STRING]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_oauth2_without_consumer_by_token")
|
||||
l_list := oauth2_consumers
|
||||
from
|
||||
l_list.start
|
||||
until
|
||||
l_list.after or attached Result
|
||||
loop
|
||||
if attached {CMS_USER} user_oauth2_by_token (a_token, l_list.item) as l_user then
|
||||
Result := l_user
|
||||
end
|
||||
l_list.forth
|
||||
end
|
||||
end
|
||||
|
||||
user_oauth2_by_id (a_uid: like {CMS_USER}.id; a_consumer: READABLE_STRING_32): detachable CMS_USER
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_oauth2_by_id")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_uid, "uid")
|
||||
create l_string.make_from_string (select_user_oauth2_template_by_id)
|
||||
l_string.replace_substring_all ("$table_name", sql_table_name (a_consumer))
|
||||
sql_query (l_string, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
user_oauth2_by_token (a_token: READABLE_STRING_32; a_consumer: READABLE_STRING_32): detachable CMS_USER
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_by_oauth2_token")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
create l_string.make_from_string (select_user_by_oauth2_template_token)
|
||||
l_string.replace_substring_all ("$table_name", sql_table_name (a_consumer))
|
||||
sql_query (l_string, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature --Access: Consumers
|
||||
|
||||
oauth2_consumers: LIST[STRING]
|
||||
-- Return a list of consumers, or empty
|
||||
do
|
||||
error_handler.reset
|
||||
create {ARRAYED_LIST[STRING]}Result.make (0)
|
||||
write_information_log (generator + ".user_by_oauth2_token")
|
||||
sql_query (Sql_oauth_consumers, Void)
|
||||
if not has_error then
|
||||
from
|
||||
sql_start
|
||||
until
|
||||
sql_after
|
||||
loop
|
||||
if attached sql_read_string (1) as l_name then
|
||||
Result.force (l_name)
|
||||
end
|
||||
sql_forth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
oauth_consumer_by_name (a_name: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by name `a_name', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".oauth_consumer_by_name")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_name, "name")
|
||||
sql_query (sql_oauth_consumer_name, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_consumer
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
oauth_consumer_by_callback (a_callback: READABLE_STRING_8): detachable CMS_OAUTH_20_CONSUMER
|
||||
-- Retrieve a consumer by callback `a_callback', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".oauth_consumer_by_callback")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_callback, "name")
|
||||
sql_query (sql_oauth_consumer_callback, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_consumer
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: User OAuth
|
||||
|
||||
new_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32)
|
||||
-- Add a new user with oauth2 authentication.
|
||||
-- <Precursor>.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
|
||||
write_information_log (generator + ".new_user_oauth2")
|
||||
create l_parameters.make (4)
|
||||
l_parameters.put (a_user.id, "uid")
|
||||
l_parameters.put (a_token, "token")
|
||||
l_parameters.put (a_user_profile, "profile")
|
||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "utc_date")
|
||||
|
||||
create l_string.make_from_string (sql_insert_oauth2_template)
|
||||
l_string.replace_substring_all ("$table_name", sql_table_name (a_consumer))
|
||||
sql_change (l_string, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
update_user_oauth2 (a_token: READABLE_STRING_32; a_user_profile: READABLE_STRING_32; a_user: CMS_USER; a_consumer: READABLE_STRING_32 )
|
||||
-- Update user `a_user' with oauth2 authentication.
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_string: STRING
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
|
||||
write_information_log (generator + ".new_user_oauth2")
|
||||
create l_parameters.make (4)
|
||||
l_parameters.put (a_user.id, "uid")
|
||||
l_parameters.put (a_token, "token")
|
||||
l_parameters.put (a_user_profile, "profile")
|
||||
|
||||
create l_string.make_from_string (sql_update_oauth2_template)
|
||||
l_string.replace_substring_all ("$table_name", sql_table_name (a_consumer))
|
||||
sql_change (l_string, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation OAuth Consumer
|
||||
|
||||
fetch_consumer: detachable CMS_OAUTH_20_CONSUMER
|
||||
do
|
||||
if attached sql_read_integer_64 (1) as l_id then
|
||||
create Result
|
||||
Result.set_id (l_id)
|
||||
end
|
||||
if Result /= Void then
|
||||
if attached sql_read_string_32 (2) as l_name then
|
||||
Result.set_name (l_name)
|
||||
end
|
||||
if attached sql_read_string_32 (3) as l_api_secret then
|
||||
Result.set_api_secret (l_api_secret)
|
||||
end
|
||||
if attached sql_read_string_32 (4) as l_api_key then
|
||||
Result.set_api_key (l_api_key)
|
||||
end
|
||||
if attached sql_read_string_32 (5) as l_scope then
|
||||
Result.set_scope (l_scope)
|
||||
end
|
||||
if attached sql_read_string_32 (6) as l_resource_url then
|
||||
Result.set_protected_resource_url (l_resource_url)
|
||||
end
|
||||
if attached sql_read_string_32 (7) as l_callback_name then
|
||||
Result.set_callback_name (l_callback_name)
|
||||
end
|
||||
if attached sql_read_string_32 (8) as l_extractor then
|
||||
Result.set_extractor (l_extractor)
|
||||
end
|
||||
if attached sql_read_string_32 (9) as l_authorize_url then
|
||||
Result.set_authorize_url (l_authorize_url)
|
||||
end
|
||||
if attached sql_read_string_32 (10) as l_endpoint then
|
||||
Result.set_endpoint (l_endpoint)
|
||||
end
|
||||
end
|
||||
end
|
||||
feature {NONE} -- Implementation: User
|
||||
|
||||
fetch_user: detachable CMS_USER
|
||||
local
|
||||
l_id: INTEGER_64
|
||||
l_name: detachable READABLE_STRING_32
|
||||
do
|
||||
if attached sql_read_integer_32 (1) as i then
|
||||
l_id := i
|
||||
end
|
||||
if attached sql_read_string_32 (2) as s and then not s.is_whitespace then
|
||||
l_name := s
|
||||
end
|
||||
|
||||
if l_name /= Void then
|
||||
create Result.make (l_name)
|
||||
if l_id > 0 then
|
||||
Result.set_id (l_id)
|
||||
end
|
||||
elseif l_id > 0 then
|
||||
create Result.make_with_id (l_id)
|
||||
end
|
||||
|
||||
if Result /= Void then
|
||||
if attached sql_read_string (3) as l_password then
|
||||
-- FIXME: should we return the password here ???
|
||||
Result.set_hashed_password (l_password)
|
||||
end
|
||||
if attached sql_read_string (5) as l_email then
|
||||
Result.set_email (l_email)
|
||||
end
|
||||
if attached sql_read_integer_32 (6) as l_status then
|
||||
Result.set_status (l_status)
|
||||
end
|
||||
else
|
||||
check expected_valid_user: False end
|
||||
end
|
||||
end
|
||||
|
||||
feature -- {NONE} User OAuth2
|
||||
|
||||
sql_table_name (a_consumer: READABLE_STRING_8): STRING_8
|
||||
do
|
||||
Result := Sql_table_prefix.twin
|
||||
Result.append (a_consumer)
|
||||
end
|
||||
|
||||
Select_user_by_oauth2_template_token: STRING = "SELECT u.* FROM users as u JOIN $table_name as og ON og.uid = u.uid and og.access_token = :token;"
|
||||
|
||||
Select_user_oauth2_template_by_id: STRING = "SELECT u.* FROM users as u JOIN $table_name as og ON og.uid = u.uid and og.uid = :uid;"
|
||||
|
||||
Sql_insert_oauth2_template: STRING = "INSERT INTO $table_name (uid, access_token, details, created) VALUES (:uid, :token, :profile, :utc_date);"
|
||||
|
||||
Sql_update_oauth2_template: STRING = "UPDATE $table_name SET access_token = :token, details = :profile WHERE uid =:uid;"
|
||||
|
||||
Sql_oauth_consumers: STRING = "SELECT name FROM oauth2_consumers";
|
||||
|
||||
Sql_table_prefix: STRING = "oauth2_"
|
||||
|
||||
feature -- {NONE} Consumer
|
||||
|
||||
Sql_oauth_consumer_callback: STRING ="SELECT * FROM oauth2_consumers where callback_name =:name;"
|
||||
|
||||
Sql_oauth_consumer_name: STRING ="SELECT * FROM oauth2_consumers where name =:name;"
|
||||
|
||||
end
|
||||
@@ -109,4 +109,12 @@ feature -- Access
|
||||
Result:= sql_storage.sql_item (a_index)
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
sql_statement (a_statement: STRING): STRING
|
||||
-- <Precursor>
|
||||
do
|
||||
Result := sql_storage.sql_statement (a_statement)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -36,6 +36,7 @@ feature -- Initialization
|
||||
create u.make ("admin")
|
||||
u.set_password ("istrator#")
|
||||
u.set_email (a_setup.site_email)
|
||||
u.set_status ({CMS_USER}.active)
|
||||
a_storage.new_user (u)
|
||||
|
||||
--| Node
|
||||
@@ -74,16 +75,19 @@ feature -- Initialization
|
||||
create u.make ("auth")
|
||||
u.set_password ("enticated#")
|
||||
u.set_email (a_setup.site_email)
|
||||
u.set_status ({CMS_USER}.active)
|
||||
a_storage.new_user (u)
|
||||
|
||||
create u.make ("test")
|
||||
u.set_password ("test#")
|
||||
u.set_email (a_setup.site_email)
|
||||
u.set_status ({CMS_USER}.active)
|
||||
a_storage.new_user (u)
|
||||
|
||||
create u.make ("view")
|
||||
u.set_password ("only#")
|
||||
u.set_email (a_setup.site_email)
|
||||
u.set_status ({CMS_USER}.active)
|
||||
u.set_roles (l_roles)
|
||||
a_storage.new_user (u)
|
||||
end
|
||||
|
||||
@@ -76,7 +76,7 @@ feature -- Operation
|
||||
i := a_sql_statement.index_of (':', i)
|
||||
if i = 0 then
|
||||
i := n -- exit
|
||||
else
|
||||
elseif a_sql_statement.at (i-1).is_equal ('%'') or else a_sql_statement.at (i-1).is_equal ('%"') or else a_sql_statement.at (i-1).is_equal (' ') or else a_sql_statement.at (i-1).is_equal ('=') then
|
||||
from
|
||||
j := i + 1
|
||||
until
|
||||
@@ -124,6 +124,30 @@ feature -- Operation
|
||||
|
||||
feature -- Helper
|
||||
|
||||
sql_execute_file_script_with_params (a_path: PATH; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
-- Execute SQL script from `a_path' and with params `a_params'.
|
||||
local
|
||||
f: PLAIN_TEXT_FILE
|
||||
sql: STRING
|
||||
do
|
||||
create f.make_with_path (a_path)
|
||||
if f.exists and then f.is_access_readable then
|
||||
create sql.make (f.count)
|
||||
f.open_read
|
||||
from
|
||||
f.start
|
||||
until
|
||||
f.exhausted or f.end_of_file
|
||||
loop
|
||||
f.read_stream_thread_aware (1_024)
|
||||
sql.append (f.last_string)
|
||||
end
|
||||
f.close
|
||||
sql_execute_script_with_params (sql, a_params)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
sql_execute_file_script (a_path: PATH)
|
||||
-- Execute SQL script from `a_path'.
|
||||
local
|
||||
@@ -150,22 +174,50 @@ feature -- Helper
|
||||
sql_execute_script (a_sql_script: STRING)
|
||||
-- Execute SQL script.
|
||||
-- i.e: multiple SQL statements.
|
||||
local
|
||||
i: INTEGER
|
||||
err: BOOLEAN
|
||||
do
|
||||
reset_error
|
||||
-- sql_begin_transaction
|
||||
sql_change (a_sql_script, Void)
|
||||
-- sql_commit_transaction
|
||||
sql_begin_transaction
|
||||
-- Issue on MySQL with multiple statements
|
||||
-- sql_change (a_sql_script, Void)
|
||||
from
|
||||
i := 1
|
||||
until
|
||||
i > a_sql_script.count or err
|
||||
loop
|
||||
if attached next_sql_statement (a_sql_script, i) as s then
|
||||
if not s.is_whitespace then
|
||||
sql_change (sql_statement (s), Void)
|
||||
err := err or has_error
|
||||
reset_error
|
||||
end
|
||||
i := i + s.count
|
||||
else
|
||||
i := a_sql_script.count + 1
|
||||
end
|
||||
end
|
||||
if err then
|
||||
sql_rollback_transaction
|
||||
else
|
||||
sql_commit_transaction
|
||||
end
|
||||
end
|
||||
|
||||
sql_execute_script_with_params (a_sql_script: STRING; a_params: detachable STRING_TABLE [detachable ANY])
|
||||
-- Execute SQL script.
|
||||
-- i.e: multiple SQL statements.
|
||||
do
|
||||
reset_error
|
||||
sql_change (a_sql_script, a_params)
|
||||
end
|
||||
|
||||
sql_table_exists (a_table_name: READABLE_STRING_8): BOOLEAN
|
||||
-- Does table `a_table_name' exists?
|
||||
local
|
||||
l_params: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
reset_error
|
||||
create l_params.make (1)
|
||||
l_params.force (a_table_name, "tbname")
|
||||
sql_query ("SELECT count(*) FROM :tbname ;", l_params)
|
||||
sql_query ("SELECT count(*) FROM " + a_table_name + " ;", Void)
|
||||
Result := not has_error
|
||||
-- FIXME: find better solution
|
||||
reset_error
|
||||
@@ -173,13 +225,9 @@ feature -- Helper
|
||||
|
||||
sql_table_items_count (a_table_name: READABLE_STRING_8): INTEGER_64
|
||||
-- Number of items in table `a_table_name'?
|
||||
local
|
||||
l_params: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
reset_error
|
||||
create l_params.make (1)
|
||||
l_params.force (a_table_name, "tbname")
|
||||
sql_query ("SELECT count(*) FROM :tbname ;", l_params)
|
||||
sql_query ("SELECT count(*) FROM " + a_table_name + " ;", Void)
|
||||
if not has_error then
|
||||
Result := sql_read_integer_64 (1)
|
||||
end
|
||||
@@ -325,4 +373,77 @@ feature -- Access
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Conversion
|
||||
|
||||
sql_statement (a_statement: STRING): STRING
|
||||
-- Statement normalized for underlying SQL database.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
next_sql_statement (a_script: STRING; a_start_index: INTEGER): detachable STRING
|
||||
local
|
||||
i,j,n: INTEGER
|
||||
c: CHARACTER
|
||||
l_end: INTEGER
|
||||
do
|
||||
from
|
||||
i := a_start_index
|
||||
n := a_script.count
|
||||
until
|
||||
i > n or a_script[i] = ';'
|
||||
loop
|
||||
c := a_script[i]
|
||||
inspect c
|
||||
when '-' then
|
||||
if i < n and then a_script[i + 1] = '-' then
|
||||
-- Commented line "--" until New Line
|
||||
j := a_script.index_of ('%N', i)
|
||||
if j > 0 then
|
||||
i := j
|
||||
else
|
||||
i := n
|
||||
end
|
||||
end
|
||||
when '/' then
|
||||
if i < n and then a_script[i + 1] = '*' then
|
||||
-- Commented text "/*" until closing "*/"
|
||||
j := a_script.substring_index ("*/", i)
|
||||
if j > 0 then
|
||||
i := j
|
||||
else
|
||||
i := n
|
||||
end
|
||||
end
|
||||
when '`', '"', '%'' then
|
||||
from
|
||||
j := i
|
||||
l_end := 0
|
||||
until
|
||||
l_end > 0 or j > n
|
||||
loop
|
||||
j := a_script.index_of (c, i + 1)
|
||||
if j > i then
|
||||
if a_script [j - 1] /= '\' then
|
||||
l_end := j
|
||||
end
|
||||
end
|
||||
end
|
||||
if l_end > 0 then
|
||||
i := l_end
|
||||
else
|
||||
i := j
|
||||
end
|
||||
else
|
||||
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
i := a_script.index_of (';', a_start_index)
|
||||
if i > a_start_index then
|
||||
Result := a_script.substring (a_start_index, i)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -56,6 +56,20 @@ feature -- Access
|
||||
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||
end
|
||||
|
||||
user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
-- User with activation token `a_token', if any.
|
||||
deferred
|
||||
ensure
|
||||
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||
end
|
||||
|
||||
user_by_password_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
-- User with password token `a_token', if any.
|
||||
deferred
|
||||
ensure
|
||||
password: Result /= Void implies (Result.hashed_password /= Void and Result.password = Void)
|
||||
end
|
||||
|
||||
is_valid_credential (a_u, a_p: READABLE_STRING_32): BOOLEAN
|
||||
-- Does account with username `a_username' and password `a_password' exist?
|
||||
deferred
|
||||
@@ -141,4 +155,28 @@ feature -- Change: roles and permissions
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: User activation
|
||||
|
||||
save_activation (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>.
|
||||
deferred
|
||||
end
|
||||
|
||||
remove_activation (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
deferred
|
||||
end
|
||||
|
||||
feature -- Change: User password recovery
|
||||
|
||||
save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>.
|
||||
deferred
|
||||
end
|
||||
|
||||
remove_password (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -34,6 +34,14 @@ feature -- Access: user
|
||||
do
|
||||
end
|
||||
|
||||
user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
do
|
||||
end
|
||||
|
||||
user_by_password_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
do
|
||||
end
|
||||
|
||||
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
||||
do
|
||||
end
|
||||
@@ -76,4 +84,28 @@ feature -- Change: roles and permissions
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Change: User activation
|
||||
|
||||
save_activation (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>.
|
||||
do
|
||||
end
|
||||
|
||||
remove_activation (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
do
|
||||
end
|
||||
|
||||
feature -- Change: User password recovery
|
||||
|
||||
save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>.
|
||||
do
|
||||
end
|
||||
|
||||
remove_password (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
do
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -62,7 +62,7 @@ feature -- Access: user
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user")
|
||||
write_information_log (generator + ".user_by_id")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_id, "uid")
|
||||
sql_query (select_user_by_id, l_parameters)
|
||||
@@ -107,6 +107,40 @@ feature -- Access: user
|
||||
end
|
||||
end
|
||||
|
||||
user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
-- User for the given activation token `a_token', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_by_activation_token")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_query (select_user_by_activation_token, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
user_by_password_token (a_token: READABLE_STRING_32): detachable CMS_USER
|
||||
-- User for the given password token `a_token', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_by_password_token")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_query (select_user_by_password_token, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := fetch_user
|
||||
else
|
||||
check no_more_than_one: sql_rows_count = 0 end
|
||||
end
|
||||
end
|
||||
|
||||
is_valid_credential (l_auth_login, l_auth_password: READABLE_STRING_32): BOOLEAN
|
||||
local
|
||||
l_security: SECURITY_PROVIDER
|
||||
@@ -155,6 +189,7 @@ feature -- Change: user
|
||||
l_parameters.put (l_password_salt, "salt")
|
||||
l_parameters.put (l_email, "email")
|
||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "created")
|
||||
l_parameters.put (a_user.status, "status")
|
||||
|
||||
sql_change (sql_insert_user, l_parameters)
|
||||
if not error_handler.has_error then
|
||||
@@ -197,6 +232,7 @@ feature -- Change: user
|
||||
l_parameters.put (l_password_salt, "salt")
|
||||
l_parameters.put (l_email, "email")
|
||||
l_parameters.put (create {DATE_TIME}.make_now_utc, "changed")
|
||||
l_parameters.put (a_user.status, "status")
|
||||
|
||||
sql_change (sql_update_user, l_parameters)
|
||||
else
|
||||
@@ -441,6 +477,107 @@ feature -- Change: roles and permissions
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
feature -- Access: User activation
|
||||
|
||||
activation_elapsed_time (a_token: READABLE_STRING_32): INTEGER_32
|
||||
-- amount of time that has passed in days since the token `a_token' was saved.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".activation_elapsed_time")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_query (sql_select_activation_expiration, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := sql_read_integer_32 (1)
|
||||
end
|
||||
end
|
||||
|
||||
user_id_by_activation (a_token: READABLE_STRING_32): INTEGER_64
|
||||
-- User id associatied with a token `a_token', if any.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
write_information_log (generator + ".user_id_by_actication")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_query (sql_select_userid_activation, l_parameters)
|
||||
if sql_rows_count = 1 then
|
||||
Result := sql_read_integer_32 (1)
|
||||
end
|
||||
end
|
||||
|
||||
feature -- Change: User activation
|
||||
|
||||
save_activation (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_utc_date: DATE_TIME
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
write_information_log (generator + ".save_activation")
|
||||
create l_utc_date.make_now_utc
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_token, "token")
|
||||
l_parameters.put (a_id, "uid")
|
||||
l_parameters.put (l_utc_date, "utc_date")
|
||||
sql_change (sql_insert_activation, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
remove_activation (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
write_information_log (generator + ".remove_activation")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_change (sql_remove_activation, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
feature -- Change: User password recovery
|
||||
|
||||
save_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
|
||||
-- <Precursor>
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
l_utc_date: DATE_TIME
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
write_information_log (generator + ".save_password")
|
||||
create l_utc_date.make_now_utc
|
||||
create l_parameters.make (2)
|
||||
l_parameters.put (a_token, "token")
|
||||
l_parameters.put (a_id, "uid")
|
||||
l_parameters.put (l_utc_date, "utc_date")
|
||||
sql_change (sql_insert_password, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
remove_password (a_token: READABLE_STRING_32)
|
||||
-- <Precursor>.
|
||||
local
|
||||
l_parameters: STRING_TABLE [detachable ANY]
|
||||
do
|
||||
error_handler.reset
|
||||
sql_begin_transaction
|
||||
write_information_log (generator + ".remove_password")
|
||||
create l_parameters.make (1)
|
||||
l_parameters.put (a_token, "token")
|
||||
sql_change (sql_remove_password, l_parameters)
|
||||
sql_commit_transaction
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation: User
|
||||
|
||||
user_salt (a_username: READABLE_STRING_32): detachable READABLE_STRING_8
|
||||
@@ -489,6 +626,9 @@ feature {NONE} -- Implementation: User
|
||||
if attached sql_read_string (5) as l_email then
|
||||
Result.set_email (l_email)
|
||||
end
|
||||
if attached sql_read_integer_32 (6) as l_status then
|
||||
Result.set_status (l_status)
|
||||
end
|
||||
else
|
||||
check expected_valid_user: False end
|
||||
end
|
||||
@@ -551,10 +691,11 @@ feature {NONE} -- Sql Queries: USER
|
||||
Select_salt_by_username: STRING = "SELECT salt FROM Users WHERE name =:name;"
|
||||
-- Retrieve salt by username if exists.
|
||||
|
||||
sql_insert_user: STRING = "INSERT INTO users (name, password, salt, email, created) VALUES (:name, :password, :salt, :email, :created);"
|
||||
-- SQL Insert to add a new node.
|
||||
sql_insert_user: STRING = "INSERT INTO users (name, password, salt, email, created, status) VALUES (:name, :password, :salt, :email, :created, :status);"
|
||||
-- SQL Insert to add a new user.
|
||||
|
||||
sql_update_user: STRING = "UPDATE users SET name=:name, password=:password, salt=:salt, email=:email WHERE uid=:uid;"
|
||||
sql_update_user: STRING = "UPDATE users SET name=:name, password=:password, salt=:salt, email=:email, status=:status WHERE uid=:uid;"
|
||||
-- SQL update to update an existing user.
|
||||
|
||||
feature {NONE} -- Sql Queries: USER ROLE
|
||||
|
||||
@@ -584,4 +725,32 @@ feature {NONE} -- Sql Queries: USER ROLE
|
||||
select_role_permissions_by_role_id: STRING = "SELECT permission, module FROM role_permissions WHERE rid=:rid;"
|
||||
-- User role permissions for role id :rid;
|
||||
|
||||
feature {NONE} -- Sql Queries: USER ACTIVATION
|
||||
|
||||
sql_insert_activation: STRING = "INSERT INTO users_activations (token, uid, created) VALUES (:token, :uid, :utc_date);"
|
||||
-- SQL insert a new activation :token.
|
||||
|
||||
sql_select_activation_expiration: STRING = "SELECT DATEDIFF(day,created,UTC_DATE()) FROM users_activations where token = :token;"
|
||||
-- elapsed time that has passed in days since the token `a_token' was saved.
|
||||
|
||||
sql_select_userid_activation: STRING = "SELECT uid FROM users_activations where token = :token;"
|
||||
-- Retrieve userid given the activation token.
|
||||
|
||||
Select_user_by_activation_token: STRING = "SELECT u.* FROM users as u JOIN users_activations as ua ON ua.uid = u.uid and ua.token = :token;"
|
||||
-- Retrieve user by activation token if exist.
|
||||
|
||||
Sql_remove_activation: STRING = "DELETE FROM users_activations WHERE token = :token;"
|
||||
-- Remove activation token.
|
||||
|
||||
feature {NONE} -- User Password Recovery
|
||||
|
||||
sql_insert_password: STRING = "INSERT INTO users_password_recovery (token, uid, created) VALUES (:token, :uid, :utc_date);"
|
||||
-- SQL insert a new password recovery :token.
|
||||
|
||||
Sql_remove_password: STRING = "DELETE FROM users_password_recovery WHERE token = :token;"
|
||||
-- Retrieve password if exist.
|
||||
|
||||
Select_user_by_password_token: STRING = "SELECT u.* FROM users as u JOIN users_password_recovery as ua ON ua.uid = u.uid and ua.token = :token;"
|
||||
-- Retrieve user by password token if exist.
|
||||
|
||||
end
|
||||
|
||||
@@ -22,9 +22,9 @@ inherit
|
||||
|
||||
WSF_NO_PROXY_POLICY
|
||||
|
||||
WSF_URI_HELPER_FOR_ROUTED_EXECUTION
|
||||
WSF_ROUTED_URI_HELPER
|
||||
|
||||
WSF_URI_TEMPLATE_HELPER_FOR_ROUTED_EXECUTION
|
||||
WSF_ROUTED_URI_TEMPLATE_HELPER
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
|
||||
102
src/service/email/email_service.e
Normal file
102
src/service/email/email_service.e
Normal file
@@ -0,0 +1,102 @@
|
||||
note
|
||||
description: "Basic Email Service"
|
||||
date: "$Date: 2015-04-30 05:45:25 -0300 (ju. 30 de abr. de 2015) $"
|
||||
revision: "$Revision: 97218 $"
|
||||
|
||||
class
|
||||
EMAIL_SERVICE
|
||||
|
||||
inherit
|
||||
|
||||
SHARED_ERROR
|
||||
SHARED_LOGGER
|
||||
|
||||
create
|
||||
make
|
||||
|
||||
feature {NONE} -- Initialization
|
||||
|
||||
make (a_params: like parameters)
|
||||
-- Create instance of {EMAIL_SERVICE} with smtp_server `a_params.smtp_server'.
|
||||
-- Using `a_params.admin_email' as admin email.
|
||||
do
|
||||
parameters := a_params
|
||||
initialize
|
||||
end
|
||||
|
||||
initialize
|
||||
-- Initialize service.
|
||||
local
|
||||
l_address_factory: INET_ADDRESS_FACTORY
|
||||
do
|
||||
admin_email := parameters.admin_email
|
||||
|
||||
-- Get local host name needed in creation of SMTP_PROTOCOL.
|
||||
create l_address_factory
|
||||
create smtp_protocol.make (parameters.smtp_server, l_address_factory.create_localhost.host_name)
|
||||
set_successful
|
||||
end
|
||||
|
||||
parameters: EMAIL_SERVICE_PARAMETERS
|
||||
-- Associated parameters.
|
||||
|
||||
admin_email: IMMUTABLE_STRING_8
|
||||
-- Site admin's email.
|
||||
|
||||
smtp_protocol: SMTP_PROTOCOL
|
||||
-- SMTP protocol.
|
||||
|
||||
feature -- Basic Operations
|
||||
|
||||
send_internal_email (a_content: READABLE_STRING_GENERAL)
|
||||
do
|
||||
send_message (admin_email, admin_email, "Notification Contact", a_content)
|
||||
end
|
||||
|
||||
send_email_internal_server_error (a_content: READABLE_STRING_GENERAL)
|
||||
do
|
||||
send_message (admin_email, admin_email, "Internal Server Error", a_content)
|
||||
end
|
||||
|
||||
send_message (a_from_address, a_to_address: READABLE_STRING_8; a_subjet: READABLE_STRING_GENERAL; a_content: READABLE_STRING_GENERAL)
|
||||
local
|
||||
l_email: EMAIL
|
||||
utf: UTF_CONVERTER
|
||||
do
|
||||
write_debug_log (generator + ".send_message: [from:" + a_from_address + ", to:" + a_to_address + ", subject:" + a_subjet + ", content:" + a_content)
|
||||
create l_email.make_with_entry (a_from_address, a_to_address)
|
||||
l_email.set_message (utf.escaped_utf_32_string_to_utf_8_string_8 (a_content))
|
||||
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, utf.escaped_utf_32_string_to_utf_8_string_8 (a_subjet))
|
||||
l_email.add_header_entry ("MIME-Version:", "1.0")
|
||||
l_email.add_header_entry ("Content-Type", "text/html; charset=utf-8")
|
||||
send_email (l_email)
|
||||
end
|
||||
|
||||
feature {NONE} -- Implementation
|
||||
|
||||
send_email (a_email: EMAIL)
|
||||
-- Send the email represented by `a_email'.
|
||||
local
|
||||
l_retried: BOOLEAN
|
||||
do
|
||||
if not l_retried then
|
||||
write_information_log (generator + ".send_email Process send email.")
|
||||
smtp_protocol.initiate_protocol
|
||||
smtp_protocol.transfer (a_email)
|
||||
smtp_protocol.close_protocol
|
||||
write_information_log (generator + ".send_email Email sent.")
|
||||
if smtp_protocol.error then
|
||||
set_last_error ("smtp_protocol reported an error", generator + ".send_email")
|
||||
else
|
||||
set_successful
|
||||
end
|
||||
else
|
||||
write_error_log (generator + ".send_email Email not send " + last_error_message )
|
||||
end
|
||||
rescue
|
||||
set_last_error_from_exception (generator + ".send_email")
|
||||
l_retried := True
|
||||
retry
|
||||
end
|
||||
|
||||
end
|
||||
20
src/service/email/email_service_parameters.e
Normal file
20
src/service/email/email_service_parameters.e
Normal file
@@ -0,0 +1,20 @@
|
||||
note
|
||||
description: "Basic Email Service customized for cms site"
|
||||
author: ""
|
||||
date: "$Date: 2015-01-16 07:17:14 -0300 (vi. 16 de ene. de 2015) $"
|
||||
revision: "$Revision: 96467 $"
|
||||
|
||||
deferred class
|
||||
EMAIL_SERVICE_PARAMETERS
|
||||
|
||||
feature -- Access
|
||||
|
||||
smtp_server: IMMUTABLE_STRING_8
|
||||
deferred
|
||||
end
|
||||
|
||||
admin_email: IMMUTABLE_STRING_8
|
||||
deferred
|
||||
end
|
||||
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user