Skip to content

Commit

Permalink
feat(user): add ACL management
Browse files Browse the repository at this point in the history
  • Loading branch information
jhonsfran1165 committed Sep 14, 2021
1 parent abd1286 commit 4c138c1
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 11 deletions.
18 changes: 18 additions & 0 deletions app/api/deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from jose import jwt
from pydantic import ValidationError
from sqlmodel.ext.asyncio.session import AsyncSession
from fastapi_permissions import Everyone, Authenticated, configure_permissions

from app.user import cruds
from app.user.models.token import TokenPayload
Expand Down Expand Up @@ -43,6 +44,23 @@ async def get_current_user(
return user


async def get_principals(
current_user: User = Depends(get_current_user)
) -> dict:
""" returns the principals of the current logged in user"""

principals = [Everyone]

if cruds.user.is_active(current_user):
# TODO
principals = [Everyone, Authenticated]

return principals


# Permission is already wrapped in Depends()
Permission = configure_permissions(get_principals)

def get_current_active_user(
current_user: User = Depends(get_current_user),
) -> User:
Expand Down
3 changes: 2 additions & 1 deletion app/core/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ def create_access_token(
expire = datetime.utcnow() + timedelta(
minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES
)
to_encode = {"exp": expire, "sub": str(subject)}
# TODO
to_encode = {"exp": expire, "sub": str(subject), "groups": ["admin"]}
encoded_jwt = jwt.encode(to_encode, settings.SECRET_KEY, algorithm=ALGORITHM)
return encoded_jwt

Expand Down
11 changes: 11 additions & 0 deletions app/place/models/place.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from sqlmodel import SQLModel
from fastapi_permissions import Allow, Authenticated


# Shared properties
Expand All @@ -12,6 +13,16 @@ class PlaceBase(SQLModel):
country: str
bounding_box: str

def __acl__(self):
return [
(Allow, Authenticated, "view", "edit", "share", "create", "delete", "list"),
# (Allow, "role:admin", "edit"),
# (Allow, f"user:{self.owner}", "delete"),
# (Allow, Authenticated, "view"),
# (Allow, "role:admin", "edit"),
# (Allow, f"user:{self.owner}", "delete"),
]


# Additional properties to return via API
class Place(PlaceBase):
Expand Down
15 changes: 9 additions & 6 deletions app/place/routers/place.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from sqlmodel import select
from sqlmodel.ext.asyncio.session import AsyncSession
from fastapi_permissions import Authenticated, Allow


from app.place.models.place import Place
from app.place.views import place
Expand All @@ -14,18 +16,19 @@
prefix="/places"
)

@router.get("/users", response_model=List[User])
async def get_songs(db: AsyncSession = Depends(deps.get_db)):
result = await db.exec(select(User))
songs = result.all()
return songs

acl_places = [
(Allow, "admin", "*"),
(Allow, "owner", "*"),
(Allow, Authenticated, "view")
]

# TODO: https://github.com/holgi/fastapi-permissions/issues/3
@router.get("/", response_model=List[Place])
async def read_users(
db: AsyncSession = Depends(deps.get_db),
skip: int = 0,
limit: int = 100,
acls: list = deps.Permission("view", acl_places)
) -> Any:
"""
Retrieve places from bigquery.
Expand Down
11 changes: 9 additions & 2 deletions app/place/views/place.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@

from app.place.queries import queries
from app.core.bigquery import bigquery
# from app.place.models.place import Place


@logger.catch
async def get_places(limit: int, skip: int):
async def get_places(limit: int = 1, skip: int = 0):
query_job = await queries.get_places(bigquery.client, limit=limit, offset=skip)
df = query_job.to_dataframe()
result = json.loads(df.to_json(orient='records'))

return result
# I can format the response
# places = []

# for place in result:
# places.append(Place(**place))

# return places
4 changes: 3 additions & 1 deletion app/user/routers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ async def login_access_token(
access_token_expires = timedelta(minutes=settings.ACCESS_TOKEN_EXPIRE_MINUTES)
return {
"access_token": security.create_access_token(
user.id, expires_delta=access_token_expires
user.id,

expires_delta=access_token_expires
),
"token_type": "bearer",
}
Expand Down
11 changes: 11 additions & 0 deletions app/user/routers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@
prefix="/users"
)

# https://medium.com/swlh/quickly-make-an-api-with-auth-3e1e0ca695ef
# TODO
async def common_parameters(
db: AsyncSession = Depends(deps.get_db),
skip: int = 0,
limit: int = Query(default=100, lte=100),
current_user: User = Depends(deps.get_current_active_superuser)
):
return {"db": db, "skip": skip, "limit": limit, "current_user": current_user}



@router.get("/", response_model=List[User])
async def read_users(
Expand Down
22 changes: 21 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ python-jose = {extras = ["cryptography"], version = "^3.3.0"}
asyncpg = "^0.24.0"
psycopg2-binary = "^2.9.1"
aiosql = "^3.3.1"
fastapi_permissions = "^0.2.7"

[tool.poetry.dev-dependencies]
gitlint = "^0.15.1"
Expand Down

0 comments on commit 4c138c1

Please sign in to comment.