Skip to content

Commit

Permalink
Add privileges/authorization info to the API
Browse files Browse the repository at this point in the history
  • Loading branch information
wrobelda committed Nov 22, 2022
1 parent 5f5bcbc commit 9b0b819
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 3 deletions.
6 changes: 3 additions & 3 deletions collect_api_endpoints.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
{{ title_underline }}
{% for controller in controllers %}
.. csv-table:: {{controller.type}} ({{controller.filename}})
:header: "Method", "Module", "Controller", "Command", "Parameters"
:widths: 4, 15, 15, 30, 40
:header: "Method", "Module", "Controller", "Command", "Parameters", "Privilege required"
:widths: 4, 15, 15, 30, 40, 40
{% for endpoint in controller.endpoints %}
"``{{endpoint.method}}``","{{endpoint.module}}","{{endpoint.controller}}","{{endpoint.command}}","{{endpoint.parameters}}"
"``{{endpoint.method}}``","{{endpoint.module}}","{{endpoint.controller}}","{{endpoint.command}}","{{endpoint.parameters}}","{{', '.join(endpoint.acl_names)}}"
{%- endfor %}
{%- if controller.uses %}
{% for use in controller.uses %}
Expand Down
16 changes: 16 additions & 0 deletions collect_api_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import os
import argparse
import re
import xml.etree.ElementTree as ET
from jinja2 import Template

EXCLUDE_CONTROLLERS = ['Core/Api/FirmwareController.php']
Expand Down Expand Up @@ -85,6 +86,14 @@ def parse_api_php(src_filename):
if os.path.isfile(model_xml):
model_filename = model_xml.replace('//', '/')

acl_filename = None
if len(m) > 0:
app_location = "/".join(src_filename.split('/')[:-5])
acl_location = "/".join(m[0].replace("\\", "/").split('/')[:-1])
acl_xml = "%s/models/%s/ACL/ACL.xml" % (app_location, acl_location)
if os.path.isfile(acl_xml):
acl_filename = acl_xml.replace('//', '/')

function_callouts = re.findall(r"(\n\s+(private|public|protected)\s+function\s+(\w+)\((.*)\))", data)
result = list()
this_commands = []
Expand All @@ -108,6 +117,13 @@ def parse_api_php(src_filename):
'filename': base_filename,
'model_filename': model_filename
}
if acl_filename:
record['acl_names'] = []
tree = ET.parse(acl_filename)
for page in tree.findall('*'):
for pattern in page.findall('patterns/pattern'):
if pattern.text in [f"api/{module_name}/{controller}", f"api/{module_name}/*"]:
record['acl_names'] += [page.find('name').text]
if is_abstract:
record['type'] = 'Abstract [non-callable]'
elif controller.find('service') > -1:
Expand Down
28 changes: 28 additions & 0 deletions source/development/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ There are two HTTP verbs used in the OPNsense API:
The body of the HTTP POST request and response is an 'application/json' object.
Authentication
--------------
The $key and $secret parameters are used to pass the API credentials using curl. You need to set these parameters with your own API credentials before using them in the examples:
.. code-block:: sh
Expand All @@ -29,6 +32,31 @@ The $key and $secret parameters are used to pass the API credentials using curl.
When using Postman to test an API call, use the 'basic auth' authorization type. The $key and $secret parameters go into Username/Password respectively.
Authorization
-------------
When using the API, the user for which the $key and $secret were issued, needs to have required privileges granted.
The required privileges, if any, are explicitly mentioned in the API documentation.
In case of doubts, however, you can grep through the source code. For example, for the `sslh` module,
the privileges can be found in https://github.com/opnsense/plugins/blob/master/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/ACL/ACL.xml (you may need to choose a tag that is relevant to the OPNsense version you use).
The corresponding privilege name that needs to be granted is denoted by the `<name>` element. For the `sslh` module and "any" controller (as denoted by the "`/*`" wildcard ),
it is `Services: SSLH`:
.. code-block:: xml
<acl>
<page-services-sslh>
<name>Services: SSLH</name>
<patterns>
<pattern>ui/sslh/*</pattern>
<pattern>api/sslh/*</pattern>
</patterns>
</page-services-sslh>
</acl>
Core API
--------
Expand Down

0 comments on commit 9b0b819

Please sign in to comment.