def did_auth(self, host, user_did, app_did):
        # sign_in
        doc = lib.DIDStore_LoadDID(app_did.store, app_did.did)
        doc_str = ffi.string(lib.DIDDocument_ToJson(doc, True)).decode()
        logging.getLogger("test_auth_common").debug(f"\ndoc_str: {doc_str}")
        doc = json.loads(doc_str)

        param = {"document": doc}
        r = requests.post(host + '/api/v1/did/sign_in',
                          json=param,
                          headers=self.json_header())
        self.assert200(r.status_code)
        rt = r.json()

        jwt = rt["challenge"]
        # print(jwt)
        jws = lib.DefaultJWSParser_Parse(jwt.encode())
        # if not jws:
        #     print(ffi.string(lib.DIDError_GetLastErrorMessage()).decode())
        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        self.assertEqual(aud, app_did.get_did_string())
        nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
        hive_did = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)

        # auth
        vc = user_did.issue_auth(app_did)
        vp_json = app_did.create_presentation(vc, nonce, hive_did)
        auth_token = app_did.create_vp_token(vp_json, "DIDAuthResponse",
                                             hive_did, 60)
        # print(auth_token)
        logging.getLogger("test_auth_common").debug(
            f"\nauth_token: {auth_token}")
        param = {
            "jwt": auth_token,
        }
        r = requests.post(host + '/api/v1/did/auth',
                          json=param,
                          headers=self.json_header())
        self.assert200(r.status_code)
        rt = r.json()

        token = rt["access_token"]
        jws = lib.DefaultJWSParser_Parse(token.encode())
        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        self.assertEqual(aud, app_did.get_did_string())
        issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        # print(token)
        logging.getLogger("test_auth_common").debug(f"\ntoken: {token}")
        app_did.set_access_token(token)

        # auth_check
        # token = test_common.get_auth_token()
        r = requests.post(host + '/api/v1/did/check_token',
                          json=param,
                          headers=self.auth_header(token))
        self.assert200(r.status_code)
        return token, hive_did
Exemplo n.º 2
0
    def get_backup_auth_from_node(self, base_url, auth_token, hive_did):
        rt, status_code, err = self.post(base_url + '/api/v1/did/backup_auth',
                                         {"jwt": auth_token})
        if err != None:
            return None, "Post backup_auth error: " + err

        token = rt["backup_token"]
        if token is None:
            return None, "Token is none."

        jws = lib.DefaultJWSParser_Parse(token.encode())
        if not jws:
            return None, "Backup token DefaultJWSParser_Parse error: " + ffi.string(
                lib.DIDError_GetLastErrorMessage()).decode()

        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if aud != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, "Audience is error."

        issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if issuer is None:
            return None, "Issuer is none."

        if issuer != hive_did:
            return None, "Issuer is error."

        return token, None
Exemplo n.º 3
0
    def get_info_from_token(self, token):
        if token is None:
            return None, "Then token is none!"

        token_splits = token.split(".")
        if token_splits is None:
            return None, "Then token is invalid!"

        if (len(token_splits) != 3) or token_splits[2] == "":
            return None, "Then token is invalid!"

        jws = lib.DefaultJWSParser_Parse(token.encode())
        if not jws:
            return None, self.get_error_message("JWS parser")

        issuer = lib.JWT_GetIssuer(jws)
        if not issuer:
            lib.JWT_Destroy(jws)
            return None, self.get_error_message("JWT getIssuer")

        issuer = ffi.string(issuer).decode()
        if issuer != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, "Then issuer is invalid!"

        expired = lib.JWT_GetExpiration(jws)
        now = (int)(datetime.now().timestamp())
        if now > expired:
            lib.JWT_Destroy(jws)
            return None, "Then token is expired!"

        props = lib.JWT_GetClaim(jws, "props".encode())
        if not props:
            lib.JWT_Destroy(jws)
            return None, "Then props is none!"

        props_str = ffi.string(props).decode()
        props_json = json.loads(props_str)

        app_instance_did = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if not app_instance_did:
            lib.JWT_Destroy(jws)
            return None, "Then app instance id is none!"

        props_json[APP_INSTANCE_DID] = app_instance_did

        lib.JWT_Destroy(jws)
        # print(props_json)

        return props_json, None
Exemplo n.º 4
0
    def get_auth_token_by_sign_in(self, base_url, vc_str, subject):
        vc = lib.Credential_FromJson(vc_str.encode(), ffi.NULL)
        if not vc:
            return None, None, "The credential string is error, unable to rebuild to a credential object."

        #sign_in
        doc = lib.DIDStore_LoadDID(self.store, self.did)
        doc_str = ffi.string(lib.DIDDocument_ToJson(doc, True)).decode()
        doc = json.loads(doc_str)

        rt, status_code, err = self.post(base_url + '/api/v1/did/sign_in',
                                         {"document": doc})

        if err != None:
            return None, None, "Post sign_in error: " + err

        jwt = rt["challenge"]
        if jwt is None:
            return None, None, "Challenge is none."

        # print(jwt)
        jws = lib.DefaultJWSParser_Parse(jwt.encode())
        if not jws:
            return None, None, "Challenge DefaultJWSParser_Parse error: " + ffi.string(
                lib.DIDError_GetLastErrorMessage()).decode()

        aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
        if aud != self.get_did_string():
            lib.JWT_Destroy(jws)
            return None, None, "Audience is error."

        nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
        if nonce is None:
            lib.JWT_Destroy(jws)
            return None, None, "Nonce is none."

        hive_did = ffi.string(lib.JWT_GetIssuer(jws)).decode()
        lib.JWT_Destroy(jws)
        if hive_did is None:
            return None, None, "Issuer is none."

        #auth_token
        vp_json = self.create_presentation(vc, nonce, hive_did)
        if vp_json is None:
            return None, None, "create_presentation error."
        auth_token = self.create_vp_token(vp_json, subject, hive_did,
                                          hive_setting.AUTH_CHALLENGE_EXPIRED)
        if auth_token is None:
            return None, None, "create_vp_token error."
        return auth_token, hive_did, None
Exemplo n.º 5
0
    def __get_auth_token_info(self, props):
        # get jwt
        body = request.get_json(force=True, silent=True)
        if body is None:
            return None, "The parameter is not application/json"
        jwt = body.get('jwt', None)

        if jwt is None:
            return None, "The jwt is none."

        # check jwt token
        jws = lib.DefaultJWSParser_Parse(jwt.encode())
        if not jws:
            return None, self.get_error_message("JWS parser")

        vp_str = lib.JWT_GetClaimAsJson(jws, "presentation".encode())
        if not vp_str:
            lib.JWT_Destroy(jws)
            return None, "The jwt's presentation is none."

        vp = lib.Presentation_FromJson(vp_str)
        if not vp:
            lib.JWT_Destroy(jws)
            return None, "The presentation string is error, unable to rebuild to a presentation object."

        vp_json = json.loads(ffi.string(vp_str).decode())
        lib.JWT_Destroy(jws)

        # check vp
        if lib.Presentation_IsValid(vp) != 1:
            return None, self.get_error_message("Presentation isValid")
        # print(ffi.string(vp_str).decode())

        # check nonce
        nonce = lib.Presentation_GetNonce(vp)
        if not nonce:
            return None, "The nonce is none."
        nonce = ffi.string(nonce).decode()
        if nonce is None:
            return None, "The nonce is isn't valid."

        # check did:nonce from db
        info = get_did_info_by_nonce(nonce)
        if info is None:
            return None, "The nonce is error."

        # check realm
        realm = lib.Presentation_GetRealm(vp)
        if not realm:
            return None, "The realm is none."
        realm = ffi.string(realm).decode()
        if realm is None:
            return None, "The realm is isn't valid."

        if realm != self.get_did_string():
            return None, "The realm is error."

        # check vc
        count = lib.Presentation_GetCredentialCount(vp)
        if count < 1:
            return None, "The credential count is error."

        if not "verifiableCredential" in vp_json:
            return None, "The credential isn't exist."

        vcs_json = vp_json["verifiableCredential"]
        if not isinstance(vcs_json, list):
            return None, "The verifiableCredential isn't valid"

        vc_json = vcs_json[0]
        if vc_json is None:
            return None, "The credential isn't exist"

        vc_str = json.dumps(vc_json)

        credential_info, err = self.get_credential_info(vc_str, props)
        if not credential_info is None:
            if credential_info["id"] != info[APP_INSTANCE_DID]:
                return None, "The app instance did is error."
            credential_info["nonce"] = nonce
            if info[DID_INFO_NONCE_EXPIRED] < int(datetime.now().timestamp()):
                return None, "The nonce is expired"

        return credential_info, err
def test_auth_common(self, user_did, app_did):
    # sign_in
    doc = lib.DIDStore_LoadDID(app_did.store, app_did.did)
    doc_str = ffi.string(lib.DIDDocument_ToJson(doc, True)).decode()
    logging.getLogger("test_auth_common").debug(f"\ndoc_str: {doc_str}")
    doc = json.loads(doc_str)
    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/sign_in',
                              data=json.dumps({
                                  "document": doc,
                              }),
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")
    jwt = rt["challenge"]
    # print(jwt)
    jws = lib.DefaultJWSParser_Parse(jwt.encode())
    # if not jws:
    #     print(ffi.string(lib.DIDError_GetMessage()).decode())
    aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
    self.assertEqual(aud, app_did.get_did_string())
    nonce = ffi.string(lib.JWT_GetClaim(jws, "nonce".encode())).decode()
    hive_did = ffi.string(lib.JWT_GetIssuer(jws)).decode()
    lib.JWT_Destroy(jws)

    # auth
    vc = user_did.issue_auth(app_did)
    vp_json = app_did.create_presentation(vc, nonce, hive_did)
    auth_token = app_did.create_vp_token(vp_json, "DIDAuthResponse", hive_did,
                                         60)
    # print(auth_token)
    logging.getLogger("test_auth_common").debug(f"\nauth_token: {auth_token}")

    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/auth',
                              data=json.dumps({
                                  "jwt": auth_token,
                              }),
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")

    token = rt["access_token"]
    jws = lib.DefaultJWSParser_Parse(token.encode())
    aud = ffi.string(lib.JWT_GetAudience(jws)).decode()
    self.assertEqual(aud, app_did.get_did_string())
    issuer = ffi.string(lib.JWT_GetIssuer(jws)).decode()
    lib.JWT_Destroy(jws)
    # print(token)
    logging.getLogger("test_auth_common").debug(f"\ntoken: {token}")
    app_did.set_access_token(token)

    # auth_check
    # token = test_common.get_auth_token()
    self.json_header = [
        ("Authorization", "token " + token),
        self.content_type,
    ]
    rt, s = self.parse_response(
        self.test_client.post('/api/v1/did/check_token',
                              headers=self.json_header))
    self.assert200(s)
    self.assertEqual(rt["_status"], "OK")
    return token, hive_did