Skip to content

Commit

Permalink
Conda-store Authentication/Authorization (#97)
Browse files Browse the repository at this point in the history
* Adding jupyterhub authenticator to begin implementation

* Adding authentication

* Adding initial tests to conda-store-server

* Adding authentication routes

* Adding authentication method

* Testing authentication/authorization internals

* Adding routes and methods for authentication

* Adding authentication routes to app

* Making tests pass

* Adding authorized routes

* Removing specifications from api provided via build route

* Black and flake8 formatting

* Wrong permissions for developer role

* Adding entity to nav bar for login/logout routes

* Black formatting
  • Loading branch information
costrouc authored Aug 4, 2021
1 parent 0fa49b6 commit 928ba38
Show file tree
Hide file tree
Showing 25 changed files with 866 additions and 184 deletions.
10 changes: 5 additions & 5 deletions conda-store-server/conda_store_server/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from .conda import conda_platform


def list_namespaces(db, limit: int = 25):
def list_namespaces(db):
filters = []
return db.query(orm.Namespace).filter(*filters).all()
return db.query(orm.Namespace).filter(*filters)


def get_namespace(db, name: str = None, id: int = None):
Expand All @@ -23,7 +23,7 @@ def list_environments(db, namespace: str = None, search=None):
if namespace:
filters.append(orm.Namespace.name == namespace)

return db.query(orm.Environment).join(orm.Namespace).filter(*filters).all()
return db.query(orm.Environment).join(orm.Environment.namespace).filter(*filters)


def get_environment(
Expand Down Expand Up @@ -70,12 +70,12 @@ def post_specification(conda_store, specification, namespace=None):
conda_store.register_environment(specification, namespace)


def list_builds(db, limit: int = 25, status: orm.BuildStatus = None):
def list_builds(db, status: orm.BuildStatus = None):
filters = []
if status:
filters.append(orm.Build.status == status)

return db.query(orm.Build).filter(*filters).limit(limit).all()
return db.query(orm.Build).filter(*filters)


def get_build(db, build_id):
Expand Down
1 change: 0 additions & 1 deletion conda-store-server/conda_store_server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@ def register_environment(
orm.Environment(
name=specification.name,
namespace_id=namespace.id,
specification_id=specification.id,
build_id=build.id,
)
)
Expand Down
3 changes: 0 additions & 3 deletions conda-store-server/conda_store_server/orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,6 @@ class Environment(Base):

name = Column(String, nullable=False)

specification_id = Column(Integer, ForeignKey("specification.id"))
specification = relationship(Specification)

build_id = Column(Integer, ForeignKey("build.id"))
build = relationship(Build)

Expand Down
71 changes: 53 additions & 18 deletions conda-store-server/conda_store_server/schema.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import datetime
import enum
from typing import List, Optional, Union, Dict
import functools

from pydantic import BaseModel, Field


def docker_datetime_factory():
def _datetime_factory(offset: datetime.timedelta):
"""utcnow datetime + timezone as string"""
return datetime.datetime.utcnow().astimezone().isoformat()
return datetime.datetime.utcnow() + offset


#########################
# Authentication Schema
#########################


class AuthenticationToken(BaseModel):
exp: datetime.datetime = Field(
default_factory=functools.partial(_datetime_factory, datetime.timedelta(days=1))
)
primary_namespace: str = "default"
role_bindings: Dict[str, List[str]] = {}


##########################
# Database Schema
##########################


class StorageBackend(enum.Enum):
Expand Down Expand Up @@ -36,19 +55,12 @@ class Config:
orm_mode = True


class Build(BaseModel):
class Namespace(BaseModel):
id: int
specification_id: int
packages: List[CondaPackage]
status: enum.Enum
size: int
scheduled_on: datetime.datetime
started_on: Optional[datetime.datetime]
ended_on: Optional[datetime.datetime]
name: str

class Config:
orm_mode = True
use_enum_values = True


class Specification(BaseModel):
Expand All @@ -57,19 +69,33 @@ class Specification(BaseModel):
spec: dict
sha256: str
created_on: datetime.datetime
builds: List[Build]

class Config:
orm_mode = True


class Build(BaseModel):
id: int
namespace: Namespace
specification: Specification
packages: List[CondaPackage]
status: enum.Enum
size: int
scheduled_on: datetime.datetime
started_on: Optional[datetime.datetime]
ended_on: Optional[datetime.datetime]

class Config:
orm_mode = True
use_enum_values = True


class Environment(BaseModel):
id: int
namespace: str
namespace: Namespace
name: str
build_id: Optional[int]
specification_id: Optional[int]
specification: Optional[Specification]
build: Optional[Build]

class Config:
orm_mode = True
Expand All @@ -88,7 +114,16 @@ class CondaSpecification(BaseModel):
prefix: Optional[str]


# Docker Registry
###############################
# Docker Registry Schema
###############################


def _docker_datetime_factory():
"""utcnow datetime + timezone as string"""
return datetime.datetime.utcnow().astimezone().isoformat()


class DockerManifestLayer(BaseModel):
mediaType: str = "application/vnd.docker.image.rootfs.diff.tar.gzip"
size: int
Expand Down Expand Up @@ -137,7 +172,7 @@ class DockerConfigRootFS(BaseModel):


class DockerConfigHistory(BaseModel):
created: str = Field(default_factory=docker_datetime_factory)
created: str = Field(default_factory=_docker_datetime_factory)
created_by: str = ""


Expand All @@ -147,7 +182,7 @@ class DockerConfig(BaseModel):
config: DockerConfigConfig
container: str
container_config: DockerConfigConfig
created: str = Field(default_factory=docker_datetime_factory)
created: str = Field(default_factory=_docker_datetime_factory)
docker_version: str = "18.09.7"
history: List[DockerConfigHistory] = []
rootfs: DockerConfigRootFS
Expand Down
7 changes: 6 additions & 1 deletion conda-store-server/conda_store_server/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from traitlets import Bool, Unicode, Integer
from traitlets.config import Application

from conda_store_server.server import views
from conda_store_server.server import views, auth
from conda_store_server.app import CondaStore


Expand Down Expand Up @@ -69,6 +69,11 @@ def start(self):
app.register_blueprint(views.app_metrics)

app.conda_store = CondaStore(parent=self, log=self.log)
app.authentication = auth.Authentication(parent=self, log=self.log)

# add dynamic routes
for route, method, func in app.authentication.routes:
app.add_url_rule(route, func.__name__, func, methods=[method])

app.conda_store.ensure_namespace()
app.conda_store.ensure_directories()
Expand Down
Loading

0 comments on commit 928ba38

Please sign in to comment.