def search_diplomas():
    """Method that search for diplomas of a student, given its cnp(student id). Firstly, it lists all the assets found
    in the blockchain, then it lists all the transactions of every asset. If the student cnp is found in any transaction
    and it was not revoked, the diploma is added to the response variable

    Args:
        stud_cnp (str): the id of the student.

    Returns:
         (html): the entity page
         (dict): response variable that contains all the valid diplomas with the corresponding asset name of the
         university that issued it.
    """
    response = dict()
    response["diplomas"] = dict()

    stud_cnp = request.args.get("stud_cnp")

    assets = MultichainCLI.list_assets()
    burn_address = MultichainCLI.get_burn_address()

    for asset in assets:
        asset_transaction = MultichainCLI.list_assets_transactions(
            asset["name"])

        for transaction in asset_transaction:
            if len(transaction["data"]) > 0:
                if stud_cnp == transaction["data"][0][0:4]:
                    if burn_address not in transaction["addresses"]:
                        response["diplomas"][transaction["data"][0]
                                             [4:]] = asset["name"]
                    else:
                        response["diplomas"].pop(transaction["data"][0][4:])

    return render_template("entity.html", response=response)
Exemple #2
0
def create_diploma_transaction():
    """
    Method that gives a diploma to a student. It gets the asset name of the university currency and sends a unit
    of that asset to the multisignature student+university. Then it creates a multisignature transfer from the
    multisignature student+university to university+high authority and signs it. It also adds the cnp(student id)+hash
    as metadata and adds the diploma to the database.

    Args:
        multisig_address (str): the multisignature of student+university.
        stud_cnp (str): the id of the student.
        diploma_hash (str): the hash of the diploma.
        diploma_name (str): the name of the diploma.

    Returns:
        (html): the university page.
        (dict): response variable that contains the students, diplomas and the hexblob of the
        transaction that the student must sign.
    """
    response = dict()

    multisig_address = request.args.get("multisig_address")
    stud_cnp = request.args.get("stud_cnp")
    diploma_hash = request.args.get("diploma_hash")
    diploma_name = request.args.get("diploma_name")

    asset_name = MultichainCLI.get_asset_name()

    error = MultichainCLI.send_asset(multisig_address, asset_name)

    print("Student cnp: {}".format(stud_cnp))

    if not error:
        time.sleep(0.5)

        asset_dest_addr = MultichainCLI.get_destination_addr_asset(asset_name)

        hexblob, errors = MultichainCLI.create_raw_trans(multisig_address, asset_dest_addr, asset_name, stud_cnp + diploma_hash)

        if errors:
            response["create_hexblob"] = "Multisignature with the high authority was not created. Please create the " \
                                         "multisignature before issuing any diploma."
        else:
            response["create_hexblob"] = "Hexblob: {}".format(hexblob["hex"])

            diploma = Diploma(hash=diploma_hash, name=diploma_name, student_cnp=stud_cnp)
            db.session.add(diploma)
            db.session.commit()

    students = Student.query.all()
    response["students"] = students_schema.dump(students).data
    diplomas = Diploma.query.all()
    response["diplomas"] = diplomas_schema.dump(diplomas).data

    return render_template("university.html", response=response)
def create_university():
    """
    Method that creates a university. It gives a node activate, send and receive permissions, creates the multisignature
    and adds the university to the database.

    Args:
        univ_address (str): the address of the university.
        target_pubkey (str): the public key of the university.
        univ_name (str): the name of the university.
        asset_name (str): the asset name of the university.

    Returns:
         (html): the high authority page
         (dict): response variable that contains all the universities and whether there were errors at creation.
    """
    response = dict()

    univ_address = request.args.get("univ_address")

    errors = MultichainCLI.create_university(univ_address)
    response['create_errors'] = "Could not create university" if errors else ""

    target_pubkey = request.args.get("target_pubkey").replace(" ", "")
    univ_name = request.args.get("univ_name")

    multisig_addr, errors = MultichainCLI.create_multisigaddress(
        session["pubkey"], target_pubkey)

    print(multisig_addr)

    if errors:
        response[
            "create_errors"] = "Could not create multisignature address. The provided public key is not valid."
    else:
        asset_name = request.args.get("asset_name")
        univ_address = MultichainCLI.get_multisig_second_address(
            session["address"])
        errors = MultichainCLI.issue_asset_univ(univ_address, asset_name,
                                                multisig_addr)

        if errors:
            response["create_errors"] = "Multisig was already created"
        else:
            db.session.add(
                University(name=univ_name,
                           address=univ_address,
                           pubkey=target_pubkey))
            db.session.commit()
            universities = University.query.all()
            response["universities"] = universities_schema.dump(
                universities).data

    return render_template("high_authority.html", response=response)
def disconnect():
    """
     Method that disconnects a user from the application. It stops the blockchain.

    Returns:
         (html): the index page.
    """

    MultichainCLI.disconeect()
    time.sleep(1)

    return render_template("index.html", response=dict())
def revoke_university():
    """
        Method that revokes a university. It revokes a node activate, send and receive permissions and deletes it from
        the database.

        Args:
            univ_address (str): the address of the university.

        Returns:
            (html): the high authority page
            (dict): response variable that contains all the universities and whether there were errors.
    """

    response = dict()

    univ_address = request.args.get("univ_address")

    errors = MultichainCLI.revoke_university(univ_address)
    response['revoke_errors'] = "Could not revoke university" if errors else ""

    # carefull here! SQL injection possibility - must patch.
    db.session.execute(
        "delete from university where address = '{}'".format(univ_address))
    db.session.commit()
    universities = University.query.all()
    response["universities"] = universities_schema.dump(universities).data

    return render_template("high_authority.html", response=response)
Exemple #6
0
def revoke_student():
    """
    Method that revokes a student. It revokes send and receive permissions from a node and deletes the node to the
    database.

    Args:
        student address (str): the address of the student.

    Returns:
         (html): university page.
         (dict): response variable that contains all students and diplomas.
    """
    response = dict()

    stud_address = request.args.get("stud_address")

    errors = MultichainCLI.revoke_stud(stud_address)
    response['revoke_errors'] = "Could not revoke student" if errors else ""

    # !SQL injection possibility - must patch.
    db.session.execute("delete from student where address = '{}'".format(stud_address))
    db.session.commit()

    students = Student.query.all()
    response["students"] = students_schema.dump(students).data
    diplomas = Diploma.query.all()
    response["diplomas"] = diplomas_schema.dump(diplomas).data

    return render_template("university.html", response=response)
def sign_transaction():
    """
    Method that sign a multisignature transaction blob and send the transaction to the destination.

    Args:
        transaction_blob (str): the transaction encoded in a hex blob.

    Returns:
         (html): student/high authority page, depending on node ranks.
         (dict): response variable that contains all the universities if the rank of the node is high authority.
    """
    response = dict()
    transaction_blob = request.args.get("transaction_blob")

    _, errors = MultichainCLI.sign_and_send_transaction(transaction_blob)

    if session["rank"] == "student":
        if errors:
            response["sign_errors"] = "Could not sign the diploma transaction. You must create the multisignature with" \
                                      " the university first."

        return render_template("student.html", response=response)
    if session["rank"] == "high_authority":
        universities = University.query.all()
        response["universities"] = universities_schema.dump(universities).data

        return render_template("high_authority.html", response=response)
Exemple #8
0
def create_student():
    """
    Method that creates a student. It gives send and receive permissions to a node, creates a multisignature with the
    node and adds the node to the database.

    Args:
        student address (str): the address of the student.
        target_pubkey (str): the public key of the student.
        stud_name (str): the name of the student.
        stud_cnp (str): the id of the student.

    Returns:
         (html): university page
         (dict): response variable that contains all students and diplomas.
    """
    response = dict()

    stud_address = request.args.get("stud_address")
    errors = MultichainCLI.create_stud(stud_address)
    response['create_errors'] = "Could not create student" if errors else ""

    target_pubkey = request.args.get("target_pubkey").replace(" ", "")
    stud_name = request.args.get("stud_name")
    stud_cnp = request.args.get("stud_cnp")

    if len(stud_cnp) != 4:
        response["create_errors"] = "CNP is invalid. It must contain 4 digits"
    else:
        multisig_addr, errors = MultichainCLI.create_multisigaddress(target_pubkey, session["pubkey"])

        if errors:
            response["create_errors"] = "Could not create multisignature address. The provided public key is not valid."
        else:

            MultichainCLI.create_stud(multisig_addr)

            db.session.add(Student(cnp=stud_cnp, name=stud_name, address=stud_address,
                                   pubkey=target_pubkey, multisig=multisig_addr))
            db.session.commit()

    students = Student.query.all()
    response["students"] = students_schema.dump(students).data
    diplomas = Diploma.query.all()
    response["diplomas"] = diplomas_schema.dump(diplomas).data

    return render_template("university.html", response=response)
Exemple #9
0
def create_univha_multisig():
    response = dict()

    target_pubkey = request.args.get("target_pubkey").replace(" ", "")

    multisig_addr, errors = MultichainCLI.create_multisigaddress(target_pubkey, session["pubkey"])

    if errors:
        response["multisig_errors"] = "Could not create multisignature address. The provided public key is not valid."
    else:
        MultichainCLI.grand_send_recieve(multisig_addr)

    students = Student.query.all()
    response["students"] = students_schema.dump(students).data
    diplomas = Diploma.query.all()
    response["diplomas"] = diplomas_schema.dump(diplomas).data

    return render_template("university.html", response=response)
def verify_diploma():
    """
    Method that verifies if a diploma is valid. It lists all the transaction of the given asset and checks whether the
    cnp+diploma hash is found in the university+high authority multisignature address. It also checks if the
    diploma was revoked, the cnp+diploma was transferred to burn address.

    Args:
        diploma_hash (str): the hash of the diploma.
        asset_name (str): the name of the asset of the university.
        stud_cnp (str): the student id.

    Returns:
         (html): the entity page.
         (dict): response variable that contains a message that says whether the diploma is valid.
    """
    response = dict()

    diploma_hash = request.args.get("diploma_hash")
    asset_name = request.args.get("asset_name")
    stud_cnp = request.args.get("stud_cnp")

    asset_transactions = MultichainCLI.list_assets_transactions(asset_name)
    burn_address = MultichainCLI.get_burn_address()

    diploma_hash_exists = False
    diploma_revoked = False
    for transaction in asset_transactions:
        if len(transaction["data"]) > 0:
            if stud_cnp + diploma_hash == transaction["data"][0]:
                if burn_address not in transaction["addresses"]:
                    diploma_hash_exists = True
                else:
                    diploma_revoked = True

    if diploma_hash_exists and not diploma_revoked:
        response["valid"] = "Diploma is valid"
    else:
        response["valid"] = "Diploma is not valid"

    return render_template("entity.html", response=response)
Exemple #11
0
def revoke_diploma_transaction():
    """
        Method that revokes a diploma from a student. It creates a multisignature transfer from the multisignature
        between univ+high authority to the burn address.

        Args:
            stud_cnp (str): the id of the student.
            diploma_hash (str): the hash of the diploma.

        Returns:
            (html): the university page.
            (dict): response variable that contains the students, diplomas and the hexblob of the
            transaction that the high authority must sign.
        """

    response = dict()

    stud_cnp = request.args.get("stud_cnp")

    diploma_hash = request.args.get("diploma_hash")

    asset_name = MultichainCLI.get_asset_name()
    asset_dest_addr = MultichainCLI.get_destination_addr_asset(asset_name)

    burn_address = MultichainCLI.get_burn_address()

    hexblob, _ = MultichainCLI.create_raw_trans(asset_dest_addr, burn_address, asset_name, stud_cnp + diploma_hash)

    response["revoke_hexblob"] = "Hexblob: {}".format(hexblob["hex"])

    db.session.execute("delete from diploma where hash = '{}'".format(diploma_hash))
    db.session.commit()

    students = Student.query.all()
    response["students"] = students_schema.dump(students).data
    diplomas = Diploma.query.all()
    response["diplomas"] = diplomas_schema.dump(diplomas).data

    return render_template("university.html", response=response)
Exemple #12
0
def create_studuniv_multisig():
    """
    Method that creates the multisignature with the university.

    Args:
       target_pubkey (str): the public key of the university.

    Returns:
         (html): student page.
         (dict): response variable that contains whether there was an error of creation of the multisignature.
    """
    response = dict()

    target_pubkey = request.args.get("target_pubkey").replace(" ", "")

    _, errors = MultichainCLI.create_multisigaddress(session["pubkey"],
                                                     target_pubkey)
    response["multisig_errors"] = "Could not create multisignature address. The provided public key is not valid." \
                                  if errors else ""

    return render_template("student.html", response=response)
def connect():
    """
    Method that connects a user to the application. It stores the address, ip+port, public key and rank(student,
    university, high authority) in the session variable.

    Args:
        scholarium_address (str): the address(ip+port) of the node.

    Returns:
        (html): the page of student, university or high authority, depending on the rank of the node.
        (dict): response variable that contains students and diplomas for university, and universities for high
        authorities.
    """
    response = dict()

    scholarium_address = request.args.get("scholarium_address")

    MultichainCLI.connect(scholarium_address)

    session["address"] = MultichainCLI.get_address()

    session['node_address'] = MultichainCLI.get_node_address()

    session["pubkey"] = MultichainCLI.get_node_public_key()

    session["rank"] = MultichainCLI.get_node_rank(session["address"])

    if session["rank"] == "university":
        students = Student.query.all()
        response["students"] = students_schema.dump(students).data
        diplomas = Diploma.query.all()
        response["diplomas"] = diplomas_schema.dump(diplomas).data

        return render_template("university.html", response=response)
    if session["rank"] == "high_authority":
        universities = University.query.all()
        response["universities"] = universities_schema.dump(universities).data

        return render_template("high_authority.html", response=response)
    if session["rank"] == "student":
        return render_template("student.html", response=response)
    if session["rank"] == "entity":
        return render_template("entity.html", response=response)