Skip to content
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

feat: add accept or decline collaboration invite #367

Merged
merged 1 commit into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions api_docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2783,6 +2783,44 @@ paths:
500:
description: "Internal Server Error"

"/projects/{project_id}/users/handle_invite":
patch:
tags:
- projects
consumes:
- application/json
description: "Accept or decline invite to project collaboration"
parameters:
- in: header
name: Authorization
required: true
type: string

- in: path
name: project_id
required: true
type: string

- in: body
name: projectUsers
schema:
type: object
required:
- accepted_collaboration_invite
properties:
accepted_collaboration_invite:
type: boolean
produces:
- application/json
responses:
201:
description: "Success"
400:
description: "Bad request"
500:
description: "Internal Server Error"


"/databases":
post:
tags:
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@
ProjectDatabaseRetrievePasswordView, ProjectDatabaseAdminRetrievePasswordView, DatabaseStatsView)
from .billing_invoice import (BillingInvoiceView,BillingInvoiceNotificationView)
from .system_status import SystemStatusView
from .project_users import ProjectUsersView, ProjectUsersTransferView
from .project_users import ProjectUsersView, ProjectUsersTransferView, ProjectUsersHandleInviteView
61 changes: 60 additions & 1 deletion app/controllers/project_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def post(self, project_id):
if role == 'owner':
return dict(status='fail', message='User cannot be added as owner'), 400

new_role = ProjectUser(role=role, user_id=user.id)
new_role = ProjectUser(role=role, user_id=user.id, accepted_collaboration_invite=False)
project.users.append(new_role)

saved_project_user = project.save()
Expand Down Expand Up @@ -399,3 +399,62 @@ def post(self, project_id):
status='success',
message='Project has been transfered successfully',
), 201

class ProjectUsersHandleInviteView(Resource):

@jwt_required
def patch(self, project_id):
"""
"""
current_user_id = get_jwt_identity()

project_user_schema = ProjectUserSchema(partial=True, exclude=["email","role"])

project_user_data = request.get_json()

validated_project_user_data, errors = project_user_schema.load(
project_user_data, partial=True)

if errors:
return dict(status='fail', message=errors), 400

# Get Project
project = Project.get_by_id(project_id)

if not project:
return dict(status='fail', message='Project not found'), 404

# Get user
user = User.get_by_id(current_user_id)

if not user:
return dict(status='fail', message='User not found'), 404

if user.id == project.owner.id:
return dict(status='fail', message='User is the owner of project and cannot be invited'), 400

existing_user = ProjectUser.find_first(user_id=user.id, project_id=project.id)

if not existing_user:
return dict(status='fail', message='User is not part of project'), 404

# updating user project collaboration invite
invite_status = validated_project_user_data.get('accepted_collaboration_invite', None)

if invite_status == False:
deleted_user = ProjectUser.delete(existing_user)

if not deleted_user:
return dict(status='fail', message='Internal Server Error'), 500

return dict(status='success', message='User successfully removed from the project'), 201

updated = ProjectUser.update(existing_user, accepted_collaboration_invite=invite_status)

if not updated:
return dict(status='fail', message='Internal Server Error'), 500

return dict(
status='success',
message='Invite to project has successfully been accepted',
), 201
1 change: 1 addition & 0 deletions app/models/project_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ class ProjectUser(ModelMixin):
user_id = db.Column('user_id', UUID(as_uuid=True), db.ForeignKey(User.id), nullable=False)
project_id = db.Column(UUID(as_uuid=True), db.ForeignKey('project.id'), nullable=False)
role = db.Column(db.Enum(RolesList), nullable=False)
accepted_collaboration_invite = db.Column(db.Boolean, nullable=True)
user = db.relationship("User", back_populates="other_projects")
other_project = db.relationship("Project", back_populates="users")
3 changes: 2 additions & 1 deletion app/routes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
ProjectDatabaseRetrievePasswordView, ProjectDatabaseAdminRetrievePasswordView, DatabaseStatsView, AppDataSummaryView,
ProjectDatabaseRetrievePasswordView, ProjectDatabaseAdminRetrievePasswordView, DatabaseStatsView, AppDataSummaryView,
UserAdminUpdateView, AppRevertView, ProjectGetCostsView, TransactionRecordView, CreditTransactionRecordView, CreditPurchaseTransactionRecordView, BillingInvoiceView, BillingInvoiceNotificationView,
SystemStatusView, CreditDetailView, ProjectUsersView, ProjectUsersTransferView)
SystemStatusView, CreditDetailView, ProjectUsersView, ProjectUsersTransferView, ProjectUsersHandleInviteView)
from app.controllers.billing_invoice import BillingInvoiceDetailView
from app.controllers.receipts import BillingReceiptsDetailView, BillingReceiptsView
from app.controllers.transactions import TransactionRecordDetailView
Expand Down Expand Up @@ -187,5 +187,6 @@
# Project Users
api.add_resource(ProjectUsersView, '/projects/<string:project_id>/users')
api.add_resource(ProjectUsersTransferView, '/projects/<string:project_id>/users/transfer')
api.add_resource(ProjectUsersHandleInviteView, '/projects/<string:project_id>/users/handle_invite')
# system status
api.add_resource(SystemStatusView, '/system_status')
1 change: 1 addition & 0 deletions app/schemas/project_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ class ProjectUserSchema(Schema):
])
project_id = fields.String()
user = fields.Nested(UserRoleSchema, many=False, dump_only=True)
accepted_collaboration_invite = fields.Boolean()
29 changes: 29 additions & 0 deletions migrations/versions/aeef37c779c1_.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""empty message

Revision ID: aeef37c779c1
Revises: 6436b82e452b
Create Date: 2022-11-24 17:32:54.009985

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'aeef37c779c1'
down_revision = '6436b82e452b'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('project_user', sa.Column('accepted_collaboration_invite', sa.Boolean(), nullable=True))
op.execute('''UPDATE "project_user" SET accepted_collaboration_invite = false WHERE role!='owner'; ''')
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('project_user', 'accepted_collaboration_invite')
# ### end Alembic commands ###