mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-03-03 10:46:53 +00:00
76_SMAPortal: imptove cookie/login management
git-svn-id: https://svn.fhem.de/fhem/trunk@22276 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
cbbf89e124
commit
1b5fe39087
@ -1,5 +1,6 @@
|
||||
# Add changes at the top of the list. Keep it in ASCII, and 80-char wide.
|
||||
# Do not insert empty lines here, update check depends on it.
|
||||
- change: 76_SMAPortal: imptove cookie/login management
|
||||
- feature: 49_SSCam / 49_SSCamSTRM: new capability operate PTZ Zoom cameras
|
||||
- changed: 76_SMAPortal: get plantOid from cookie if not in JSON
|
||||
- bugfix: 70_ZoneMinder: fix afterInitialized (thx GeberNehmer)
|
||||
|
@ -136,6 +136,7 @@ BEGIN {
|
||||
|
||||
# Versions History intern
|
||||
my %vNotesIntern = (
|
||||
"3.1.2" => "25.06.2020 don't delete cookie after every data retrieval, change login management ",
|
||||
"3.1.1" => "24.06.2020 change german Error regex, get plantOid from cookie if not in JSON ",
|
||||
"3.1.0" => "20.06.2020 language of SMA Portal messages depend on global language attribute, avoid order problems by ".
|
||||
"executing retrieve master data firstly every time",
|
||||
@ -200,8 +201,8 @@ my %vNotesIntern = (
|
||||
);
|
||||
|
||||
# Voreinstellungen
|
||||
my $maxretries = 6; # max. Anzahl Wiederholungen in einem Abruf-Zyklus
|
||||
my $thold = int($maxretries/2); # Schwellenwert nicht erfolgreicher Leseversuche in einem Zyklus mit dem gleichen Cookie
|
||||
my $maxretries = 8; # max. Anzahl Wiederholungen in einem Abruf-Zyklus
|
||||
my $thold = int($maxretries/2); # Schwellenwert nicht erfolgreicher Leseversuche in einem Zyklus mit dem gleichen Cookie, Standard: int($maxretries/2)
|
||||
my $sleepretry = 0.5; # Sleep zwischen Data Call Retries (ohne Threshold Überschreitung)
|
||||
my $sleepexc = 2; # Sleep vor neuem Datencall nach Überschreitung Threshold (Data Calls mit gleichem Cookie)
|
||||
my $defmaxcycles = 19; # Standard max. Anzahl Datenabrufzyklen abgeleitet von Interval 120 (wird bei Automatic berechnet)
|
||||
@ -381,6 +382,7 @@ sub Set { ## no critic 'complexity'
|
||||
($success) = setcredentials($hash,$prop,$prop1);
|
||||
|
||||
if($success) {
|
||||
delcookiefile ($hash);
|
||||
CallInfo($hash);
|
||||
return "Username and Password saved successfully";
|
||||
} else {
|
||||
@ -658,7 +660,8 @@ sub Attr {
|
||||
$val = ($do == 1 ? "disabled" : "initialized");
|
||||
|
||||
if($do) {
|
||||
deleteData($hash);
|
||||
deleteData ($hash);
|
||||
delcookiefile ($hash);
|
||||
delete $hash->{MODE};
|
||||
RemoveInternalTimer($hash);
|
||||
} else {
|
||||
@ -812,16 +815,16 @@ return ($interval,$maxcycles,$timeout,$ctime);
|
||||
################################################################
|
||||
sub GetSetData { ## no critic 'complexity'
|
||||
my ($string) = @_;
|
||||
my ($name,$getp,$setp) = split("\\|",$string);
|
||||
my $hash = $defs{$name};
|
||||
my $useragent = AttrVal($name, "userAgent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
|
||||
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||
my $v5d = AttrVal($name, "verbose5Data", "none");
|
||||
my $verbose = AttrVal($name, "verbose", 3);
|
||||
my $lang = AttrVal("global", "language", "EN");
|
||||
my $state = "ok";
|
||||
my ($st,$lc) = ("","");
|
||||
my @da = ();
|
||||
my ($name,$getp,$setp) = split("\\|",$string);
|
||||
my $hash = $defs{$name};
|
||||
my $useragent = AttrVal($name, "userAgent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)");
|
||||
my $cookieLocation = AttrVal($name, "cookieLocation", "./log/".$name."_cookie.txt");
|
||||
my $v5d = AttrVal($name, "verbose5Data", "none");
|
||||
my $verbose = AttrVal($name, "verbose", 3);
|
||||
my $lang = AttrVal("global", "language", "EN");
|
||||
my $state = "ok";
|
||||
my ($st,$lc) = ("","");
|
||||
my @da = ();
|
||||
|
||||
my ($errstate,$reread,$retry,$exceed,$newcycle) = (0,0,0,0,0);
|
||||
|
||||
@ -866,7 +869,7 @@ sub GetSetData { ## no cri
|
||||
### Login
|
||||
##############
|
||||
my $paref = [ $name, $ua, $state, $errstate ];
|
||||
($state, $errstate) = _checkLogin ($paref);
|
||||
($state, $errstate) = _doLogin ($paref);
|
||||
|
||||
if($errstate) {
|
||||
$st = encode_base64 ( $state,"");
|
||||
@ -944,7 +947,7 @@ sub GetSetData { ## no cri
|
||||
goto &GetSetData if($reread);
|
||||
|
||||
# Wiederholung Datenabruf innerhalb eines Cycle
|
||||
my $retc = $hash->{HELPER}{RETRIES}; # aktuelle Retry-Zähler
|
||||
my $retc = $hash->{HELPER}{RETRIES}; # aktuelle Retry-Zähler
|
||||
|
||||
if($retry && $retc < $maxretries) { # neuer Retry im gleichen Zyklus (nicht wenn Verbraucher schalten)
|
||||
$hash->{HELPER}{RETRIES}++;
|
||||
@ -964,7 +967,7 @@ sub GetSetData { ## no cri
|
||||
my $ac = $hash->{HELPER}{ACTCYCLE};
|
||||
my $maxcycles = (controlParams $name)[1];
|
||||
if($retry && $ac < $maxcycles) { # neuer Zyklus (nicht wenn Verbraucher schalten)
|
||||
Log3 ($name, 3, qq{$name - Maximum retries reached, delete cookie and start new cycle ...});
|
||||
Log3 ($name, 3, qq{$name - Maximum retries reached, start new data get cycle ...});
|
||||
$newcycle = 1;
|
||||
return "$name|$exceed|$newcycle|$errstate|$getp|$setp";
|
||||
}
|
||||
@ -976,6 +979,7 @@ sub GetSetData { ## no cri
|
||||
if(@da) {
|
||||
$lc = join "###", @da;
|
||||
$lc = encode_base64 ( $lc, "");
|
||||
Log3 ($name, 3, "$name - data retrieved successfully.");
|
||||
}
|
||||
|
||||
return "$name|$exceed|$newcycle|$errstate|$getp|$setp|$st|$lc";
|
||||
@ -984,7 +988,7 @@ return "$name|$exceed|$newcycle|$errstate|$getp|$setp|$st|$lc";
|
||||
################################################################
|
||||
# Login Status checken und ggf. einloggen
|
||||
################################################################
|
||||
sub _checkLogin {
|
||||
sub _doLogin {
|
||||
my $paref = shift;
|
||||
my $name = $paref->[0];
|
||||
my $ua = $paref->[1];
|
||||
@ -994,30 +998,31 @@ sub _checkLogin {
|
||||
my $hash = $defs{$name};
|
||||
my $v5d = AttrVal($name, "verbose5Data", "none");
|
||||
my $verbose = AttrVal($name, "verbose", 3);
|
||||
|
||||
my $loginp = $ua->post('https://www.sunnyportal.com/Templates/Start.aspx');
|
||||
my $retcode = $loginp->code;
|
||||
my $location = $loginp->header('Location') // "";
|
||||
|
||||
if($verbose == 5 && $v5d =~ /loginData/) {
|
||||
$ua->add_handler( request_send => sub { shift->dump; return } ); # for debugging
|
||||
$ua->add_handler( response_done => sub { shift->dump; return } );
|
||||
}
|
||||
|
||||
my ($success, $username, $password) = getcredentials($hash,0); # gespeicherte Credentials abrufen
|
||||
|
||||
my $loginp = $ua->post('https://www.sunnyportal.com/Templates/Start.aspx');
|
||||
my $retcode = $loginp->code;
|
||||
my $location = $loginp->header('Location') // "";
|
||||
my $cookie = $loginp->header('Set-Cookie') // "";
|
||||
|
||||
if ($loginp->is_success) {
|
||||
if($v5d =~ /loginData/) {
|
||||
Log3 ($name, 5, "$name - Status Login Page: ".$loginp->status_line);
|
||||
Log3 ($name, 5, "$name - Header Location: ".$location);
|
||||
Log3 ($name, 5, "$name - Header Location: ". $location);
|
||||
Log3 ($name, 5, "$name - Header Set-Cookie: ".$cookie);
|
||||
}
|
||||
|
||||
$retcode = $loginp->code;
|
||||
$location = $loginp->header('Location') // "";
|
||||
|
||||
if($location ne "/FixedPages/HoManLive.aspx" || $retcode ne "302") { # keine aktive Session -> neuer Login
|
||||
if(!__isLoggedIn ($name,$username,$loginp)) { # keine aktive Session -> neuer Login
|
||||
Log3 ($name, 4, "$name - User not logged in. Try login with credentials ...");
|
||||
|
||||
# Credentials abrufen
|
||||
my ($success, $username, $password) = getcredentials($hash,0);
|
||||
|
||||
if(!$success) {
|
||||
Log3($name, 1, qq{$name - Credentials couldn't be retrieved successfully - make sure you've set it with "set $name credentials <username> <password>"});
|
||||
@ -1044,29 +1049,31 @@ sub _checkLogin {
|
||||
my ($logname) = $sc =~ /SunnyPortalLoginInfo=Username=(.*?)&/sx;
|
||||
Log3 ($name, 5, "$name - Header Set-Cookie: ".$sc) if($v5d =~ /loginData/);
|
||||
|
||||
if($logname && $logname eq $username) { # Login erfolgeich(Landing Pages können im Portal eingestellt werden!)
|
||||
Log3 ($name, 3, "$name - Login into SMA-Portal successfully done with user: $logname");
|
||||
if(__isLoggedIn ($name,$username,$loginp)) { # Login erfolgeich(Landing Pages können im Portal eingestellt werden!)
|
||||
handleCounter ($name, "dailyIssueCookieCounter"); # Cookie Ausstellungszähler setzen
|
||||
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "loginState:successful", "oldlogintime:".(gettimeofday())[0] ], 1);
|
||||
$errstate = 0;
|
||||
|
||||
} else {
|
||||
Log3 ($name, 2, "$name - ERROR - Login into SMA-Portal failed !");
|
||||
$state = "login failed - check user and password";
|
||||
$state = "login failed";
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "loginState:failed", "NULL" ], 1);
|
||||
$errstate = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} elsif($loginp->is_redirect) {
|
||||
} elsif ($loginp->is_redirect) {
|
||||
$retcode = $loginp->code;
|
||||
$location = $loginp->header('Location') // "";
|
||||
Log3 ($name, 3, "$name - User is already logged in.");
|
||||
|
||||
if($v5d =~ /loginData/) {
|
||||
Log3 ($name, 5, "$name - Redirect return code: ".$retcode);
|
||||
Log3 ($name, 5, "$name - Redirect return code: ". $retcode );
|
||||
Log3 ($name, 5, "$name - Redirect Header Location: ".$location);
|
||||
}
|
||||
|
||||
BlockingInformParent("FHEM::SMAPortal::setFromBlocking", [$name, "loginState:successful", "NULL" ], 1);
|
||||
$errstate = 0;
|
||||
|
||||
} else {
|
||||
@ -1082,15 +1089,34 @@ sub _checkLogin {
|
||||
return ($state, $errstate);
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Login Status testen
|
||||
################################################################
|
||||
sub __isLoggedIn {
|
||||
my $name = shift;
|
||||
my $username = shift;
|
||||
my $loginp = shift;
|
||||
|
||||
my $sc = $loginp->header('Set-Cookie') // "";
|
||||
my ($logname) = $sc =~ /SunnyPortalLoginInfo=Username=(.*?)&/sx;
|
||||
|
||||
if($logname && $logname eq $username) {
|
||||
Log3 ($name, 3, "$name - Login into SMA-Portal successfully done with user: $logname");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Abruf Live Daten
|
||||
################################################################
|
||||
sub _getLiveData { ## no critic "not used"
|
||||
my $paref = shift;
|
||||
my $name = $paref->{name};
|
||||
my $ua = $paref->{ua}; # LWP Useragent
|
||||
my $state = $paref->{state};
|
||||
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||
my $paref = shift;
|
||||
my $name = $paref->{name};
|
||||
my $ua = $paref->{ua}; # LWP Useragent
|
||||
my $state = $paref->{state};
|
||||
my $daref = $paref->{daref}; # Referenz zum Datenarray
|
||||
|
||||
my ($reread,$retry,$errstate) = (0,0,0);
|
||||
|
||||
@ -1761,6 +1787,7 @@ sub ParseData { ## no critic
|
||||
|
||||
if($newcycle && $ac < $maxcycles) {
|
||||
delete($hash->{HELPER}{RUNNING_PID});
|
||||
delcookiefile ($hash);
|
||||
$hash->{HELPER}{GETTER} = $getp;
|
||||
$hash->{HELPER}{SETTER} = $setp;
|
||||
$hash->{HELPER}{ACTCYCLE}++;
|
||||
@ -1859,7 +1886,7 @@ sub finalCleanup {
|
||||
$hash->{HELPER}{GETTER} = "all";
|
||||
$hash->{HELPER}{SETTER} = "none";
|
||||
|
||||
delcookiefile ($hash);
|
||||
#delcookiefile ($hash);
|
||||
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user