mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
minor fix (#1704)
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# Server-Test
|
||||
|
||||
```
|
||||
$ pip install -r requirements.txt
|
||||
$ cd bcfserver/
|
||||
$ python
|
||||
>>> from run import db
|
||||
>>> db.create_all()
|
||||
$ export FLASK_APP=run.py
|
||||
$ flask run
|
||||
```
|
||||
|
||||
Go to [http://localhost:5000](http://localhost:5000) to see the server
|
||||
|
||||
# Register the user
|
||||
|
||||
1. Go to http://localhost:5000/register to register the user
|
||||
2. Create the client
|
||||
3. For grant type enter authorization_code
|
||||
4. For response_type enter code secret
|
||||
5. Enter the scope and create the client
|
||||
|
||||
### You will be redirected to the page with the details of your client id and secret
|
||||
|
||||
# Foundation API
|
||||
|
||||
- Set the Base URL will be `http://127.0.0.1:5000/`
|
||||
@@ -0,0 +1,444 @@
|
||||
{
|
||||
"Projects":[{
|
||||
"project_id": "F445F4F2-4D02-4B2A-B612-5E456BEF9137",
|
||||
"name": "Example project 1",
|
||||
"authorization": {
|
||||
"project_actions": [
|
||||
"createTopic",
|
||||
"createDocument"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"project_id": "A233FBB2-3A3B-EFF4-C123-DE22ABC8414",
|
||||
"name": "Example project 2",
|
||||
"authorization": {
|
||||
"project_actions": []
|
||||
}
|
||||
}],
|
||||
"Extensions":[{
|
||||
"topic_type": [
|
||||
"Information",
|
||||
"Error"
|
||||
],
|
||||
"topic_status": [
|
||||
"Open",
|
||||
"Closed",
|
||||
"ReOpened"
|
||||
],
|
||||
"topic_label": [
|
||||
"Architecture",
|
||||
"Structural",
|
||||
"MEP"
|
||||
],
|
||||
"snippet_type": [
|
||||
".ifc",
|
||||
".csv"
|
||||
],
|
||||
"priority": [
|
||||
"Low",
|
||||
"Medium",
|
||||
"High"
|
||||
],
|
||||
"users": [
|
||||
"Architect@example.com",
|
||||
"BIM-Manager@example.com",
|
||||
"bob_heater@example.com"
|
||||
],
|
||||
"stage": [
|
||||
"Preliminary Planning End",
|
||||
"Construction Start",
|
||||
"Construction End"
|
||||
],
|
||||
"project_actions": [
|
||||
"update",
|
||||
"createTopic",
|
||||
"createDocument"
|
||||
],
|
||||
"topic_actions": [
|
||||
"update",
|
||||
"updateBimSnippet",
|
||||
"updateRelatedTopics",
|
||||
"updateDocumentReferences",
|
||||
"updateFiles",
|
||||
"createComment",
|
||||
"createViewpoint"
|
||||
],
|
||||
"comment_actions": [
|
||||
"update"
|
||||
]
|
||||
}],
|
||||
"Topics": [{
|
||||
"guid": "A245F4F2-2C01-B43B-B612-5E456BEF8116",
|
||||
"server_assigned_id": "ISSUE-00001",
|
||||
"creation_author": "Architect@example.com",
|
||||
"title": "Example topic 1",
|
||||
"labels": [
|
||||
"Architecture",
|
||||
"Structural"
|
||||
],
|
||||
"creation_date": "2013-10-21T17:34:22.409Z"
|
||||
}, {
|
||||
"guid": "A211FCC2-3A3B-EAA4-C321-DE22ABC8414",
|
||||
"server_assigned_id": "ISSUE-00078",
|
||||
"creation_author": "Architect@example.com",
|
||||
"title": "Example topic 2",
|
||||
"labels": [
|
||||
"Architecture",
|
||||
"Heating",
|
||||
"Electrical"
|
||||
],
|
||||
"creation_date": "2014-11-19T14:24:11.316Z"
|
||||
},
|
||||
{
|
||||
"guid": "B345F4F2-3A04-B43B-A713-5E456BEF8228",
|
||||
"server_assigned_id": "ISSUE-00549",
|
||||
"creation_author": "Architect@example.com",
|
||||
"creation_date": "2016-08-01T17:34:22.409Z",
|
||||
"topic_type": "Clash",
|
||||
"topic_status": "open",
|
||||
"title": "Example topic 3",
|
||||
"priority": "high",
|
||||
"labels": [
|
||||
"Architecture",
|
||||
"Heating"
|
||||
],
|
||||
"assigned_to": "harry.muster@example.com",
|
||||
"bim_snippet": {
|
||||
"snippet_type": "clash",
|
||||
"is_external": true,
|
||||
"reference": "https://example.com/bcf/1.0/ADFE23AA11BCFF444122BB",
|
||||
"reference_schema": "https://example.com/bcf/1.0/clash.xsd"
|
||||
},
|
||||
"authorization": {
|
||||
"topic_actions": [
|
||||
"createComment",
|
||||
"createViewpoint"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"Files":[{
|
||||
"display_information": [{
|
||||
"field_display_name": "Model Name",
|
||||
"field_value": "ARCH-Z100-051"
|
||||
}, {
|
||||
"field_display_name": "Revision Date",
|
||||
"field_value": "May 3 2020"
|
||||
}],
|
||||
"file": {
|
||||
"ifc_project": "0J$yPqHBD12v72y4qF6XcD",
|
||||
"file_name": "OfficeBuilding_Architecture_0001.ifc",
|
||||
"reference": "https://example.com/files/0J$yPqHBD12v72y4qF6XcD_0001.ifc"
|
||||
}
|
||||
}, {
|
||||
"display_information": [{
|
||||
"field_display_name": "Model Name",
|
||||
"field_value": "MEP-Z100-015"
|
||||
}, {
|
||||
"field_display_name": "Revision Date",
|
||||
"field_value": "Apr 30 2020"
|
||||
}],
|
||||
"file": {
|
||||
"ifc_project": "3hwBHP91jBRwPsmyf$3Hea",
|
||||
"file_name": "OfficeBuilding_Heating_0003.ifc",
|
||||
"reference": "cf37bae6-0900-46be-b37f-b34754fe0b4a"
|
||||
}
|
||||
}],
|
||||
"Comments":[
|
||||
{
|
||||
"guid": "C4215F4D-AC45-A43A-D615-AA456BEF832B",
|
||||
"date": "2016-08-01T12:34:22.409Z",
|
||||
"author": "max.muster@example.com",
|
||||
"comment": "Clash found",
|
||||
"topic_guid": "B345F4F2-3A04-B43B-A713-5E456BEF8228",
|
||||
"authorization": {
|
||||
"comment_actions": [
|
||||
"update"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"guid": "A333FCA8-1A31-CAAC-A321-BB33ABC8414",
|
||||
"date": "2016-08-01T14:24:11.316Z",
|
||||
"author": "bob.heater@example.com",
|
||||
"comment": "will rework the heating model",
|
||||
"topic_guid": "B345F4F2-3A04-B43B-A713-5E456BEF8228"
|
||||
}
|
||||
],
|
||||
"RelatedTopics":[{
|
||||
"related_topic_guid": "db49df2b-0e42-473b-a3ee-f7b785d783c4"
|
||||
}, {
|
||||
"related_topic_guid": "6963a846-54d1-4050-954d-607cd5e48aa3"
|
||||
}],
|
||||
"Viewpoints":[{
|
||||
"guid": "b24a82e9-f67b-43b8-bda0-4946abf39624",
|
||||
"perspective_camera": {
|
||||
"camera_view_point": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"camera_direction": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 2.0
|
||||
},
|
||||
"camera_up_vector": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"field_of_view": 90.0,
|
||||
"aspect_ratio": 1.33
|
||||
},
|
||||
"lines": [{
|
||||
"start_point": {
|
||||
"x": 2.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"end_point": {
|
||||
"x": 0.0,
|
||||
"y": 1.0,
|
||||
"z": 0.7
|
||||
}
|
||||
}],
|
||||
"clipping_planes": [{
|
||||
"location": {
|
||||
"x": 0.7,
|
||||
"y": 0.3,
|
||||
"z": -0.2
|
||||
},
|
||||
"direction": {
|
||||
"x": 1.0,
|
||||
"y": 0.4,
|
||||
"z": 0.1
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
"guid": "a11a82e7-e66c-34b4-ada1-5846abf39133",
|
||||
"perspective_camera": {
|
||||
"camera_view_point": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
},
|
||||
"camera_direction": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 2.0
|
||||
},
|
||||
"camera_up_vector": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"field_of_view": 90.0,
|
||||
"aspect_ratio": 1.33
|
||||
},
|
||||
"lines": [{
|
||||
"start_point": {
|
||||
"x": 1.0,
|
||||
"y": 1.0,
|
||||
"z": 1.0
|
||||
},
|
||||
"end_point": {
|
||||
"x": 0.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}],
|
||||
"clipping_planes": [{
|
||||
"location": {
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 0.5
|
||||
},
|
||||
"direction": {
|
||||
"x": 1.0,
|
||||
"y": 0.0,
|
||||
"z": 0.0
|
||||
}
|
||||
}],
|
||||
"coloring": [
|
||||
{
|
||||
"color": "#ff0000",
|
||||
"components": [
|
||||
{
|
||||
"ifc_guid": "2MF28NhmDBiRVyFakgdbCT",
|
||||
"originating_system": "Example CAD Application",
|
||||
"authoring_tool_id": "EXCAD/v1.0"
|
||||
},
|
||||
{
|
||||
"ifc_guid": "3$cshxZO9AJBebsni$z9Yk"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"visibility": {
|
||||
"default_visibility": true,
|
||||
"exceptions": [
|
||||
{
|
||||
"ifc_guid": "2MF28NhmDBiRVyFakgdbCT",
|
||||
"originating_system": "Example CAD Application",
|
||||
"authoring_tool_id": "EXCAD/v1.0"
|
||||
},
|
||||
{
|
||||
"ifc_guid": "3$cshxZO9AJBebsni$z9Yk"
|
||||
}
|
||||
],
|
||||
"view_setup_hints": {
|
||||
"spaces_visible": true,
|
||||
"space_boundaries_visible": false,
|
||||
"openings_visible": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"guid": "a11a82e7-e66c-34b4-ada1-5846abf39133",
|
||||
"index": 10,
|
||||
"perspective_camera": {
|
||||
"camera_view_point": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"camera_direction": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 2
|
||||
},
|
||||
"camera_up_vector": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 1
|
||||
},
|
||||
"field_of_view": 90,
|
||||
"aspect_ratio": 1.33
|
||||
},
|
||||
"lines": [
|
||||
{
|
||||
"start_point": {
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"end_point": {
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"clipping_planes": [
|
||||
{
|
||||
"location": {
|
||||
"x": 0.5,
|
||||
"y": 0.5,
|
||||
"z": 0.5
|
||||
},
|
||||
"direction": {
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
}
|
||||
}
|
||||
],
|
||||
"bitmaps": [
|
||||
{
|
||||
"guid": "20c1cb56-315f-4a0a-922d-ed7a4a8edf55",
|
||||
"bitmap_type": "jpg",
|
||||
"location": {
|
||||
"x": 10,
|
||||
"y": -10,
|
||||
"z": 7
|
||||
},
|
||||
"normal": {
|
||||
"x": -1,
|
||||
"y": 1.25,
|
||||
"z": 0
|
||||
},
|
||||
"up": {
|
||||
"x": -5.4,
|
||||
"y": -4.3,
|
||||
"z": 1
|
||||
},
|
||||
"height": 1666
|
||||
}
|
||||
],
|
||||
"snapshot": {
|
||||
"snapshot_type": "png"
|
||||
},
|
||||
"selection": [
|
||||
{
|
||||
"ifc_guid": "2MF28NhmDBiRVyFakgdbCT",
|
||||
"originating_system": "Example CAD Application",
|
||||
"authoring_tool_id": "EXCAD/v1.0"
|
||||
},
|
||||
{
|
||||
"ifc_guid": "3$cshxZO9AJBebsni$z9Yk"
|
||||
}
|
||||
]
|
||||
}],
|
||||
"DocumentReferences":[{
|
||||
"guid": "212ab37a-6122-448e-86fc-86503183b520",
|
||||
"url": "http://example.com/files/LegalRequirements.pdf",
|
||||
"description": "The legal requirements for buildings."
|
||||
}, {
|
||||
"guid": "6cbfe31d-95c3-4f4d-92a6-420c23698721",
|
||||
"document_guid": "472ab37a-6122-448e-86fc-86503183b520",
|
||||
"description": "The building owners global design parameters for buildings."
|
||||
}],
|
||||
"Documents":[{
|
||||
"guid": "472ab37a-6122-448e-86fc-86503183b520",
|
||||
"filename": "LegalRequirements.pdf"
|
||||
}, {
|
||||
"guid": "6cbfe31d-95c3-4f4d-92a6-420c23698721",
|
||||
"filename": "DesignParameters.pdf"
|
||||
}],
|
||||
"Events": [{
|
||||
"topic_guid": "A211FCC2-3A3B-EAA4-C321-DE22ABC8414",
|
||||
"date": "2014-11-19T14:24:11.316Z",
|
||||
"author": "Architect@example.com",
|
||||
"events": [
|
||||
{
|
||||
"type": "status_updated",
|
||||
"value": "Closed"
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"topic_guid": "A245F4F2-2C01-B43B-B612-5E456BEF8116",
|
||||
"date": "2013-10-21T17:34:22.409Z",
|
||||
"author": "Architect@example.com",
|
||||
"events": [
|
||||
{
|
||||
"type": "type_updated",
|
||||
"value": "Warning"
|
||||
}
|
||||
]
|
||||
}],
|
||||
"EventComments":[{
|
||||
"comment_guid": "C4215F4D-AC45-A43A-D615-AA456BEF832B",
|
||||
"topic_guid": "A211FCC2-3A3B-EAA4-C321-DE22ABC8414",
|
||||
"date": "2014-11-19T14:24:11.316Z",
|
||||
"author": "Architect@example.com",
|
||||
"events": [
|
||||
{
|
||||
"type": "comment_created",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}, {
|
||||
"comment_guid": "C4215F4D-AC45-A43A-D615-AA456BEF832B",
|
||||
"topic_guid": "A245F4F2-2C01-B43B-B612-5E456BEF8116",
|
||||
"date": "2013-10-21T17:34:22.409Z",
|
||||
"author": "Architect@example.com",
|
||||
"events": [
|
||||
{
|
||||
"type": "viewpoint_updated",
|
||||
"value": "b24a82e9-f67b-43b8-bda0-4946abf39624"
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,631 @@
|
||||
from flask import jsonify, url_for, redirect, render_template, request, session, send_file
|
||||
from flask_login import login_user, logout_user, login_required, current_user
|
||||
from flask.blueprints import Blueprint
|
||||
from foundation.models import User, OAuth2AuthorizationCode, OAuth2Token, OAuth2Client
|
||||
from run import app, db
|
||||
import json
|
||||
import os
|
||||
from flask_expects_json import expects_json
|
||||
|
||||
bcf = Blueprint("bcf", __name__, template_folder="templates", url_prefix="/bcf/3.0")
|
||||
my_absolute_dirpath = os.path.abspath(os.path.dirname(__file__))
|
||||
data = open(
|
||||
f"{my_absolute_dirpath}/project.json",
|
||||
)
|
||||
jdata = json.load(data)
|
||||
schema_path = os.path.join(my_absolute_dirpath, "schemas")
|
||||
|
||||
|
||||
def validate_client(request):
|
||||
Headers = str.split(request.headers["Authorization"])
|
||||
token = Headers[1]
|
||||
access_token = OAuth2Token.query.filter_by(access_token=token).first()
|
||||
if access_token:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def invalid_user():
|
||||
response = jsonify({"message": "User not recognized"})
|
||||
response.status = 401
|
||||
return response
|
||||
|
||||
|
||||
def invalid_project():
|
||||
response = jsonify({"message": "Project not found"})
|
||||
response.status_code = 404
|
||||
return response
|
||||
|
||||
|
||||
@bcf.route("/projects")
|
||||
def projects():
|
||||
if validate_client(request):
|
||||
return jsonify(jdata["Projects"])
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/")
|
||||
@login_required
|
||||
def bcf_3():
|
||||
return "<h1>BCF HOMPAGE</h1>"
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>")
|
||||
def project_details(project_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
return jsonify(project)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
project_put = open(f"{schema_path}/Project/project_PUT.json")
|
||||
project_put = json.load(project_put)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>", methods=["PUT"])
|
||||
@expects_json(project_put)
|
||||
def update_project(project_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
response = jsonify(data)
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/extensions")
|
||||
def extensions(project_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
return jsonify(jdata["Extensions"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics")
|
||||
def topics(project_id):
|
||||
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
return jsonify(jdata["Topics"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
topic_post = open(f"{schema_path}/Collaboration/Topic/topic_POST.json")
|
||||
topic_post = json.load(topic_post)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>", methods=["POST"])
|
||||
@expects_json(topic_post)
|
||||
def create_topic(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "POST":
|
||||
body = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
response = jsonify(body)
|
||||
response.status_code = 201
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>")
|
||||
def topic_details(project_id, topic_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(topic)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
topic_put = open(f"{schema_path}/Collaboration/Topic/topic_PUT.json")
|
||||
topic_put = json.load(topic_put)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>", methods=["PUT"])
|
||||
@expects_json(topic_put)
|
||||
def update_topic(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(data)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>", methods=["DELETE"])
|
||||
def delete_topic(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "DELETE":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify("OK")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/snippet", methods=["GET"])
|
||||
def get_snippet(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return send_file(f"{my_absolute_dirpath}/success.txt", download_name="snippet.txt")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/snippet", methods=["PUT"])
|
||||
def update_snippet(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify("PUT Request Sucessfull")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/files_information", methods=["GET"])
|
||||
def get_files_information(project_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
return jsonify(jdata["Files"])
|
||||
return invalid_project()
|
||||
else:
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/files", methods=["GET"])
|
||||
def get_files(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify("Get request for files successfull")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
file_put = open(f"{schema_path}/Collaboration/File/file_PUT.json")
|
||||
file_put = json.load(file_put)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/files", methods=["PUT"])
|
||||
@expects_json(file_put)
|
||||
def update_files(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(data)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/comments", methods=["GET"])
|
||||
def get_comments(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(jdata["Comments"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
comment_post = open(f"{schema_path}/Collaboration/Comment/comment_POST.json")
|
||||
comment_post = json.load(comment_post)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/comments", methods=["POST"])
|
||||
@expects_json(comment_post)
|
||||
def create_comments(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "POST":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
response = jsonify(data)
|
||||
response.status_code = 201
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/comments/<comment_id>", methods=["GET"])
|
||||
def get_comment(project_id, topic_id, comment_id):
|
||||
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for comment in jdata["Comments"]:
|
||||
if (comment["guid"]) == comment_id:
|
||||
return jsonify(comment)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
comment_put = open(f"{schema_path}/Collaboration/Comment/comment_PUT.json")
|
||||
comment_put = json.load(comment_put)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/comments/<comment_id>", methods=["PUT"])
|
||||
@expects_json(comment_put)
|
||||
def update_comment(project_id, topic_id, comment_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for comment in jdata["Comments"]:
|
||||
if (comment["guid"]) == comment_id:
|
||||
return jsonify(data)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/comments/<comment_id>", methods=["DELETE"])
|
||||
def delete_comment(project_id, topic_id, comment_id):
|
||||
if validate_client(request) and request.method == "DELETE":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for comment in jdata["Comments"]:
|
||||
if (comment["guid"]) == comment_id:
|
||||
return jsonify("OK")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints", methods=["GET"])
|
||||
def get_viewpoints(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
return jsonify(jdata["Viewpoints"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
viewpoint_post = open(f"{schema_path}/Collaboration/Viewpoint/viewpoint_POST.json")
|
||||
viewpoint_post = json.load(viewpoint_post)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints", methods=["POST"])
|
||||
@expects_json(viewpoint_post)
|
||||
def create_viewpoints(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "POST":
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
data = request.get_json()
|
||||
response = jsonify(data)
|
||||
response.status_code = 201
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>", methods=["GET"])
|
||||
def get_viewpoint(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint)
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>", methods=["DELETE"])
|
||||
def delete_viewpoint(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request) and request.method == "DELETE":
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint)
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>/snapshot", methods=["GET"])
|
||||
def get_snapshot(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint["snapshot"])
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>/bitmaps/<bitmap_id>", methods=["GET"])
|
||||
def get_bitmap(project_id, topic_id, viewpoint_id, bitmap_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
for bitmap in viewpoint["bitmaps"]:
|
||||
if bitmap["guid"] == bitmap_id:
|
||||
response = jsonify(bitmap)
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>/selection", methods=["GET"])
|
||||
def get_selection(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint["selection"])
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>/coloring", methods=["GET"])
|
||||
def get_coloring(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint["coloring"])
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/viewpoints/<viewpoint_id>/visibility", methods=["GET"])
|
||||
def get_visibility(project_id, topic_id, viewpoint_id):
|
||||
if validate_client(request):
|
||||
for project in jdata["Projects"]:
|
||||
if project["project_id"] == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if topic["guid"] == topic_id:
|
||||
for viewpoint in jdata["Viewpoints"]:
|
||||
if viewpoint["guid"] == viewpoint_id:
|
||||
response = jsonify(viewpoint["visibility"])
|
||||
response.status_code = 200
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/related_topics", methods=["GET"])
|
||||
def get_related_topics(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(jdata["RelatedTopics"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
related_topics_put = open(f"{schema_path}/Collaboration/RelatedTopic/related_topic_PUT.json")
|
||||
related_topics_put = json.load(related_topics_put)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/related_topics", methods=["PUT"])
|
||||
@expects_json(related_topics_put)
|
||||
def update_related_topics(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(data)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/document_references", methods=["GET"])
|
||||
def get_document_references(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(jdata["DocumentReferences"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
document_reference_post = open(f"{schema_path}/Collaboration/DocumentReference/document_reference_POST.json")
|
||||
document_reference_post = json.load(document_reference_post)
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/document_references", methods=["POST"])
|
||||
@expects_json(document_reference_post)
|
||||
def create_document_references(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "POST":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
response = jsonify(data)
|
||||
response.status_code = 201
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
document_reference_put = open(f"{schema_path}/Collaboration/DocumentReference/document_reference_PUT.json")
|
||||
document_reference_put = json.load(document_reference_put)
|
||||
|
||||
|
||||
@bcf.route(
|
||||
"/projects/<project_id>/topics/<topic_id>/document_references/<document_reference_id>",
|
||||
methods=["PUT"],
|
||||
)
|
||||
@expects_json(document_reference_put)
|
||||
def update_document_references(project_id, topic_id, document_reference_id):
|
||||
if validate_client(request) and request.method == "PUT":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for document in jdata["DocumentReferences"]:
|
||||
if (document["guid"]) == document_reference_id:
|
||||
return jsonify(data)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/documents", methods=["GET"])
|
||||
def get_documents(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
return jsonify(jdata["Documents"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/documents", methods=["POST"])
|
||||
def create_documents(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "POST":
|
||||
data = request.get_json()
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
response = jsonify(data)
|
||||
response.status_code = 201
|
||||
return response
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/documents/<document_id>", methods=["GET"])
|
||||
def get_document(project_id, topic_id, document_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for document in jdata["Documents"]:
|
||||
if (document["guid"]) == document_id:
|
||||
return send_file(f"{my_absolute_dirpath}/success.txt", download_name="document.txt")
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/events", methods=["GET"])
|
||||
def get_events(project_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
return jsonify(jdata["Events"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/<topic_id>/events", methods=["GET"])
|
||||
def get_topic_events(project_id, topic_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for event in jdata["Events"]:
|
||||
if (event["topic_guid"]) == topic_id:
|
||||
return jsonify(event)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route("/projects/<project_id>/topics/comments/events", methods=["GET"])
|
||||
def get_comments_events(project_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
return jsonify(jdata["EventComments"])
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
|
||||
|
||||
@bcf.route(
|
||||
"/projects/<project_id>/topics/<topic_id>/comments/<comment_id>/events",
|
||||
methods=["GET"],
|
||||
)
|
||||
def get_comment_events(project_id, topic_id, comment_id):
|
||||
if validate_client(request) and request.method == "GET":
|
||||
for project in jdata["Projects"]:
|
||||
if (project["project_id"]) == project_id:
|
||||
for topic in jdata["Topics"]:
|
||||
if (topic["guid"]) == topic_id:
|
||||
for comment in jdata["EventComments"]:
|
||||
if (comment["comment_guid"]) == comment_id:
|
||||
return jsonify(comment)
|
||||
return invalid_project()
|
||||
return invalid_user()
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"title": "comment_actions",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["update",
|
||||
"delete"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"title": "project_actions",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["update",
|
||||
"createTopic",
|
||||
"createDocument"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"title": "topic_actions",
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["update",
|
||||
"updateBimSnippet",
|
||||
"updateRelatedTopics",
|
||||
"updateDocumentReferences",
|
||||
"updateFiles",
|
||||
"createComment",
|
||||
"createViewpoint",
|
||||
"delete"]
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"required": false,
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": ["delete"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"title": "comment_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"author": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"comment": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"topic_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"viewpoint_guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"modified_date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"modified_author": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"authorization": {
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"properties": {
|
||||
"comment_actions": {
|
||||
"$ref": "../Action/comment_actions.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"title": "comment_POST",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"comment": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"viewpoint_guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "comment_PUT",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comment": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"viewpoint_guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "document_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"filename": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "document_reference_GET",
|
||||
"description": "Schema for a single document reference GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"document_guid": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"url": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"title": "document_reference_POST",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"document_guid": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"url": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "document_reference_PUT",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"document_guid": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"url": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"title": "comment_event_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"comment_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"topic_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"author": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "event_action.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "event_action",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"type": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"title": "topic_event_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"topic_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"date": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"author": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"$ref": "event_action.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "file_GET",
|
||||
"description": "Schema for a single file GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ifc_project": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"ifc_spatial_structure_element": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"filename": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"reference": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"title": "file_PUT",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"ifc_project": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"ifc_spatial_structure_element": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"filename": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"reference": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "project_file_display_information",
|
||||
"description": "Schema for the display information of a project file, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"field_display_name": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"field_value": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "project_file_information",
|
||||
"description": "Schema for a single project file information, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"display_information": {
|
||||
"type": "array",
|
||||
"items": { "$ref": "project_file_display_information.json" },
|
||||
"default": []
|
||||
},
|
||||
"file": { "$ref": "file_GET.json" }
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"description": "Schema for the listing the response of the GET project files information service",
|
||||
"title": "project_files_information_GET",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "project_file_information.json"
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "related_topic_GET",
|
||||
"description": "Schema for single related topic GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"related_topic_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "related_topic_PUT",
|
||||
"description": "Schema for related topic PUT, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"related_topic_guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"title": "bim_snippet",
|
||||
"type": ["object",
|
||||
"null"],
|
||||
"properties": {
|
||||
"snippet_type": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"is_external": {
|
||||
"required": true,
|
||||
"type": "boolean"
|
||||
},
|
||||
"reference": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"reference_schema": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"title": "topic_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"server_assigned_id": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"topic_type": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"topic_status": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"reference_links": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"priority": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"index": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"labels": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"creation_date": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"creation_author": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"modified_date": {
|
||||
"type": "string"
|
||||
},
|
||||
"modified_author": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"assigned_to": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"stage": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"bim_snippet": {
|
||||
"$ref": "bim_snippet.json"
|
||||
},
|
||||
"due_date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"authorization": {
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"properties": {
|
||||
"topic_actions": {
|
||||
"$ref": "../Action/topic_actions.json"
|
||||
},
|
||||
"topic_status": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "topic_POST",
|
||||
"description": "Schema for topic POST, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"topic_type": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"topic_status": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"reference_links": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"priority": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"index": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"labels": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"assigned_to": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"stage": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"bim_snippet": {
|
||||
"$ref": "bim_snippet.json"
|
||||
},
|
||||
"due_date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "topic_PUT",
|
||||
"description": "Schema for topic PUT, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"topic_type": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"topic_status": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"reference_links": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"priority": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"index": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"labels": {
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"assigned_to": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"stage": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"description": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"bim_snippet": {
|
||||
"$ref": "bim_snippet.json"
|
||||
},
|
||||
"due_date": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": "string"
|
||||
},
|
||||
"bitmap_type": {
|
||||
"type": "string",
|
||||
"enum": ["jpg", "png"]
|
||||
},
|
||||
"location": {
|
||||
"$ref": "location.json"
|
||||
},
|
||||
"normal": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"up": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"height": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bitmap_type": {
|
||||
"type": "string",
|
||||
"enum": ["jpg", "png"]
|
||||
},
|
||||
"bitmap_data": {
|
||||
"type": "string",
|
||||
"format": "base64"
|
||||
},
|
||||
"location": {
|
||||
"$ref": "location.json"
|
||||
},
|
||||
"normal": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"up": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"height": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"title": "clipping_plane",
|
||||
"type": ["object",
|
||||
"null"],
|
||||
"properties": {
|
||||
"location": {
|
||||
"$ref": "location.json"
|
||||
},
|
||||
"direction": {
|
||||
"$ref": "direction.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "coloring",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"color": {
|
||||
"type": "string"
|
||||
},
|
||||
"components": {
|
||||
"$ref": "component_list.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "coloring_GET",
|
||||
"description": "Schema for coloring GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"coloring": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "coloring.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "component",
|
||||
"type": ["object"],
|
||||
"properties": {
|
||||
"ifc_guid": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"originating_system": {
|
||||
"type": ["string", "null"]
|
||||
},
|
||||
"authoring_tool_id": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title": "component list",
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "component.json"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"title": "components",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"selection": {
|
||||
"$ref": "component_list.json"
|
||||
},
|
||||
"coloring": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "coloring.json"
|
||||
}
|
||||
},
|
||||
"visibility": {
|
||||
"$ref": "visibility.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "direction",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number"
|
||||
},
|
||||
"y": {
|
||||
"type": "number"
|
||||
},
|
||||
"z": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "line",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"start_point": {
|
||||
"$ref": "point.json"
|
||||
},
|
||||
"end_point": {
|
||||
"$ref": "point.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"title": "location",
|
||||
"type": ["object",
|
||||
"null"],
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number"
|
||||
},
|
||||
"y": {
|
||||
"type": "number"
|
||||
},
|
||||
"z": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"title": "orthogonal_camera",
|
||||
"type": ["object",
|
||||
"null"],
|
||||
"properties": {
|
||||
"camera_view_point": {
|
||||
"$ref": "point.json"
|
||||
},
|
||||
"camera_direction": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"camera_up_vector": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"view_to_world_scale": {
|
||||
"type": "number"
|
||||
},
|
||||
"aspect_ratio": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"title": "perspective_camera",
|
||||
"type": ["object",
|
||||
"null"],
|
||||
"properties": {
|
||||
"camera_view_point": {
|
||||
"$ref": "point.json"
|
||||
},
|
||||
"camera_direction": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"camera_up_vector": {
|
||||
"$ref": "direction.json"
|
||||
},
|
||||
"field_of_view": {
|
||||
"type": "number"
|
||||
},
|
||||
"aspect_ratio": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"title": "point",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"x": {
|
||||
"type": "number"
|
||||
},
|
||||
"y": {
|
||||
"type": "number"
|
||||
},
|
||||
"z": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "selection_GET",
|
||||
"description": "Schema for selection GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"selection": {
|
||||
"$ref": "component_list.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"title": "snapshot_GET",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"snapshot_type": {
|
||||
"type": ["string"],
|
||||
"enum": ["jpg", "png"]
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "snapshot_POST",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"snapshot_type": {
|
||||
"type": ["string"],
|
||||
"enum": ["jpg", "png"]
|
||||
},
|
||||
"snapshot_data": {
|
||||
"type": ["string"],
|
||||
"format": "base64"
|
||||
}
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"title": "view_setup_hints",
|
||||
"type": ["object", "null"],
|
||||
"properties": {
|
||||
"spaces_visible": {
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
},
|
||||
"space_boundaries_visible": {
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
},
|
||||
"openings_visible": {
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"title": "viewpoint_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"index": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"guid": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"orthogonal_camera": {
|
||||
"$ref": "orthogonal_camera.json"
|
||||
},
|
||||
"perspective_camera": {
|
||||
"$ref": "perspective_camera.json"
|
||||
},
|
||||
"lines": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "line.json"
|
||||
}
|
||||
},
|
||||
"clipping_planes": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "clipping_plane.json"
|
||||
}
|
||||
},
|
||||
"bitmaps": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "bitmap_GET.json"
|
||||
}
|
||||
},
|
||||
"snapshot": {
|
||||
"$ref": "snapshot_GET.json"
|
||||
},
|
||||
"authorization": {
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"properties": {
|
||||
"viewpoint_actions": {
|
||||
"$ref": "../Action/viewpoint_actions.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"title": "viewpoint_POST",
|
||||
"type": [ "object" ],
|
||||
"properties": {
|
||||
"guid": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
},
|
||||
"index": {
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"orthogonal_camera": {
|
||||
"$ref": "orthogonal_camera.json"
|
||||
},
|
||||
"perspective_camera": {
|
||||
"$ref": "perspective_camera.json"
|
||||
},
|
||||
"lines": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "line.json"
|
||||
}
|
||||
},
|
||||
"clipping_planes": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "clipping_plane.json"
|
||||
}
|
||||
},
|
||||
"bitmaps": {
|
||||
"type": ["array", "null"],
|
||||
"items": {
|
||||
"$ref": "bitmap_POST.json"
|
||||
}
|
||||
},
|
||||
"snapshot": {
|
||||
"$ref": "snapshot_POST.json"
|
||||
},
|
||||
"components": {
|
||||
"$ref": "components.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"title": "visibility",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"default_visibility": {
|
||||
"type": "boolean",
|
||||
"default": "false"
|
||||
},
|
||||
"exceptions": {
|
||||
"$ref": "component_list.json"
|
||||
},
|
||||
"view_setup_hints": {
|
||||
"$ref": "view_setup_hints.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "visibility_GET",
|
||||
"description": "Schema for visibility GET, BCF REST API.",
|
||||
"type": "object",
|
||||
|
||||
"properties": {
|
||||
"visibility": {
|
||||
"$ref": "visibility.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"title": "extensions_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"topic_type": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"topic_status": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"topic_label": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"snippet_type": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"stage": {
|
||||
"required": true,
|
||||
"type": ["array",
|
||||
"null"],
|
||||
"items": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
},
|
||||
"project_actions": {
|
||||
"$ref": "../Collaboration/Action/project_actions.json"
|
||||
},
|
||||
"topic_actions": {
|
||||
"$ref": "../Collaboration/Action/topic_actions.json"
|
||||
},
|
||||
"comment_actions": {
|
||||
"$ref": "../Collaboration/Action/comment_actions.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "project_GET",
|
||||
"description": "Schema for single project GET, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"project_id": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
},
|
||||
"authorization": {
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"properties": {
|
||||
"project_actions": {
|
||||
"$ref": "../Collaboration/Action/project_actions.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "project_PUT",
|
||||
"description": "Schema for project PUT, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "user_GET",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"required": true,
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": ["string",
|
||||
"null"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"title": "Error",
|
||||
"description": "Schema for error, BCF REST API.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Your request was successfull
|
||||
@@ -0,0 +1,54 @@
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import StringField, PasswordField, BooleanField, SubmitField
|
||||
from wtforms.validators import DataRequired, Length, Email, Regexp, EqualTo
|
||||
from wtforms import ValidationError
|
||||
from .models import User
|
||||
|
||||
|
||||
class RegisterForm(FlaskForm):
|
||||
def validate_username(self, username_to_check):
|
||||
user = User.query.filter_by(username=username_to_check.data).first()
|
||||
if user:
|
||||
raise ValidationError(
|
||||
"Username already exists! Please try a different username"
|
||||
)
|
||||
|
||||
def validate_email_address(self, email_address_to_check):
|
||||
email_address = User.query.filter_by(
|
||||
email_address=email_address_to_check.data
|
||||
).first()
|
||||
if email_address:
|
||||
raise ValidationError("Email Address already exists!")
|
||||
|
||||
username = StringField(
|
||||
label="User Name:", validators=[Length(min=2, max=30), DataRequired()]
|
||||
)
|
||||
email_address = StringField(
|
||||
label="Email Address:", validators=[Email(), DataRequired()]
|
||||
)
|
||||
password1 = PasswordField(
|
||||
label="Password:", validators=[Length(min=6), DataRequired()]
|
||||
)
|
||||
password2 = PasswordField(
|
||||
label="Confirm Password:", validators=[EqualTo("password1"), DataRequired()]
|
||||
)
|
||||
submit = SubmitField(label="Create Account")
|
||||
|
||||
|
||||
class LoginForm(FlaskForm):
|
||||
username = StringField(label="User Name:", validators=[DataRequired()])
|
||||
password = PasswordField(label="Password:", validators=[DataRequired()])
|
||||
submit = SubmitField(label="Sign in")
|
||||
|
||||
|
||||
class OauthForm(FlaskForm):
|
||||
client_name = StringField(label="Client Name:", validators=[DataRequired()])
|
||||
# client_uri = StringField(label="Client URI:", validators=[DataRequired()])
|
||||
grant_types = StringField(label="Grant Types:", validators=[DataRequired()])
|
||||
# redirect_uris = StringField(label="Redirect URIs:", validators=[DataRequired()])
|
||||
response_types = StringField(label="Response Types:", validators=[DataRequired()])
|
||||
scope = StringField(label="Scope:", validators=[DataRequired()])
|
||||
# token_endpoint_auth_method = StringField(
|
||||
# label="Token Endpoint Auth Method:", validators=[DataRequired()]
|
||||
# )
|
||||
submit = SubmitField(label="Create OAuth")
|
||||
@@ -0,0 +1,69 @@
|
||||
from run import db, bcrypt, login_manager
|
||||
import time
|
||||
from authlib.integrations.sqla_oauth2 import (
|
||||
OAuth2ClientMixin,
|
||||
OAuth2AuthorizationCodeMixin,
|
||||
OAuth2TokenMixin,
|
||||
)
|
||||
from flask_login import UserMixin
|
||||
|
||||
|
||||
@login_manager.user_loader
|
||||
def load_user(user_id):
|
||||
return User.query.get(int(user_id))
|
||||
|
||||
|
||||
class User(db.Model, UserMixin):
|
||||
id = db.Column(db.Integer(), primary_key=True)
|
||||
username = db.Column(db.String(50), unique=True, nullable=False)
|
||||
password_hash = db.Column(db.String(80), nullable=False)
|
||||
email_address = db.Column(db.String(50), unique=True, nullable=False)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.username} {self.email_address}"
|
||||
|
||||
def get_user_id(self):
|
||||
return self.id
|
||||
|
||||
@property
|
||||
def password(self):
|
||||
return self.password
|
||||
|
||||
@password.setter
|
||||
def password(self, plain_text_password):
|
||||
self.password_hash = bcrypt.generate_password_hash(plain_text_password).decode(
|
||||
"utf-8"
|
||||
)
|
||||
|
||||
def check_password(self, attempted_password):
|
||||
return bcrypt.check_password_hash(self.password_hash, attempted_password)
|
||||
|
||||
|
||||
class OAuth2Client(db.Model, OAuth2ClientMixin):
|
||||
__tablename__ = "oauth2_client"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
|
||||
user = db.relationship("User", lazy=True)
|
||||
|
||||
|
||||
class OAuth2AuthorizationCode(db.Model, OAuth2AuthorizationCodeMixin):
|
||||
__tablename__ = "oauth2_code"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
|
||||
user = db.relationship("User", lazy=True)
|
||||
|
||||
|
||||
class OAuth2Token(db.Model, OAuth2TokenMixin):
|
||||
__tablename__ = "oauth2_token"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
user_id = db.Column(db.Integer, db.ForeignKey("user.id", ondelete="CASCADE"))
|
||||
user = db.relationship("User", lazy=True)
|
||||
|
||||
def is_refresh_token_active(self):
|
||||
if self.revoked:
|
||||
return False
|
||||
expires_at = self.issued_at + self.expires_in * 2
|
||||
return expires_at >= time.time()
|
||||
@@ -0,0 +1,102 @@
|
||||
from authlib.integrations.flask_oauth2 import (
|
||||
AuthorizationServer,
|
||||
ResourceProtector,
|
||||
)
|
||||
from authlib.integrations.sqla_oauth2 import (
|
||||
create_query_client_func,
|
||||
create_save_token_func,
|
||||
create_revocation_endpoint,
|
||||
create_bearer_token_validator,
|
||||
)
|
||||
from authlib.oauth2.rfc6749 import grants
|
||||
from authlib.oauth2.rfc7636 import CodeChallenge
|
||||
from .models import db, User
|
||||
from .models import OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
|
||||
|
||||
|
||||
class AuthorizationCodeGrant(grants.AuthorizationCodeGrant):
|
||||
TOKEN_ENDPOINT_AUTH_METHODS = [
|
||||
"client_secret_basic",
|
||||
"client_secret_post",
|
||||
"none",
|
||||
]
|
||||
|
||||
def save_authorization_code(self, code, request):
|
||||
code_challenge = request.data.get("code_challenge")
|
||||
code_challenge_method = request.data.get("code_challenge_method")
|
||||
auth_code = OAuth2AuthorizationCode(
|
||||
code=code,
|
||||
client_id=request.client.client_id,
|
||||
redirect_uri=request.redirect_uri,
|
||||
scope=request.scope,
|
||||
user_id=request.user.id,
|
||||
code_challenge=code_challenge,
|
||||
code_challenge_method=code_challenge_method,
|
||||
)
|
||||
db.session.add(auth_code)
|
||||
db.session.commit()
|
||||
return auth_code
|
||||
|
||||
def query_authorization_code(self, code, client):
|
||||
auth_code = OAuth2AuthorizationCode.query.filter_by(
|
||||
code=code, client_id=client.client_id
|
||||
).first()
|
||||
if auth_code and not auth_code.is_expired():
|
||||
return auth_code
|
||||
|
||||
def delete_authorization_code(self, authorization_code):
|
||||
db.session.delete(authorization_code)
|
||||
db.session.commit()
|
||||
|
||||
def authenticate_user(self, authorization_code):
|
||||
return User.query.get(authorization_code.user_id)
|
||||
|
||||
|
||||
class PasswordGrant(grants.ResourceOwnerPasswordCredentialsGrant):
|
||||
def authenticate_user(self, username, password):
|
||||
user = User.query.filter_by(username=username).first()
|
||||
if user is not None and user.check_password(password):
|
||||
return user
|
||||
|
||||
|
||||
class RefreshTokenGrant(grants.RefreshTokenGrant):
|
||||
def authenticate_refresh_token(self, refresh_token):
|
||||
token = OAuth2Token.query.filter_by(refresh_token=refresh_token).first()
|
||||
if token and token.is_refresh_token_active():
|
||||
return token
|
||||
|
||||
def authenticate_user(self, credential):
|
||||
return User.query.get(credential.user_id)
|
||||
|
||||
def revoke_old_credential(self, credential):
|
||||
credential.revoked = True
|
||||
db.session.add(credential)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
query_client = create_query_client_func(db.session, OAuth2Client)
|
||||
save_token = create_save_token_func(db.session, OAuth2Token)
|
||||
authorization = AuthorizationServer(
|
||||
query_client=query_client,
|
||||
save_token=save_token,
|
||||
)
|
||||
require_oauth = ResourceProtector()
|
||||
|
||||
|
||||
def config_oauth(app):
|
||||
authorization.init_app(app)
|
||||
|
||||
# support all grants
|
||||
authorization.register_grant(grants.ImplicitGrant)
|
||||
authorization.register_grant(grants.ClientCredentialsGrant)
|
||||
authorization.register_grant(AuthorizationCodeGrant, [CodeChallenge(required=True)])
|
||||
authorization.register_grant(PasswordGrant)
|
||||
authorization.register_grant(RefreshTokenGrant)
|
||||
|
||||
# support revocation
|
||||
revocation_cls = create_revocation_endpoint(db.session, OAuth2Token)
|
||||
authorization.register_endpoint(revocation_cls)
|
||||
|
||||
# protect resource
|
||||
bearer_cls = create_bearer_token_validator(db.session, OAuth2Token)
|
||||
require_oauth.register_token_validator(bearer_cls())
|
||||
@@ -0,0 +1,302 @@
|
||||
from flask.blueprints import Blueprint
|
||||
from flask import render_template, redirect, url_for, flash, request
|
||||
from werkzeug import datastructures
|
||||
from .forms import RegisterForm, LoginForm, OauthForm
|
||||
from flask_login import login_user, logout_user, login_required, current_user
|
||||
from .models import User, OAuth2Client, OAuth2AuthorizationCode, OAuth2Token
|
||||
import base64
|
||||
from werkzeug.security import gen_salt
|
||||
import time
|
||||
import urllib
|
||||
import json
|
||||
from run import db, app
|
||||
|
||||
foundation_obj = Blueprint(
|
||||
"foundation_obj",
|
||||
__name__,
|
||||
template_folder="templates",
|
||||
)
|
||||
|
||||
|
||||
def split_by_crlf(s):
|
||||
return [v for v in s.splitlines() if v]
|
||||
|
||||
|
||||
@foundation_obj.route("/")
|
||||
def homepage():
|
||||
return render_template("index.html")
|
||||
# return "homepage"
|
||||
|
||||
|
||||
@foundation_obj.route("/register", methods=["GET", "POST"])
|
||||
def register_page():
|
||||
form = RegisterForm()
|
||||
if form.validate_on_submit():
|
||||
user_to_create = User(
|
||||
username=form.username.data,
|
||||
email_address=form.email_address.data,
|
||||
password=form.password1.data,
|
||||
)
|
||||
|
||||
db.session.add(user_to_create)
|
||||
db.session.commit()
|
||||
login_user(user_to_create)
|
||||
flash(
|
||||
f"Account created successfully! {user_to_create.username}",
|
||||
category="success",
|
||||
)
|
||||
return redirect(url_for("foundation_obj.homepage"))
|
||||
if form.errors != {}:
|
||||
for err_msg in form.errors.values():
|
||||
flash(
|
||||
f"There was an error with creating a user: {err_msg}", category="danger"
|
||||
)
|
||||
|
||||
return render_template("register.html", form=form)
|
||||
|
||||
|
||||
@foundation_obj.route("/createclient", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def create_client():
|
||||
grants = [
|
||||
"AuthorizationCodeGrant",
|
||||
"ImplicitGrant",
|
||||
"ResourceOwnerPasswordCredentialsGrant",
|
||||
"ClientCredentialsGrant",
|
||||
"RefreshTokenGrant",
|
||||
]
|
||||
form = OauthForm()
|
||||
if form.validate_on_submit():
|
||||
client_id = gen_salt(24)
|
||||
client_id_issued_at = int(time.time())
|
||||
|
||||
client = OAuth2Client(
|
||||
client_id=client_id,
|
||||
client_id_issued_at=client_id_issued_at,
|
||||
user_id=current_user.id,
|
||||
)
|
||||
client_metadata = {
|
||||
"client_name": form.client_name.data,
|
||||
"grant_types": split_by_crlf(form.grant_types.data),
|
||||
"response_types": split_by_crlf(form.response_types.data),
|
||||
"scope": form.scope.data,
|
||||
"token_endpoint_auth_method": "client_secret_basic",
|
||||
}
|
||||
client.client_secret = gen_salt(48)
|
||||
|
||||
client.set_client_metadata(client_metadata)
|
||||
db.session.add(client)
|
||||
db.session.commit()
|
||||
flash(
|
||||
"Oauth Client Created Successfully",
|
||||
category="info",
|
||||
)
|
||||
clients = OAuth2Client.query.filter_by(user_id=current_user.id).all()
|
||||
for client in clients:
|
||||
print(client.client_info)
|
||||
print(client.client_metadata)
|
||||
return render_template("clientdata.html", user=current_user.id, clients=clients)
|
||||
return render_template("createclient.html", form=form, grants=grants)
|
||||
|
||||
|
||||
@foundation_obj.route("/login", methods=["GET", "POST"])
|
||||
def login_page():
|
||||
form = LoginForm()
|
||||
if form.validate_on_submit():
|
||||
attempted_user = User.query.filter_by(username=form.username.data).first()
|
||||
if attempted_user and attempted_user.check_password(
|
||||
attempted_password=form.password.data
|
||||
):
|
||||
login_user(attempted_user)
|
||||
return redirect(url_for("foundation_obj.homepage"))
|
||||
else:
|
||||
flash(
|
||||
"Invalid Credentials",
|
||||
category="danger",
|
||||
)
|
||||
|
||||
return render_template("login.html", form=form)
|
||||
|
||||
|
||||
@foundation_obj.route("/logout")
|
||||
def logoutpage():
|
||||
logout_user()
|
||||
flash("You have been logged out!", category="info")
|
||||
return redirect(url_for("foundation_obj.homepage"))
|
||||
|
||||
|
||||
@foundation_obj.route("/foundation/1.0/auth")
|
||||
def foundation_auth():
|
||||
data = {
|
||||
"oauth2_auth_url": "http://127.0.0.1:5000/oauth/authorize",
|
||||
"oauth2_token_url": "http://127.0.0.1:5000/oauth/token",
|
||||
"supported_oauth2_flows": ["authorization_code"],
|
||||
}
|
||||
response = app.response_class(
|
||||
response=json.dumps(data), status=200, mimetype="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@foundation_obj.route("/foundation/versions")
|
||||
def foundation_versions():
|
||||
Body = {
|
||||
"versions": [
|
||||
{
|
||||
"api_id": "opencde-foundation",
|
||||
"version_id": "1.0",
|
||||
"detailed_version": "https://github.com/BuildingSMART/opencde-foundation-API/tree/v1.0",
|
||||
},
|
||||
# {
|
||||
# "api_id": "bcf",
|
||||
# "version_id": "2.1",
|
||||
# "detailed_version": "https://github.com/buildingSMART/BCF-API/tree/release_2_1",
|
||||
# "api_base_url": "http://127.0.0.1:5000/bcf/2.1"
|
||||
# },
|
||||
{
|
||||
"api_id": "bcf",
|
||||
"version_id": "3.0",
|
||||
"detailed_version": "https://github.com/buildingSMART/BCF-API/tree/release_3_0",
|
||||
"api_base_url": "http://127.0.0.1:5000/bcf/3.0",
|
||||
},
|
||||
]
|
||||
}
|
||||
response = app.response_class(
|
||||
response=json.dumps(Body), status=200, mimetype="application/json"
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
@foundation_obj.route("/outh/login", methods=["GET", "POST"])
|
||||
def oauth_login():
|
||||
form = LoginForm()
|
||||
if form.validate_on_submit():
|
||||
attempted_user = User.query.filter_by(username=form.username.data).first()
|
||||
if attempted_user and attempted_user.check_password(
|
||||
attempted_password=form.password.data
|
||||
):
|
||||
login_user(attempted_user)
|
||||
flash(
|
||||
"Invalid Credentials",
|
||||
category="info",
|
||||
)
|
||||
client_id = request.args.get("client_id")
|
||||
redirect_uri = request.args.get("redirect_uri")
|
||||
state = request.args.get("state")
|
||||
return redirect(
|
||||
url_for(
|
||||
"foundation_obj.authorize",
|
||||
client_id=client_id,
|
||||
redirect_uri=redirect_uri,
|
||||
state=state,
|
||||
)
|
||||
)
|
||||
else:
|
||||
flash(
|
||||
"Invalid Credentials",
|
||||
category="danger",
|
||||
)
|
||||
return render_template("ologin.html", form=form)
|
||||
|
||||
|
||||
@foundation_obj.route("/oauth/authorize", methods=["GET", "POST"])
|
||||
def authorize():
|
||||
client_id = request.args.get("client_id")
|
||||
redirect_uri = request.args.get("redirect_uri")
|
||||
state = request.args.get("state")
|
||||
if current_user.is_anonymous:
|
||||
flash("Please Login !", category="info")
|
||||
query = request.query_string
|
||||
return redirect(
|
||||
url_for(
|
||||
"foundation_obj.oauth_login",
|
||||
client_id=client_id,
|
||||
redirect_uri=redirect_uri,
|
||||
state=state,
|
||||
)
|
||||
)
|
||||
else:
|
||||
try:
|
||||
|
||||
user = current_user.id
|
||||
flash(message=redirect_uri, category="warning")
|
||||
client = OAuth2Client.query.filter_by(client_id=client_id).first()
|
||||
if client:
|
||||
if client.user_id == user:
|
||||
code = gen_salt(48)
|
||||
OauthCode = OAuth2AuthorizationCode(
|
||||
client_id=client_id,
|
||||
redirect_uri=redirect_uri,
|
||||
user_id=user,
|
||||
code=code,
|
||||
response_type="code",
|
||||
)
|
||||
db.session.add(OauthCode)
|
||||
db.session.commit()
|
||||
query = urllib.parse.urlencode(
|
||||
{
|
||||
"code": OauthCode.code,
|
||||
"state": state,
|
||||
}
|
||||
)
|
||||
return redirect(f"{redirect_uri}?{query}")
|
||||
else:
|
||||
flash(
|
||||
"You are not authorized to access this client",
|
||||
category="danger",
|
||||
)
|
||||
else:
|
||||
flash("Client not found", category="danger")
|
||||
except Exception as e:
|
||||
flash(e, category="danger")
|
||||
return render_template("oauth.html")
|
||||
|
||||
|
||||
@foundation_obj.route("/oauth/token", methods=["POST"])
|
||||
def issue_token():
|
||||
try:
|
||||
code = request.form["code"]
|
||||
Headers = str.split(request.headers["Authorization"])
|
||||
decode_header = base64.b64decode(Headers[1]).decode("utf-8")
|
||||
creds = decode_header.split(":")
|
||||
client_id = creds[0]
|
||||
# print(code, Headers, decode_header, creds, client_id)
|
||||
auth_code = OAuth2AuthorizationCode.query.filter_by(code=code).first()
|
||||
if auth_code:
|
||||
if auth_code.client_id == client_id:
|
||||
access_token = gen_salt(48)
|
||||
refresh_token = gen_salt(48)
|
||||
expires_in = 3600
|
||||
OauthToken = OAuth2Token(
|
||||
client_id=auth_code.client_id,
|
||||
user_id=auth_code.user_id,
|
||||
access_token=access_token,
|
||||
refresh_token=refresh_token,
|
||||
expires_in=expires_in,
|
||||
scope=auth_code.scope,
|
||||
token_type="Bearer",
|
||||
)
|
||||
db.session.add(OauthToken)
|
||||
db.session.commit()
|
||||
query = {
|
||||
"access_token": access_token,
|
||||
"refresh_token": refresh_token,
|
||||
"expires_in": expires_in,
|
||||
}
|
||||
response = app.response_class(
|
||||
response=json.dumps(query),
|
||||
status=200,
|
||||
mimetype="application/json",
|
||||
)
|
||||
print(query)
|
||||
return response
|
||||
else:
|
||||
flash(
|
||||
"You are not authorized to access this client",
|
||||
category="danger",
|
||||
)
|
||||
else:
|
||||
flash("Client not found", category="danger")
|
||||
except Exception as e:
|
||||
flash(e, category="danger")
|
||||
return render_template("oauth.html")
|
||||
@@ -0,0 +1,119 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<!-- Required meta tags -->
|
||||
<meta charset="utf-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||
/>
|
||||
<!-- Bootstrap CSS -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
|
||||
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
|
||||
crossorigin="anonymous"
|
||||
/>
|
||||
<title>{% block title %} {% endblock %}</title>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md navbar-dark bg-dark">
|
||||
<a class="navbar-brand" href="#">BCF OLD SERVER</a>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target="#navbarNav"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarNav">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item active">
|
||||
<a class="nav-link" href="{{ url_for('foundation_obj.homepage') }}"
|
||||
>Home <span class="sr-only">(current)</span></a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
{% if current_user.is_authenticated %}
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" style="color: lawngreen; font-weight: bold">
|
||||
<i class="fas fa-coins"></i>
|
||||
{{ current_user.prettier_budget }}
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link">Welcome, {{ current_user.username }}</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{{ url_for('foundation_obj.logoutpage') }}"
|
||||
>Logout</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{{ url_for('foundation_obj.create_client') }}"
|
||||
>Create Client</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
{% else %}
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{{ url_for('foundation_obj.login_page') }}"
|
||||
>Login</a
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
href="{{ url_for('foundation_obj.register_page') }}"
|
||||
>Register</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
</nav>
|
||||
{% with messages = get_flashed_messages(with_categories=true) %} {% if
|
||||
messages %} {% for category, message in messages %}
|
||||
<div class="alert alert-{{ category }}">
|
||||
<button
|
||||
type="button"
|
||||
class="m1-2 mb-1 close"
|
||||
data-dismiss="alert"
|
||||
aria-label="Close"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
{{ message }}
|
||||
</div>
|
||||
{% endfor %} {% endif %} {% endwith %} {% block content %} {% endblock %}
|
||||
<!-- Future Content here -->
|
||||
|
||||
<!-- Optional JavaScript -->
|
||||
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
|
||||
<script src="https://kit.fontawesome.com/a076d05399.js"></script>
|
||||
<script
|
||||
src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
|
||||
integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
|
||||
integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
<script
|
||||
src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"
|
||||
integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV"
|
||||
crossorigin="anonymous"
|
||||
></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
{%extends 'base.html'%} {%block content%} {% if user %}
|
||||
<style>
|
||||
pre {
|
||||
white-space: wrap;
|
||||
}
|
||||
</style>
|
||||
<div>Logged in as <strong>{{user}}</strong></div>
|
||||
|
||||
{% for client in clients %}
|
||||
<pre>
|
||||
{{ client.client_info|tojson }}
|
||||
{{ client.client_metadata|tojson }}
|
||||
</pre>
|
||||
<hr />
|
||||
{% endfor %} {% else %}
|
||||
<div>Not logged in</div>
|
||||
{% endif %} {% endblock %}
|
||||
@@ -0,0 +1,28 @@
|
||||
{%extends 'base.html' %} {%block title %} {% endblock%} {%block content%}
|
||||
<body class="text-center">
|
||||
<div class="container">
|
||||
<form method="post" class="form-register" style="color: black">
|
||||
{{form.hidden_tag()}}
|
||||
<h1 class="h3 mb-3 font-weight-normal font-monospace text-center">
|
||||
Register
|
||||
</h1>
|
||||
{{form.client_name.label()}} {{form.client_name(class="form-control",
|
||||
placeholder="Client_name")}}
|
||||
<!-- <label for="grant_types">Select grant Type</label>
|
||||
<select name="grants">
|
||||
{% for grant in grants%}
|
||||
<option value="{{ grant_types}}" selected>{{ grant }}</option>
|
||||
{% endfor %}
|
||||
</select> -->
|
||||
{{form.grant_types.label()}} {{form.grant_types(class="form-control",
|
||||
placeholder="Grant_Types")}} {{form.response_types.label()}}
|
||||
{{form.response_types(class="form-control",
|
||||
placeholder="Response_Types")}} {{form.scope.label()}}
|
||||
{{form.scope(class="form-control", placeholder="Scope")}}
|
||||
<br />
|
||||
{{form.submit(class="btn btn-lg btn-primary btn-block" ,value="Create
|
||||
Oauth Credentials")}}
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
<!-- {%extends 'base.html'%} {%block title%} Homepage {%endblock%} {%block content%}
|
||||
<h1>BCF Open Source Server Homepage</h1>
|
||||
{%endblock%} -->
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
Home Page
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,27 @@
|
||||
{% extends 'base.html' %} {% block title %}{% endblock %} {% block content %}
|
||||
<body class="text-center">
|
||||
<div class="container">
|
||||
<form method="POST" class="form-signin" style="color: black">
|
||||
{{ form.hidden_tag() }}
|
||||
<h1 class="h3 mb-3 font-weight-normal">Please Login</h1>
|
||||
<br />
|
||||
{{ form.username.label() }} {{ form.username(class="form-control",
|
||||
placeholder="User Name") }} {{ form.password.label() }} {{
|
||||
form.password(class="form-control", placeholder="Password") }}
|
||||
|
||||
<br />
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<h6>Do not have an account?</h6>
|
||||
<a
|
||||
class="btn btn-sm btn-secondary"
|
||||
href="{{ url_for('foundation_obj.register_page') }}"
|
||||
>Register</a
|
||||
>
|
||||
</div>
|
||||
|
||||
{{ form.submit(class="btn btn-lg btn-block btn-primary") }}
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{%extends "base.html"%} {%block content%} this is Oauth page {%endblock%}
|
||||
@@ -0,0 +1,28 @@
|
||||
{% extends 'base.html' %} {% block title %}{% endblock %} {% block content %}
|
||||
<body class="text-center">
|
||||
<div class="container">
|
||||
<form method="POST" class="form-signin" style="color: black">
|
||||
{{ form.hidden_tag() }}
|
||||
<h1 class="h3 mb-3 font-weight-normal">Please Login</h1>
|
||||
THis is Oauth Login
|
||||
<br />
|
||||
{{ form.username.label() }} {{ form.username(class="form-control",
|
||||
placeholder="User Name") }} {{ form.password.label() }} {{
|
||||
form.password(class="form-control", placeholder="Password") }}
|
||||
|
||||
<br />
|
||||
|
||||
<div class="checkbox mb-3">
|
||||
<h6>Do not have an account?</h6>
|
||||
<a
|
||||
class="btn btn-sm btn-secondary"
|
||||
href="{{ url_for('foundation_obj.register_page') }}"
|
||||
>Register</a
|
||||
>
|
||||
</div>
|
||||
|
||||
{{ form.submit(class="btn btn-lg btn-block btn-primary") }}
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,30 @@
|
||||
{%extends 'base.html' %} {%block title %} {% endblock%} {%block content%}
|
||||
<body class="text-center">
|
||||
<div class="container">
|
||||
<form method="post" class="form-register" style="color: black">
|
||||
{{form.hidden_tag()}}
|
||||
<h1 class="h3 mb-3 font-weight-normal font-monospace text-center">
|
||||
Register
|
||||
</h1>
|
||||
{{form.username.label()}} {{form.username(class="form-control"
|
||||
,placeholder="Username")}} {{form.email_address.label()}}
|
||||
{{form.email_address(class="form-control" ,placeholder="Email Address")}}
|
||||
{{form.password1.label()}}
|
||||
{{form.password1(class="form-control",placeholder="Password")}}
|
||||
{{form.password2.label()}} {{form.password2(class="form-control"
|
||||
,placeholder="Confirm Password")}}
|
||||
<br />
|
||||
<div class="checkbox mb-3">
|
||||
<h6>Already have an account?</h6>
|
||||
<a
|
||||
class="btn btn-sm btn-secondary"
|
||||
href="{{ url_for('foundation_obj.login_page') }}"
|
||||
>Login</a
|
||||
>
|
||||
</div>
|
||||
{{form.submit(class="btn btn-lg btn-primary btn-block"
|
||||
,value="Register")}}
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,25 @@
|
||||
from flask import Flask
|
||||
from flask_sqlalchemy import SQLAlchemy
|
||||
from flask_login import LoginManager
|
||||
from flask_bcrypt import Bcrypt
|
||||
|
||||
|
||||
app = Flask(__name__)
|
||||
db = SQLAlchemy(app)
|
||||
login_manager = LoginManager(app)
|
||||
bcrypt = Bcrypt(app)
|
||||
app.config["SECRET_KEY"] = "f613729206685405cde0e388"
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///sqlite.db"
|
||||
login_manager.login_view = "foundation_obj.login_page"
|
||||
login_manager.login_message_category = "info"
|
||||
|
||||
from foundation.routes import foundation_obj
|
||||
from bcf.routes import bcf
|
||||
|
||||
|
||||
app.register_blueprint(foundation_obj)
|
||||
app.register_blueprint(bcf)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5000, debug=True)
|
||||
@@ -0,0 +1,9 @@
|
||||
Authlib==0.15.4
|
||||
email-validator==1.1.3
|
||||
Flask==2.0.1
|
||||
Flask-Login==0.5.0
|
||||
Flask-SQLAlchemy==2.5.1
|
||||
Flask-WTF==0.15.1
|
||||
Flask-Bcrypt==0.7.1
|
||||
bcrypt==3.2.0
|
||||
flask-expects-json==1.6.0
|
||||
Reference in New Issue
Block a user