Navigation

    Logo
    • Register
    • Login
    • Search
    • Recent
    • Tags
    • Unread
    • Categories
    • Unreplied
    • Popular
    • GitHub
    • Docu
    • Hilfe
    1. Home
    2. Armin Junge

    NEWS

    • Neuer Blog: Fotos und Eindrücke aus Solingen

    • ioBroker@Smart Living Forum Solingen, 14.06. - Agenda added

    • ioBroker goes Matter ... Matter Adapter in Stable

    • Profile
    • Following 0
    • Followers 0
    • Topics 4
    • Posts 9
    • Best 0
    • Groups 2

    Armin Junge

    @Armin Junge

    Starter

    0
    Reputation
    9
    Profile views
    9
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Armin Junge Follow
    Developer Starter

    Latest posts made by Armin Junge

    • Adapter zum Anmelden am Webserver (web Adapter) mit Google

      Hallo zusammen,

      im Test-Bereich habe ich ja meinen Adapter 'Google Authentication' schon bekannt gemacht (siehe https://forum.iobroker.net/topic/33110/test-adapter-googleauth-0-1-x). Hier würde mich interessieren, was ihr von der Idee grundsätzlich haltet und zugleich möchte ich meine Erweiterungs- bzw. Differenzierungsidee einbringen.

      Erstmal was zum Hintergrund der Entstehung:
      Bevorzugt möchte ich per Smartphone (Android) meine Geräte steuern können. Da aber in unserem Haus nicht jeder Nutzer auf alles zugreifen soll, habe ich die Authentifizierung aktiviert und Objekte/Status entsprechend mit Berechtigungen versorgt (über Benutzergruppen). Damit ich aber nicht ständig (oder bestenfalls jeden Monat) am Smartphone Benutzer und Passwort eintippseln muss, habe ich mir diese Lösung überlegt. Mit Android ist man ja sowieso schon mit dem Google-Account angemeldet, was den Zugriff viel einfacher macht.

      Nun zu meiner Idee für die nächste Version (geplant 0.2.x):
      Mit der ersten Version habe ich den Login-Bildschirm geklont und entsprechend für den Google Login ergänzt. Was mich daran stört? Gibt es Änderungen an dem Login im web Adapter, müsste ich das nachziehen. Also müsste ich bei jeder Version des web Adapter prüfen, ob sich was geändert hat und ggf. meine Implementierung anpassen.
      Ein weiterer Nachteil ist, dass der Login dann ja nur zusätzlich mit Google funktioniert. Würde jetzt eine andere Alternative aufkommen (z.B. Facebook oder Apple), dann verliert eine der Anmeldemöglichkeiten. Entweder wird der Login-Bildschirm des einen oder des anderen Adapters angezeigt, aber keine Kombination daraus.
      Daher möchte ich den Punkt mit dem Login-Bildschirm herausschneiden. Das heißt aber, dass ein zusätzlicher Adapter entsteht und zwar, der den Login-Bildschirm ergänzt. Dieser Adapter liest den Original-Login-Bildschirm des web Adapters und fügt an geeigneten Stellen die zusätzlichen Screen-Elemente und die nötige Logik (als Javascript-Coding) ein. Für den Adapter mit der Google Anmeldung bedeutet das natürlich, dass er nichts mehr mit dem Login-Bildschirm direkt zu tun hat und implizit von dem neuen Adapter mit dem alternativen Login-Bildschirm abhängt.

      Die grundlegende Idee dahinter ist, dass man flexibel und erweiterbar ist mit den Adaptern. Vielleicht möchte ja jemand eine weitere Login-Variante implementieren (z.B. für Facebook oder Apple oder ...).

      Ich hoffe meine Ausführungen waren nicht zu verwirrend 😉 Was meint ihr denn zu dem Ganzen?

      posted in Entwicklung
      Armin Junge
      Armin Junge
    • Test Adapter googleauth 0.1.x
      Aktuelle Test Version 0.1.0
      Veröffentlichungsdatum 06.05.2020
      Github Link https://github.com/Vertumnus/ioBroker.googleauth

      Googleauth
      Erweitert den web server um die Möglichkeit sich per Google Account anzumelden. Der Login Screen wird erweitert um einen "Sign in with Google" Button.

      Wichtig

      Beim Webserver muss die Authentifizierung aktiviert sein.
      Zur ersten Anmeldung muss man Benutzernamen und Passwort angeben und die Checkbox "Erstanmeldung" anhaken, damit der ioBroker Benutzer mit dem Google Account verknüpft werden kann.

      Dies und weitere Details findet ihr im README (englisch).

      Ich freue mich auf euer Feedback 😎

      posted in Tester
      Armin Junge
      Armin Junge
    • RE: socketio Kommando getObject liefert Berechtigungsfehler

      Na super. Mit dem Rumprobieren eine Minimal-Version hinzubekommen, habe ich wohl irgendwas gemacht, dass es jetzt funktioniert. Es ist mir unbegreiflich.

      Das einzige was ich jetzt anders gemacht habe, ist den Web Adapter nochmal hochzuladen. Vielleicht wurde bei einer Aktualisierung irgendwas nicht richtig mitgenommen. Denn eigentlich hatte ich schon die aktuellste Version drauf.

      Also, das Problem scheint gelöst zu sein. Danke fürs Draufschauen @apollon77

      posted in Error/Bug
      Armin Junge
      Armin Junge
    • RE: socketio Kommando getObject liefert Berechtigungsfehler

      Ja, finde das auch total strange. Rein vom Coding ist das Phänomen nicht erklärbar für mich. Ich versuche mal eine Minimal-HTML-Datei mit JS-Code bereitzustellen, die man mit der web Instanz aufrufen kann.

      posted in Error/Bug
      Armin Junge
      Armin Junge
    • RE: socketio Kommando getObject liefert Berechtigungsfehler

      PS: Wenn ich per .emit() einen getState oder setState Aufruf mache, funktioniert es tadellos.

      posted in Error/Bug
      Armin Junge
      Armin Junge
    • RE: socketio Kommando getObject liefert Berechtigungsfehler

      Ok, hier die Benutzer + Gruppen und die Zugriffseinstellung des Status/Objekts als Screenshots:
      Benutzer.PNG

      Berechtigung Status.PNG

      Mit nachfolgendem Codeteil greife ich per socketio auf das Backend (ioBroker.web) zu. Das Attribut this._socket wird mit io() instanziert (im constructor()). Die beiden emits 'authenticate' und 'subscribeObjects' habe ich gestern noch hinzugefügt, als Versuch, ob das vielleicht das Problem beheben könnte.

      ...
         connect(){
            // on connect, try to authenticate, get user permissions and subscribe for Objects
            return new Promise(function(resolve, reject){
               this._socket.emit('authenticate', function(bIsOk, bIsSecure){
                  if(!bIsOk){
                     if(this.showError)
                        this.showError('Authentifizierung fehlgeschlagen')
                     return reject()
                  }
                  this._socket.emit('getUserPermissions', function(err, oAcl){
                     if(err){
                        if(this.showError)
                           this.showError(err)
                        return reject()
                     }
                     this._acl = oAcl
                     this._socket.emit('subscribeObjects', '*')
                     return resolve(this)
                  }.bind(this))
               }.bind(this))
            }.bind(this))
         }
         parse(){
            let elements = this._content.querySelectorAll('[bind],[bind-get],[bind-set]')
            elements.forEach(function(element) {
               let mapping = element.getAttribute('bind-map')
               let binding = element.getAttribute('bind')
               let bindingGet = element.getAttribute('bind-get') || binding
               let bindingSet = element.getAttribute('bind-set') || binding
               if(bindingGet === bindingSet){
                  this._socket.emit('getObject', bindingGet, function(err, oObject){
                     if(this.hasError(err))
                        return this.noReadAccess(element), this.noWriteAccess(element)
                     this.handleGetBinding(element, bindingGet, mapping, oObject.acl)
                     this.handleSetBinding(element, bindingSet, mapping, oObject.acl)
                  }.bind(this))
               } else {
                  if(bindingGet)
                     this._socket.emit('getObject', bindingGet, function(err, oObject){
                        if(this.hasError(err))
                           return this.noReadAccess(element)
                        this.handleGetBinding(element, bindingGet, mapping, oObject.acl)
                     }.bind(this))
                  if(bindingSet)
                     this._socket.emit('getObject', bindingSet, function(err, oObject){
                        if(this.hasError(err))
                           return this.noWriteAccess(element)
                        this.handleSetBinding(element, bindingSet, mapping, oObject.acl)
                     }.bind(this))
               }
            }, this)
            this._socket.on('stateChange', function(sId, oState){
               let elements = this._content.querySelectorAll(`[bind-get="${ sId }"],[bind="${ sId }"]`)
               elements.forEach(function(element){
                  let mapping = element.getAttribute('bind-map')
                  this.setData(element, this.mapTo(mapping, oState.val))
               }, this)
            }.bind(this))
         }
      ...
      

      Die beiden Methoden werden folgendermaßen aufgerufen:

      var app = new App()
      window.addEventListener('load', () => {
         app.binding.connect().then(binding => binding.parse())
      })
      

      Der callback bei dem emit auf getObject liefert mir dann den Fehler 'permissionError' in err und im Log des ioBroker kommt folgende Meldung:
      (17145) Permission error for user "system.user.armin"on "lgtv.0.states.on" : getState

      Es liegt auch nicht speziell an diesen speziellen Status, sondern taucht auch bei den anderen Status auf, die ich so konfiguriert habe.

      Im web Adapter habe ich die Authentifikation aktiviert und angemeldet bin ich als Armin.

      Stelle ich als Besitzer des Status Armin ein, funktioniert es. Erlaube ich beim Zugriff von Jeder auf den Status auch das Lesen, funktioniert es auch. Nur mit der Gruppe will es nicht gehen.

      posted in Error/Bug
      Armin Junge
      Armin Junge
    • socketio Kommando getObject liefert Berechtigungsfehler
      Systemdata Werte
      Hardwaresystem: Pi3
      Arbeitsspeicher: 1GB
      Festplattenart: SD-Karte
      Betriebssystem: Linux
      Node-Version: 10.15.2
      NPM-Version: 6.14.4
      Installationsart: Skript
      Image genutzt: Nein

      Folgendes Szenario
      Bentzer: Es gibt zwei User. Den admin und User B. Außerdem gibt es zwei Gruppen. Die Admingruppe und die Usergruppe (oder eine Gruppe X, egal). User B ist nur der Usergruppe zugeordnet.
      Objekte: Es gibt einen Status S. Dieser hat bei der Zugriffskontrolle den admin als Besitzer und die Usergruppe als Gruppe. Der Zugriff auf das Objekt und den Status ist für Besitzer und Gruppe auf Lesen und Schreiben eingestellt. Bei Jeder ist nur das Lesen auf das Objekt erlaubt.

      Über die socketio-Integration im Webserver (Adapter web) setze ich einen Request ab auf getObject, um die Metadaten des Objekts auszulesen. Angemeldet bin ich mit User B. Anstatt der Daten erhalte ich aber den Fehler "permissionError". Im Log des ioBroker erhalte ich zusätzlich den Eintrag: Permission error for user "B"on "S" : getState

      Dass bei getObject irgendwo ein getState aufgerufen wird, hatte ich so nicht erwartet. Man könnte das zwar umgehen, wenn man den Zugriff für Jeden zum Lesen des Status freigibt oder alternativ wenn man Benutzer B als Besitzer einträgt. Das hilft mir aber leider nicht weiter. Da mein Szenario eigentlich noch etwas komplexer ist. Ich habe zwei Benutzergruppen und mehrere User. Und das Ziel ist eigentlich, dass Benutzer bestimmter Gruppen nur auf bestimmte Status zugreifen dürfen. Was ich aber nicht per Try & Error machen möchte, sondern anhand der Metadaten ermitteln will.

      Leider bin ich der Ursache noch nicht auf die Schliche gekommen. Zumindest konnte ich aus dem Quellcode nichts rauslesen was auf den getState Aufruf hinweist. Ich sehe hier zwei Probleme. Erstens den getState Aufruf bei getObject und zweitens, dass scheinbar bei der Berechtigungsprüfung des getState Aufrufs die Gruppe ignoriert wird.

      Adapter Versionen
      js-controller: 2.2.9
      admin: 3.7.8
      web: 2.4.10
      socketio: 2.1.2

      posted in Error/Bug
      Armin Junge
      Armin Junge
    • RE: Kann man socketio um eigene Kommandos erweitern?

      Im io Objekt ist die socketio Instanz enthalten, die von iobroker.socketio/lib/socket.js erzeugt wird. Im Endeffekt steckt die Instanz von socket.io dahinter. Man könnte also darüber auf Kommandos horchen per on(...). (Was ich so aus dem Quellcode gelesen habe.)

      Zum Hintergrund: Ich wollte damit feststellen können, ob bzw. welche Berechtigung ein Benutzer auf einen State hat. Mittlerweile habe ich rausgefunden, dass man das über getObject() herausfinden kann. Das zurückgelieferte Objekt hat das Unterobjekt ACL, welches die Berechtigungsdaten enthält; Also: Besitzer, Gruppe, Berechtigungen als Zahl auf das Object und den State. Leider hatte ich in der Dokumentation (Core Concept) dazu nichts gefunden.

      Fazit: Mein ursprüngliches Problem kann ich lösen. Trotzdem wundert es mich noch, dass wohl eine Erweiterbarkeit des socketio vorgesehen ist, aber scheinbar (noch) nicht wirklich verwendet wird.

      posted in Entwicklung
      Armin Junge
      Armin Junge
    • Kann man socketio um eigene Kommandos erweitern?

      Hallo zusammen,

      ich habe jetzt einige Zeit gesucht und den Quellcode des web Adapters und des socketio Adapters durchwühlt. Beim socketio Adapter habe ich auch etwas entdeckt, was auf eine Erweiterbarkeit hinweisen dürfte (-> lib/socket.js -> Schlüsselwort für die Suche: extensions), aber ich habe keine Möglichkeit gefunden darauf zurückzugreifen. Leider wird auch beim web Adapter das io Objekt nicht an die Erweiterungen übergeben, also sehe ich da auch keine Möglichkeit mich einzuhängen.

      Vielleicht habe ich ja was übersehen. Weiß hier jemand mehr dazu?

      posted in Entwicklung
      Armin Junge
      Armin Junge
    Community
    Impressum | Datenschutz-Bestimmungen | Nutzungsbedingungen
    The ioBroker Community 2014-2023
    logo