view release on metacpan or search on metacpan
0.17.0 2019-05-31 16:02:43 +0200 Tobias Oetiker <tobi@oetiker.ch>
- add the triggerFormReset key to form elements, when a widget has this key
set the form configuration will be re-queried from the server, and the
current content of the form will be available in $self->args. In this
way it is possible to change settings of the form widgets based on the current
form content, as well as altering the content of selectboxes.
0.16.0 2019-04-23 17:04:50 +0200 Tobias Oetiker <tobi@oetiker.ch>
- if the getUserConfig returns a sessionCookie property, start using it
to authenticate and thus skipping the login step. this can be used to
implement single sign on ... see bdass.
0.15.1 2019-04-03 15:44:12 +0200 Tobias Oetiker <tobi@oetiker.ch>
- added missing NumberFormatter to archive
0.15.0 2019-04-03 15:13:53 +0200 Tobias Oetiker <tobi@oetiker.ch>
- added support for numberformating ... 1000 Byte => 1 kByte
lib/CallBackery/Controller/RpcService.pm view on Meta::CPAN
my %allow = (
getBaseConfig => 1,
login => 1,
logout => 1,
ping => 1,
getUserConfig => 2,
getPluginConfig => 3,
validatePluginData => 3,
processPluginData => 3,
getPluginData => 3,
getSessionCookie => 2
);
has config => sub ($self) {
$self->app->config;
}, weak => 1;
has user => sub ($self) {
my $obj = $self->app->userObject->new(app=>$self->app,controller=>$self,log=>$self->log);
return $obj;
};
lib/CallBackery/Controller/RpcService.pm view on Meta::CPAN
=head2 ping()
check if the server is happy with our authentication state
=cut
sub ping {
return 'pong';
}
=head2 getSessionCookie()
Return a timeestamped session cookie. For use in the X-Session-Cookie header or as a xsc field
in form submissions. Note that session cookies for form submissions are only valid for 2 seconds.
So you have to get a fresh one from the server before submitting your form.
=cut
sub getSessionCookie {
shift->user->makeSessionCookie();
}
=head2 getConfig()
get some gloabal configuration information into the interface
=cut
sub getBaseConfig {
my $self = shift;
lib/CallBackery/Controller/RpcService.pm view on Meta::CPAN
=cut
async sub login { ## no critic (RequireArgUnpacking)
my $self = shift;
my $login = shift;
my $password = shift;
my $cfg = $self->config->cfgHash->{BACKEND};
if (my $ok =
await $self->config->promisify($self->user->login($login,$password))){
return {
sessionCookie => $self->user->makeSessionCookie()
}
} else {
return;
}
}
=head2 logout
Kill the session.
lib/CallBackery/User.pm view on Meta::CPAN
=cut
has loginName => sub {
shift->userInfo->{cbuser_login} // '*UNKNOWN*';
};
=head2 $self->sessionConf
Extracts the session config from the cookie from the X-Session-Cookie header or the xsc parameter.
If the xsc parameter is set, its timestamp must be no older than 2 seconds.
=cut
has headerSessionCookie => sub {
my $self = shift;
my $c = $self->controller;
return $c->req->headers->header('X-Session-Cookie');
};
has paramSessionCookie => sub {
my $self = shift;
my $c = $self->controller;
return $c->param('xsc');
};
has firstSecret => sub {
shift->app->secrets()->[0];
};
sub isUserAuthenticated {
my $self = shift;
$self->userInfo->{cbuser_id} ? 1 : 0;
};
has cookieConf => sub {
my $self = shift;
my $headerCookie = $self->headerSessionCookie;
my $paramCookie = $self->paramSessionCookie;
my ($data,$check) = split /:/,($headerCookie || $paramCookie || ''),2;
return {} if not ($data and $check);
my $secret = $self->firstSecret;
my $checkTest = Mojo::Util::hmac_sha1_sum($data, $secret);
if (not secure_compare($check,$checkTest)){
$self->log->debug(qq{Bad signed cookie possible hacking attempt.});
return {};
}
lib/CallBackery/User.pm view on Meta::CPAN
my $conf = eval {
local $SIG{__DIE__};
decode_json(b64_decode($data))
};
if ($@){
$self->log->debug("Invalid cookie structure in '$data': $@");
return {};
}
if (ref $conf ne 'HASH'){
$self->log->debug("Cookie structure not a hash");
return {};
}
if (not $conf->{t}){
$self->log->debug("Cookie timestamp is invalid");
return {};
}
if ($paramCookie and gettimeofday() - $conf->{t} > 300.0){
$self->log->debug(qq{Cookie is expired});
die mkerror(38445,"cookie has expired");
}
return $conf;
};
=head2 $user->login($login,$password)
login the user object. If login return 1 you can then makeSessionCookie.
=cut
sub login {
my $self = shift;
my $login = shift;
my $password = shift;
my $cfg = $self->app->config->cfgHash;
my $remoteAddress = eval { $self->controller->tx->remote_address } // 'UNKNOWN_IP';
if ($cfg->{sesame_pass} and $cfg->{sesame_user}
lib/CallBackery/User.pm view on Meta::CPAN
# root has all the rights
if (($self->userId // '') eq '__ROOT'){
return 1;
}
my $db = $self->db;
my $rightId = $db->lookUp('cbright','key',$right);
my $userId = $self->userId;
return ($db->matchData('cbuserright',{cbuser=>$userId,cbright=>$rightId}) ? 1 : 0);
}
=head2 makeSessionCookie()
Returns a timestamped, signed session cookie containing the current userId.
=cut
sub makeSessionCookie {
my $self = shift;
my $timeout = shift;
my $now = gettimeofday;
my $conf = b64_encode(encode_json({
u => $self->userId,
t => $now,
}));
$conf =~ s/\s+//g;
my $secret = $self->firstSecret;
my $check = Mojo::Util::hmac_sha1_sum($conf, $secret);
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Config.js view on Meta::CPAN
if (base){
base[1].split(/;/).forEach(function(kv){
var list = kv.split('=');
ha[list[0]] = decodeURIComponent(list[1]);
});
}
window.location.hash = '';
return ha;
},
/* if there is a sessonCookie in the userConfig start using it. This allows for seemless login */
_applyUserConfig: function(newData,oldData) {
if (newData.userInfo && newData.userInfo.sessionCookie) {
callbackery.data.Server.getInstance().setSessionCookie(newData.userInfo.sessionCookie);
}
}
}
});
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js view on Meta::CPAN
this.base( arguments );
this.set( {
timeout: 180000,
url: 'QX-JSON-RPC/',
serviceName: 'default',
protocol: 'qx1'
});
},
properties: {
sessionCookie: {
init: null,
nullable: true
}
},
members: {
/**
* A asyncCall handler which tries to
* login in the case of a permission exception.
*
* @param handler {Function} the callback function.
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js view on Meta::CPAN
var origThis = this;
var localeMgr = qx.locale.Manager.getInstance();
var newArgs = Array.prototype.slice.call(arguments);
newArgs[0] = function(ret, exc, id) {
if (exc) {
switch (exc.code) {
case 6:
let login = callbackery.ui.Login.getInstance();
login.addListenerOnce('login', (e) => {
let ret = e.getData();
origThis.setSessionCookie(ret.sessionCookie);
origArguments.callee.base.apply(origThis, origArguments);
});
login.open();
return;
case 7:
if (window.console){
window.console.log("Session Expired. Reloading page");
}
callbackery.ui.Busy.getInstance().vanish();
let mb = callbackery.ui.MsgBox.getInstance()
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/data/Server.js view on Meta::CPAN
var newArgs = Array.prototype.slice.call(arguments);
newArgs[0] = superHandler;
busy.manifest('Runnning ' + methodName);
this.callAsync.apply(this, newArgs);
},
/**
* override the request creation, to add our 'cookie' header
*/
createRequest: function() {
var req = this.base(arguments);
var cookie = this.getSessionCookie();
if (cookie) {
req.setRequestHeader('X-Session-Cookie', this.getSessionCookie());
}
return req;
}
}
});
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/Login.js view on Meta::CPAN
iframe.setAttribute('src',
'login?nocache='+Math.round(1000000*Math.random()).toString(16));
return iframe;
},
__getIframeDocument: function(){
var iframe = this.__iframe;
return iframe.contentWindow ? iframe.contentWindow.document : iframe.contentDocument;
},
__loginHandler : function(ret, exc) {
if (exc == null) {
if (qx.lang.Type.isObject(ret) && ret.sessionCookie) {
// submit the iframe form to trigger the browser to save the password
this.__getIframeDocument().getElementById('cbLoginForm').submit();
this.fireDataEvent('login', ret);
this.close();
}
else {
var element = this.getContentElement().getDomElement();
var tada = {duration: 1000, keyFrames : {
0 : {scale: 1, rotate: "0deg"},
10 : {scale: 0.9, rotate: "-3deg"},
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/plugin/Action.js view on Meta::CPAN
that.xtr(response.exception.message) + " (" + response.exception.code + ")"
);
}
that.getApplicationRoot().remove(iframe);
if (btCfg.closeAfterDownload) {
that.fireDataEvent('actionResponse', { action: 'cancel' });
}
});
iframe.setSource(url);
that.getApplicationRoot().add(iframe, { top: -1000, left: -1000 });
}, 'getSessionCookie');
break;
case 'cancel':
this.fireDataEvent('actionResponse', { action: 'cancel' });
break;
case 'wizzard':
var parent = that.getLayoutParent();
while (!parent.classname.match(/Page|Popup/)) {
parent = parent.getLayoutParent();
}
// This could in principal work for Page although.
lib/CallBackery/qooxdoo/callbackery/source/class/callbackery/ui/plugin/Action.js view on Meta::CPAN
if (formData && fileList) {
var form = new FormData();
form.append('name', name);
form.append('key', key);
form.append('file', fileList[0]);
form.append('formData', qx.lang.Json.stringify(formData));
var that = this;
serverCall.callAsyncSmart(function (cookie) {
form.append('xsc', cookie);
that._uploadForm(form,btCfg.busyMessage);
}, 'getSessionCookie');
} else {
callbackery.ui.MsgBox.getInstance().error(
this.tr("Upload Exception"),
this.tr("Make sure to select a file and properly fill the form")
);
}
}, this);
return button;
},