Loxone / lxcommunicator

Communicate securily with the Loxone Miniserver via Websocket or HTTP requests
MIT License
63 stars 20 forks source link

Loxone miniserver socket connect in iOS swift #2

Closed qadirsuh closed 5 years ago

qadirsuh commented 5 years ago

I am trying to acquire tokens in iOS. I am following your code of javascript and re-writing it in iOS swift.

here is my code. and LOGs in comments

    ```
    func connectToServer2(_ user:NSString ,password:NSString, address:NSString ,command :NSString ) {        
    let urlString = NSString(format:"%@%@", address,command) as String
    let getKey2url = URL(string: urlString)

    print("getKey2 Url", String(describing: getKey2url)); // 

    Alamofire.request(getKey2url!, method: .get, parameters: nil, encoding: JSONEncoding.default)
        .downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
            print("Progress: \(progress.fractionCompleted)")
        }
        .validate { request, response, data in
            // Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
            //print("response", response);
            return .success
        }
        .responseJSON { response in
            //debugPrint(response)
            //print("JSON req", response)

            if((response.result.value) != nil) {

                let swiftyJSON = JSON(response.result.value!)

                if let jsonArray = swiftyJSON.dictionary {

                    if let code = jsonArray["LL"]!["code"].int {

                        if(code == 200){

                            print("response code", code);

                            // get key
                             self._key = jsonArray["LL"]!["value"]["key"].string!
                            // get salt from request jdev/sys/getkey2/james_user
                            self._salt = jsonArray["LL"]!["value"]["salt"].string!

                            // print("_key", self._key);
                            print("_salt", self._salt);

                            // create {pwHash}
                            // {pwHash}​ is the uppercase result of hashing the string “{password}:{salt}​” using the
                            // SHA1 algorithm.
                            let passwordWithSalt = "\(self._password):\(self.self._salt)"
                            print("passwordWithSalt",passwordWithSalt);

                            // self._pwHash = passwordWithSalt.sha1().uppercased();
                            // print("pwHash my", self._pwHash);

                            // {pwHash}
                            self._pwHash = self.SHA1.hash(passwordWithSalt)
                            print("pwHash", self._pwHash);
                            self._pwHash = self._pwHash.uppercased();
                            print("pwHash", self._pwHash);
                            //pwHash=> 84EA14899207A625419E8159F40D0AE4DCC42DE2

                            self._hash = "\(self._user):\(self._pwHash)";
                            print("hash", self._hash);

                             //                                let key = "34423946324232464630433544443343413944333044383145393732433444344438363343324435"
                            self._hash = self._hash.hmac(key: self.dataFromHexadecimalString(self._key)! as String)
                            print("hash", self._hash);
                            // c42b73d90e02fadca399fc7579ceb15bd1b6def9

                            let uuid = "a513374f-10ff-11e4-a792d242c19b9d57"
                            print("uuid",uuid)
                            let info = "Qadir-Hussain.genetech.pk"; //String("Qadir-Hussain.genetech.pk".addingPercentEncoding(withAllowedCharacters: .alphanumerics)!)
                            //String(UIDevice.current.name.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!)
                            print("info",info)
                            let permissions = "4"; // “App” permission will last for a longer period (4 weeks). the permission for the app (ID = 4).
                            let command = "jdev/sys/gettoken/\(self._hash)/\(self._user)/\(permissions)/\(uuid)/\(info)";

                            print("command", command); // jdev/sys/gettoken/20e422d29ded8fe48a876d41bce95d1617c9116c/admin/4/a513374f-10ff-11e4-a792d242c19b9d57/Qadir-Hussain.genetech.pk

                            let urlString = NSString(format:"%@%@", address, command) as String
                            let gettokenUrl = URL(string: urlString)!

                            print("gettokenUrl", String(describing: gettokenUrl));

                            // Alamofire 4
                            Alamofire.request(gettokenUrl, method: .get, parameters: nil, encoding: JSONEncoding.default)
                                .downloadProgress(queue: DispatchQueue.global(qos: .utility)) { progress in
                                    print("Progress: \(progress.fractionCompleted)")
                                }
                                .validate { request, response, data in
                                    // Custom evaluation closure now includes data (allows you to parse data to dig out error messages if necessary)
                                    print("response", response);

                                    if let string = String(bytes: data!, encoding: .utf8) {
                                        print(string)
                                    } else {
                                        print("not a valid UTF-8 sequence")
                                    }
                                    return .success
                                }
                                .responseJSON { response in
                                    //debugPrint(response)
                                    print("JSON res", response)
                                    // <html><head><title>error</title></head><body><errorcode>400</errorcode> <errordetail>Bad Request</errordetail></body></html>
                                    //JSON res FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.jsonSerializationFailed(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.}))
                            }

                        } else {
                            print("response code", code);
                        }
                    } else {
                        print("ELSE LL");
                    }

                }else{
                    print("ELSE jsonArray");
                }

                print(swiftyJSON)
            }
    }
}


Problem is with my gettoken request.
I am getting **400 => Bad Request**. I do not have any clue whats going wrong.
LxToubey commented 5 years ago

This is not an issue concerning the lxCommunicator-source - you're requesting support on your own project. However, without reviewing your source in detail, it appears to be a common mistake.

Unlike the getkey2 request, the gettoken request has to be encrypted. The Miniserver will decline requests for tokens that are not encrypted with code 400. We will update our documentation, to make this information more prominent.

qadirsuh commented 5 years ago

Thanks for response. is there any code available of iOS.

LxToubey commented 5 years ago

No, you will have to stick to JS for now.

qadirsuh commented 5 years ago

I have done it in iOS BTW. was too difficult to trasnlate the JS code and the lxcommunicator docs was very comprehensive too. Thanks anyways for JS code. this helped alot.