-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Group permissions manager #107
Merged
Merged
Changes from all commits
Commits
Show all changes
45 commits
Select commit
Hold shift + click to select a range
7c00d81
add core functionality for group permissions manager
philtweir 16412dd
add the group permission manager and related models
philtweir ddd0537
ensure CELERY url is set
philtweir a64392e
add permissions concept
philtweir 21bbc59
link in permission concept
philtweir ad4210b
add logical sets
philtweir f44a888
update docker
philtweir 60c214f
add arches-orm into requirement - tracking master for now, until semi…
philtweir fd247b7
add git - ideally we strip this out post-dev
philtweir a29e0df
enforce startup db wait
philtweir c57ffe9
adding docstrings
philtweir 244d9c7
update arches_orm
philtweir ce71c9f
add django-authorization
philtweir d371055
install all deps during static build also
philtweir 02c1094
install all deps during static build also
philtweir 6047658
build static directly on dynamic container
philtweir ec61198
build static directly on dynamic container
philtweir 586c228
leave service to setup its own DB
philtweir dca4678
tidy up to work with arches-orm refactor
philtweir 8fb68b4
arches_orm references at the top level in views cause the database to…
philtweir bdfcd87
full_name no longer present at top level
philtweir 828b786
lay groundwork for anonymous sets
philtweir 673c738
up timeout for ES
philtweir 4233dcf
fix group assignment
philtweir 0677fff
fix group assignment
philtweir 98aed12
make tasks async
philtweir c24b48b
groundwork for linking django groups to groups
philtweir 958d881
add django groups back in for non-resource specific permissions
philtweir 06ca944
update readme
philtweir 50ca100
allow use of a view-all permission framework for logged-in users
philtweir 5c16ab9
speed up permission checking
philtweir 912f7d6
remove envfile
philtweir d8cda2b
keep toolbar for consistency
philtweir c7046da
turn off debug
philtweir a7c619f
align DJANGO_DEBUG and DEBUG
philtweir 2503ff1
build for prod
philtweir 1fc79e6
keep toolbar for consistency
philtweir 1f3d38f
reduce size of permission table
philtweir dac5f65
update location
philtweir 1e81310
make sure graphid is a string when filtering as an admin
philtweir 855c0cc
watch for casbin reload requests on all processes
philtweir 9a5559d
update docker definitions
philtweir 6d047bf
ensure static apt is updated
philtweir ebc567a
cover case where a user creates a resource of their own, introducing …
philtweir 32f5ee7
cannot load resources before setting up django
philtweir File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,8 @@ | ||
# Welcome to the Arches Project! | ||
# Coral Arches | ||
|
||
Arches is a new, open-source, web-based, geospatial information system for cultural heritage inventory and management. Arches is purpose-built for the international cultural heritage field, and it is designed to record all types of immovable heritage, including archaeological sites, buildings and other historic structures, landscapes, and heritage ensembles or districts. | ||
This Arches implementation is designed to be run with Kubernetes and Dockerized. | ||
|
||
Please see the [project page](http://archesproject.org/) for more information on the Arches project. | ||
In addition, it uses Casbin permissions and a patched version of Arches. | ||
|
||
The Arches Installation Guide and Arches User Guide are available [here](http://archesproject.org/documentation/). | ||
This is in-development software: no warranty is made for open source use as regards | ||
the reliability, consistency, security or stability at this point. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
"""User data type for associating with models. | ||
|
||
Datatype to extend possible node values to Django users. | ||
""" | ||
|
||
|
||
import logging | ||
|
||
from arches.app.datatypes.base import BaseDataType | ||
from arches.app.models.models import Widget, Node | ||
from arches.app.models.tile import Tile | ||
from django.contrib.auth.models import User | ||
|
||
text: Widget = Widget.objects.get(name="user") | ||
|
||
details: dict[str, str | Widget | bool | None] = { | ||
"datatype": "user", | ||
"iconclass": "fa fa-location-arrow", | ||
"modulename": "user.py", | ||
"classname": "UserDataType", | ||
"defaultwidget": text, | ||
"defaultconfig": None, | ||
"configcomponent": None, | ||
"configname": None, | ||
"isgeometric": False, | ||
"issearchable": False, | ||
} | ||
|
||
logger: logging.Logger = logging.getLogger(__name__) | ||
|
||
class UserDataType(BaseDataType): | ||
"""DataType for a Django User.""" | ||
|
||
def append_to_document(self, document, nodevalue, nodeid, tile, provisional=False): | ||
document["strings"].append( | ||
{"string": nodevalue, "nodegroup_id": tile.nodegroup_id} | ||
) | ||
|
||
def get_search_terms(self, nodevalue, nodeid=None): | ||
if nodevalue: | ||
user = User.objects.get(pk=int(nodevalue)) | ||
return [user.email] | ||
return [] | ||
|
||
def get_display_value(self, tile, node, **kwargs): | ||
if (user := self.get_user(tile, node)): | ||
return user.email | ||
return None | ||
|
||
def get_user(self, tile: Tile, node: Node) -> User: | ||
data = self.get_tile_data(tile) | ||
if data: | ||
raw_value = data.get(str(node.nodeid)) | ||
if raw_value is not None: | ||
user = User.objects.get(pk=int(raw_value)) | ||
return user | ||
|
||
def compile_json(self, tile, node, **kwargs): | ||
json = super().compile_json(tile, node, **kwargs) | ||
data = self.get_tile_data(tile) | ||
if data: | ||
raw_value = data.get(str(node.nodeid)) | ||
json["userId"] = int(raw_value) | ||
return json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
""" | ||
ARCHES - a program developed to inventory and manage immovable cultural heritage. | ||
Copyright (C) 2013 J. Paul Getty Trust and World Monuments Fund | ||
|
||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU Affero General Public License as | ||
published by the Free Software Foundation, either version 3 of the | ||
License, or (at your option) any later version. | ||
|
||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU Affero General Public License for more details. | ||
|
||
You should have received a copy of the GNU Affero General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
""" | ||
|
||
import logging | ||
import readline | ||
from django.core.management.base import BaseCommand | ||
from django.contrib.auth.models import User, Group as DjangoGroup | ||
|
||
from coral import settings | ||
|
||
logging.basicConfig() | ||
|
||
class Command(BaseCommand): | ||
"""Recalculate ES resource->set mapping. | ||
|
||
""" | ||
|
||
print_statistics = False | ||
|
||
def add_arguments(self, parser): | ||
parser.add_argument( | ||
"-s", | ||
"--statistics", | ||
action="store_true", | ||
dest="print_statistics", | ||
help="Do extra searches to provide relevant statistics?", | ||
) | ||
|
||
|
||
def handle(self, *args, **options): | ||
# Cannot be imported until Django ready | ||
from coral.permissions.casbin import CasbinPermissionFramework | ||
from coral.utils.casbin import SetApplicator | ||
|
||
print_statistics = True if options["print_statistics"] else False | ||
|
||
set_applicator = SetApplicator(print_statistics=print_statistics, wait_for_completion=True) | ||
set_applicator.apply_sets() | ||
|
||
framework = CasbinPermissionFramework() | ||
framework.recalculate_table() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
""" | ||
ARCHES - a program developed to inventory and manage immovable cultural heritage. | ||
Copyright (C) 2013 J. Paul Getty Trust and World Monuments Fund | ||
|
||
This program is free software: you can redistribute it and/or modify | ||
it under the terms of the GNU Affero General Public License as | ||
published by the Free Software Foundation, either version 3 of the | ||
License, or (at your option) any later version. | ||
|
||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
GNU Affero General Public License for more details. | ||
|
||
You should have received a copy of the GNU Affero General Public License | ||
along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
""" | ||
|
||
import logging | ||
import readline | ||
from django.core.management.base import BaseCommand | ||
from django.contrib.auth.models import User, Group as DjangoGroup | ||
from arches.app.utils.permission_backend import assign_perm | ||
from arches.app.models.system_settings import settings | ||
from arches.app.models.resource import Resource | ||
from arches_orm.utils import attempt_well_known_resource_model | ||
from arches_orm.models import Group, Set | ||
from coral.permissions.casbin import CasbinPermissionFramework | ||
|
||
logging.basicConfig() | ||
|
||
class Command(BaseCommand): | ||
""" | ||
Commands for adding arches test users | ||
|
||
""" | ||
|
||
def add_arguments(self, parser): | ||
... # parser.add_argument("operation", nargs="?") | ||
|
||
def handle(self, *args, **options): | ||
table = self.get_table() | ||
|
||
def get_table(self): | ||
framework = CasbinPermissionFramework() | ||
enforcer = framework._enforcer | ||
enforcer.load_policy() | ||
logging.disable(logging.NOTSET) | ||
enforcer.model.logger.setLevel(logging.INFO) | ||
framework.recalculate_table() | ||
enforcer.model.print_policy() | ||
print(enforcer.get_implicit_permissions_for_user("u:310")) | ||
#group_tree = {} | ||
#set_tree = {} | ||
#group_x_set = [] | ||
#att = lambda key: attempt_well_known_resource_model(key.split(":", 1)[1]) | ||
#for key, ast in enforcer.model["p"].items(): | ||
# for policy in ast.policy: | ||
# if isinstance(policy, list) and len(policy) == 3: | ||
# group_x_set.append((att(policy[0]), att(policy[1]), Group.make_concept(policy[2]))) | ||
|
||
#print("GROUP === ACTION ===> SET") | ||
#for grp, st, act in group_x_set: | ||
# print(grp.name, "----", act.text, "---->", st.title_text) | ||
|
||
#for sec in ["g"]: | ||
# if sec not in enforcer.model.keys(): | ||
# print("Sec not found", sec) | ||
# continue | ||
|
||
# for key, ast in enforcer.model[sec].items(): | ||
# for policy in ast.policy: | ||
# prnt = att(policy[1]) | ||
# group_tree.setdefault(prnt.id, {"children": [], "ri": prnt, "has_parent": False}) | ||
# group_tree[prnt.id].setdefault("children", []) | ||
# prefix = policy[0].split(":", 1)[0] | ||
# if prefix in ("ri", "g", "g2", "g2l"): | ||
# try: | ||
# chld = att(policy[0]) | ||
# except Resource.DoesNotExist: | ||
# logging.error("Missing %s", policy[0]) | ||
# else: | ||
# group_tree.setdefault(chld.id, {"ri": chld}) | ||
# group_tree[chld.id]["has_parent"] = True | ||
# group_tree[prnt.id]["children"].append(group_tree[chld.id]) | ||
# elif prefix == "u": | ||
# group_tree[prnt.id]["children"].append(User.objects.get(pk=int(policy[0][2:]))) | ||
# else: | ||
# group_tree[prnt.id]["children"].append(policy[0]) | ||
#def _print_children(node, level): | ||
# for child in node["children"]: | ||
# if isinstance(child, dict): | ||
# print(" " * 2 * level, child["ri"]._model_name, str(child["ri"])) | ||
# if "children" in child: | ||
# _print_children(child, level + 1) | ||
# elif child["ri"]._model_name not in ("Group", "Set"): | ||
# print(" " * 2 * level, "\_", child["ri"].id) | ||
# elif isinstance(child, User): | ||
# print(" " * 2 * level, "User:", child.email) | ||
# else: | ||
# print(" " * 2 * level, "Unknown:", child) | ||
|
||
#print() | ||
|
||
#for root in (node for node in group_tree.values() if not node["has_parent"]): | ||
# print("Root:", root["ri"]._model_name, str(root["ri"])) | ||
# _print_children(root, 1) | ||
|
||
#last_user = None | ||
#last_permission = None | ||
#last_entity = None | ||
#while (user := input("User: ")) != "q": | ||
# if not user: | ||
# if last_user: | ||
# user = last_user | ||
# else: | ||
# break | ||
# else: | ||
# try: | ||
# user = User.objects.get(email__startswith=user) | ||
# except User.MultipleObjectsReturned: | ||
# print("[Found multiple matches, try again]") | ||
# continue | ||
# print(user, user.email, user.id) | ||
# print(user.is_authenticated) | ||
|
||
# entity = input("Entity: ") | ||
# if not entity: | ||
# if last_entity: | ||
# entity = last_entity | ||
# else: | ||
# break | ||
# else: | ||
# try: | ||
# entity = Resource.objects.get(resourceinstanceid__startswith=entity) | ||
# except User.MultipleObjectsReturned: | ||
# print("[Found multiple matches, try again]") | ||
# continue | ||
# ri = attempt_well_known_resource_model(entity.pk) | ||
|
||
# permission = input("Permission: ") | ||
# if not permission: | ||
# if last_permission: | ||
# permission = last_permission | ||
# else: | ||
# break | ||
# result = framework.check_resource_instance_permissions(user, ri.id, permission) | ||
# print(result) | ||
|
||
# last_user = user | ||
# last_permission = permission | ||
# last_entity = entity |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
define([ | ||
'knockout', | ||
'underscore', | ||
'cytoscape', | ||
'cytoscape-elk' | ||
], function(ko, _, cytoscape, elk) { | ||
cytoscape.use(elk); | ||
ko.bindingHandlers.cytoscape = { | ||
init: function(element, valueAccessor) { | ||
var defaults = { | ||
container: element | ||
}; | ||
var config = ko.unwrap(valueAccessor()).config || {}; | ||
|
||
var viz = cytoscape( | ||
_.defaults(ko.unwrap(config), defaults) | ||
); | ||
|
||
ko.utils.domNodeDisposal.addDisposeCallback(element, function() { | ||
viz.destroy(); | ||
}, this); | ||
|
||
if (typeof ko.unwrap(valueAccessor()).afterRender === 'function') { | ||
ko.unwrap(valueAccessor()).afterRender(viz); | ||
} | ||
}, | ||
}; | ||
return ko.bindingHandlers.cytoscape; | ||
}); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove debug