Skip to content

Commit

Permalink
add policies
Browse files Browse the repository at this point in the history
  • Loading branch information
rmb938 committed Oct 23, 2017
1 parent 227b649 commit 689656f
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 40 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[run]
omit =
*/test/*
ingredients_db/alembic/env.py

[report]
exclude_lines =
Expand Down
84 changes: 57 additions & 27 deletions ingredients_db/alembic/versions/dadf4ada480a_create_authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,6 @@ def upgrade():
nullable=False)
)

# rules_table = op.create_table(
# 'authz_rules',
# sa.Column('id', sau.UUIDType, server_default=sa.text("uuid_generate_v4()"), primary_key=True),
# sa.Column('name', sa.String, nullable=False, unique=True),
# sa.Column('value', sa.String, nullable=False),
# sa.Column('description', sa.String),
# sa.Column('created_at', sau.ArrowType(timezone=True), server_default=sa.func.now(), nullable=False),
# sa.Column('updated_at', sau.ArrowType(timezone=True), server_default=sa.func.now(), onupdate=sa.func.now(),
# nullable=False)
# )

roles_table = op.create_table(
'authz_roles',
sa.Column('id', sau.UUIDType, server_default=sa.text("uuid_generate_v4()"), primary_key=True),
Expand Down Expand Up @@ -75,12 +64,10 @@ def upgrade():
nullable=False),
)

# TODO: populate default roles

op.bulk_insert(
roles_table,
[
{"name": "admin", "description": "Administrator Role for Sandwich Cloud"}
{"name": "admin", "description": "Administrator Role"}
]
)

Expand All @@ -90,38 +77,81 @@ def upgrade():
# Rules
{"name": "is_admin", "rule": "role:admin", "description": "Is the user in the admin role"},
{"name": "admin_or_member", "rule": "rule:is_admin or project_id:%(project_id)s",
"description": "Is the user in the admin role"},
"description": "Is the user in the admin role or a member of the project of the requested object"},
{"name": "admin_or_self", "rule": "rule:is_admin or user_id:%(user_id)",
"description": "Is the user in the admin role or the requested object matches the user id"},

# Policies
# Use role:admin so we don't get locked out if is_admin is changed/deleted
# If the admin role gets deleted... well don't be stupid :p
{"name": "policies:create", "rule": "role:admin", "description": "Ability to create a policy"},
{"name": "policies:get", "rule": "role:admin", "description": "Ability to get a policy"},
{"name": "policies:update", "rule": "role:admin", "description": "Ability to update a policy"},
{"name": "policies:list", "rule": "role:admin", "description": "Ability to list policies"},
{"name": "policies:delete", "rule": "role:admin", "description": "Ability to delete a policy"},

# Roles
# Use role:admin so we don't get locked out if is_admin is changed/deleted
# If the admin role gets deleted... well don't be stupid :p
{"name": "roles:create", "rule": "role:admin", "description": "Ability to create a role"},
{"name": "roles:get", "rule": "role:admin", "description": "Ability to get a role"},
{"name": "roles:list", "rule": "role:admin", "description": "Ability to list roles"},
{"name": "roles:delete", "rule": "role:admin", "description": "Ability to delete a role"},

# Tokens
{"name": "tokens:get", "rule": "rule:admin_or_self", "description": "Ability to get a token"},

# Tasks

# Projects
{"name": "projects:create", "rule": "rule:is_admin", "description": "Ability to create projects"},
{"name": "projects:get", "rule": "", "description": "Ability to get a project"},
{"name": "projects:list", "rule": "", "description": "Ability to list projects"},
{"name": "projects:delete", "rule": "rule:is_admin", "description": "Ability to delete projects"},
# Images
{"name": "images:create", "rule": "rule:admin_or_member", "description": "Ability to create an image"},
{"name": "images:create:public", "rule": "rule:is_admin",
"description": "Ability to create a public image"},
{"name": "images:get", "rule": "rule:admin_or_member", "description": "Ability to get an image"},
{"name": "images:list", "rule": "rule:admin_or_member", "description": "Ability to list images"},
{"name": "images:delete", "rule": "rule:admin_or_member", "description": "Ability to delete an image"},
{"name": "images:action:lock", "rule": "rule:admin_or_member", "description": "Ability to lock an image"},
{"name": "images:action:unlock", "rule": "rule:admin_or_member",
"description": "Ability to unlock an image"},

# Instances
{"name": "instances:create", "rule": "rule:admin_or_member",
"description": "Ability to create an instance"},
{"name": "instances:get", "rule": "rule:admin_or_member", "description": "Ability to get an instance"},
{"name": "instances:list", "rule": "rule:admin_or_member", "description": "Ability to list instances"},
{"name": "instances:delete", "rule": "rule:admin_or_member",
"description": "Ability to delete an instance"},
{"name": "instances:action:stop", "rule": "rule:admin_or_member",
"description": "Ability to stop an instance"},
{"name": "instances:action:start", "rule": "rule:admin_or_member",
"description": "Ability to start an instance"},
{"name": "instances:action:restart", "rule": "rule:admin_or_member",
"description": "Ability to restart an instance"},
{"name": "instances:action:image", "rule": "rule:admin_or_member",
"description": "Ability to create an image from an instance"},
{"name": "instances:action:image:public", "rule": "rule:is_admin",
"description": "Ability to create a public image from an instance"},
{"name": "instances:action:reset_state", "rule": "rule:admin_or_member",
"description": "Ability to reset the state of an instance"},

# Networks
{"name": "networks:create", "rule": "rule:is_admin", "description": "Ability to create a network"},
{"name": "networks:get", "rule": "", "description": "Ability to get a network"},
{"name": "networks:list", "rule": "", "description": "Ability to list networks"},
{"name": "networks:delete", "rule": "rule:is_admin", "description": "Ability to delete a network"},

# Images
{"name": "images:create", "rule": "rule:admin_or_member", "description": "Ability to create images"},
# Projects
{"name": "projects:create", "rule": "rule:is_admin", "description": "Ability to create a project"},
{"name": "projects:get", "rule": "", "description": "Ability to get a project"},
{"name": "projects:list", "rule": "", "description": "Ability to list projects"},
{"name": "projects:delete", "rule": "rule:is_admin", "description": "Ability to delete a project"},

# Instances
]
)

# TODO: populate default policies
#


def downgrade():
op.drop_table('authn_token_roles')
op.drop_table('authn_tokens')
op.drop_table('authz_roles')
# op.drop_table('authz_rules')
op.drop_table('authz_policies')
14 changes: 2 additions & 12 deletions ingredients_db/models/authz.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from ingredients_db.database import Base


# TODO: should we have locked policies to prevent accidental deletion?
class AuthZPolicy(Base):
__tablename__ = 'authz_policies'

Expand All @@ -16,18 +17,7 @@ class AuthZPolicy(Base):
updated_at = Column(ArrowType(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)


# class AuthZRule(Base):
# __tablename__ = 'authz_rules'
#
# id = Column(UUIDType, server_default=text("uuid_generate_v4()"), primary_key=True)
# name = Column(String, nullable=False, unique=True)
# value = Column(String, nullable=False)
# description = Column(String)
#
# created_at = Column(ArrowType(timezone=True), server_default=func.now(), nullable=False)
# updated_at = Column(ArrowType(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)


# TODO: should we have locked roles to prevent accidental deletion?
class AuthZRole(Base):
__tablename__ = 'authz_roles'

Expand Down
3 changes: 2 additions & 1 deletion ingredients_db/test/test_migrations.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os

import pytest
from alembic import command
Expand All @@ -19,7 +20,7 @@ def alembic_root():

@pytest.fixture()
def uri():
yield "postgresql+psycopg2://postgres@localhost"
yield "postgresql+psycopg2://postgres@127.0.0.1" if 'CI' in os.environ else os.environ['TEST_DB_URL']


@pytest.fixture()
Expand Down
3 changes: 3 additions & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ deps =
flake8

[testenv:py36]
passenv =
TEST_DB_URL
CI
commands =
py.test
deps =
Expand Down

0 comments on commit 689656f

Please sign in to comment.