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

WIP: Make it possible to have profile be public #4545

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
11 changes: 5 additions & 6 deletions app/backend/src/couchers/jobs/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import logging
from datetime import date, timedelta
from math import sqrt
from types import SimpleNamespace
from typing import List

import requests
Expand Down Expand Up @@ -59,7 +58,7 @@
from couchers.servicers.requests import host_request_to_pb
from couchers.sql import couchers_select as select
from couchers.tasks import enforce_community_memberships as tasks_enforce_community_memberships
from couchers.utils import now
from couchers.utils import make_user_context, now
from proto import notification_data_pb2
from proto.internal import jobs_pb2, verification_pb2

Expand Down Expand Up @@ -215,7 +214,7 @@ def format_title(message, group_chat, count_unseen):
author=user_model_to_pb(
message.author,
session,
SimpleNamespace(user_id=user.id),
make_user_context(user_id=user.id),
),
message=format_title(message, group_chat, count_unseen),
text=message.text,
Expand Down Expand Up @@ -269,7 +268,7 @@ def send_request_notifications(payload):
user.last_notified_request_message_id = max(user.last_notified_request_message_id, max_message_id)
session.flush()

context = SimpleNamespace(user_id=user.id)
context = make_user_context(user_id=user.id)
notify(
user_id=user.id,
topic_action="host_request:missed_messages",
Expand All @@ -285,7 +284,7 @@ def send_request_notifications(payload):
user.last_notified_request_message_id = max(user.last_notified_request_message_id, max_message_id)
session.flush()

context = SimpleNamespace(user_id=user.id)
context = make_user_context(user_id=user.id)
notify(
user_id=user.id,
topic_action="host_request:missed_messages",
Expand Down Expand Up @@ -431,7 +430,7 @@ def send_reference_reminders(payload):
# checked in sql
assert user.is_visible
if not are_blocked(session, user.id, other_user.id):
context = SimpleNamespace(user_id=user.id)
context = make_user_context(user_id=user.id)
notify(
user_id=user.id,
topic_action="reference:reminder_surfed" if surfed else "reference:reminder_hosted",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""Add profile public visibility

Revision ID: 8f056dd44a58
Revises: 461446320dfa
Create Date: 2024-07-13 17:08:33.761879

"""

import sqlalchemy as sa
from alembic import op

# revision identifiers, used by Alembic.
revision = "8f056dd44a58"
down_revision = "461446320dfa"
branch_labels = None
depends_on = None


def upgrade():
profilepublicvisibility = sa.Enum("nothing", "map_only", "limited", "most", "full", name="profilepublicvisibility")
profilepublicvisibility.create(op.get_bind(), checkfirst=True)
op.add_column(
"users",
sa.Column(
"public_visibility",
profilepublicvisibility,
server_default="limited",
nullable=False,
),
)
op.add_column(
"users",
sa.Column("needs_to_pick_public_visibility", sa.Boolean(), server_default=sa.text("false"), nullable=False),
)


def downgrade():
op.drop_column("users", "needs_to_pick_public_visibility")
op.drop_column("users", "public_visibility")
16 changes: 16 additions & 0 deletions app/backend/src/couchers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,19 @@ class ParkingDetails(enum.Enum):
paid_offsite = enum.auto()


class ProfilePublicVisibility(enum.Enum):
# no public info
nothing = enum.auto()
# only show on map, unclickable
map_only = enum.auto()
# name, gender, location, hosting/meetup status, badges, number of references, and signup time
limited = enum.auto()
# full about me except additional info (hide my home)
most = enum.auto()
# all but references
full = enum.auto()


class TimezoneArea(Base):
__tablename__ = "timezone_areas"
id = Column(BigInteger, primary_key=True)
Expand Down Expand Up @@ -146,6 +159,9 @@ class User(Base):
joined = Column(DateTime(timezone=True), nullable=False, server_default=func.now())
last_active = Column(DateTime(timezone=True), nullable=False, server_default=func.now())

public_visibility = Column(Enum(ProfilePublicVisibility), nullable=False, server_default="limited")
needs_to_pick_public_visibility = Column(Boolean, nullable=False, server_default=text("false"))

# id of the last message that they received a notification about
last_notified_message_id = Column(BigInteger, nullable=False, default=0)
# same as above for host requests
Expand Down
5 changes: 4 additions & 1 deletion app/backend/src/couchers/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from couchers.servicers.media import Media, get_media_auth_interceptor
from couchers.servicers.notifications import Notifications
from couchers.servicers.pages import Pages
from couchers.servicers.public import Public
from couchers.servicers.references import References
from couchers.servicers.reporting import Reporting
from couchers.servicers.requests import Requests
Expand All @@ -47,6 +48,7 @@
media_pb2_grpc,
notifications_pb2_grpc,
pages_pb2_grpc,
public_pb2_grpc,
references_pb2_grpc,
reporting_pb2_grpc,
requests_pb2_grpc,
Expand All @@ -69,7 +71,6 @@ def create_main_server(port):
server.add_insecure_port(f"[::]:{port}")

account_pb2_grpc.add_AccountServicer_to_server(Account(), server)
iris_pb2_grpc.add_IrisServicer_to_server(Iris(), server)
admin_pb2_grpc.add_AdminServicer_to_server(Admin(), server)
api_pb2_grpc.add_APIServicer_to_server(API(), server)
auth_pb2_grpc.add_AuthServicer_to_server(Auth(), server)
Expand All @@ -82,9 +83,11 @@ def create_main_server(port):
events_pb2_grpc.add_EventsServicer_to_server(Events(), server)
gis_pb2_grpc.add_GISServicer_to_server(GIS(), server)
groups_pb2_grpc.add_GroupsServicer_to_server(Groups(), server)
iris_pb2_grpc.add_IrisServicer_to_server(Iris(), server)
jail_pb2_grpc.add_JailServicer_to_server(Jail(), server)
notifications_pb2_grpc.add_NotificationsServicer_to_server(Notifications(), server)
pages_pb2_grpc.add_PagesServicer_to_server(Pages(), server)
public_pb2_grpc.add_PublicServicer_to_server(Public(), server)
references_pb2_grpc.add_ReferencesServicer_to_server(References(), server)
reporting_pb2_grpc.add_ReportingServicer_to_server(Reporting(), server)
requests_pb2_grpc.add_RequestsServicer_to_server(Requests(), server)
Expand Down
26 changes: 26 additions & 0 deletions app/backend/src/couchers/servicers/account.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
AccountDeletionToken,
ContributeOption,
ContributorForm,
ProfilePublicVisibility,
StrongVerificationAttempt,
StrongVerificationAttemptStatus,
StrongVerificationCallbackEvent,
Expand Down Expand Up @@ -59,6 +60,24 @@
ContributeOption.no: auth_pb2.CONTRIBUTE_OPTION_NO,
}

profilepublicitysetting2sql = {
account_pb2.PROFILE_PUBLIC_VISIBILITY_UNKNOWN: None,
account_pb2.PROFILE_PUBLIC_VISIBILITY_NOTHING: ProfilePublicVisibility.nothing,
account_pb2.PROFILE_PUBLIC_VISIBILITY_MAP_ONLY: ProfilePublicVisibility.map_only,
account_pb2.PROFILE_PUBLIC_VISIBILITY_LIMITED: ProfilePublicVisibility.limited,
account_pb2.PROFILE_PUBLIC_VISIBILITY_MOST: ProfilePublicVisibility.most,
account_pb2.PROFILE_PUBLIC_VISIBILITY_FULL: ProfilePublicVisibility.full,
}

profilepublicitysetting2api = {
None: account_pb2.PROFILE_PUBLIC_VISIBILITY_UNKNOWN,
ProfilePublicVisibility.nothing: account_pb2.PROFILE_PUBLIC_VISIBILITY_NOTHING,
ProfilePublicVisibility.map_only: account_pb2.PROFILE_PUBLIC_VISIBILITY_MAP_ONLY,
ProfilePublicVisibility.limited: account_pb2.PROFILE_PUBLIC_VISIBILITY_LIMITED,
ProfilePublicVisibility.most: account_pb2.PROFILE_PUBLIC_VISIBILITY_MOST,
ProfilePublicVisibility.full: account_pb2.PROFILE_PUBLIC_VISIBILITY_FULL,
}


def get_strong_verification_fields(session, db_user):
out = dict(
Expand Down Expand Up @@ -122,6 +141,7 @@ def GetAccountInfo(self, request, context):
phone_verified=user.phone_is_verified,
profile_complete=user.has_completed_profile,
timezone=user.timezone,
profile_public_visibility=profilepublicitysetting2api[user.public_visibility],
**get_strong_verification_fields(session, user),
)

Expand Down Expand Up @@ -457,6 +477,12 @@ def DeleteAccount(self, request, context):

return empty_pb2.Empty()

def SetProfilePublicVisibility(self, request, context):
with session_scope() as session:
user = session.execute(select(User).where(User.id == context.user_id)).scalar_one()
user.public_visibility = profilepublicitysetting2sql[request.profile_public_visibility]
return empty_pb2.Empty()


class Iris(iris_pb2_grpc.IrisServicer):
def Webhook(self, request, context):
Expand Down
1 change: 1 addition & 0 deletions app/backend/src/couchers/servicers/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,7 @@ def InitiateMediaUpload(self, request, context):


def user_model_to_pb(db_user, session, context):
# note that this function is sometimes called by a logged out user, in which case context comes from make_logged_out_context
num_references = session.execute(
select(func.count())
.select_from(Reference)
Expand Down
5 changes: 2 additions & 3 deletions app/backend/src/couchers/servicers/conversations.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from datetime import timedelta
from types import SimpleNamespace

import grpc
from google.protobuf import empty_pb2
Expand All @@ -15,7 +14,7 @@
from couchers.servicers.api import user_model_to_pb
from couchers.servicers.blocking import are_blocked
from couchers.sql import couchers_select as select
from couchers.utils import Timestamp_from_datetime, now
from couchers.utils import Timestamp_from_datetime, make_user_context, now
from proto import conversations_pb2, conversations_pb2_grpc, notification_data_pb2
from proto.internal import jobs_pb2

Expand Down Expand Up @@ -167,7 +166,7 @@ def generate_message_notifications(payload: jobs_pb2.GenerateMessageNotification
author=user_model_to_pb(
message.author,
session,
SimpleNamespace(user_id=subscription.user_id),
make_user_context(user_id=subscription.user_id),
),
message=msg,
text=message.text,
Expand Down
12 changes: 6 additions & 6 deletions app/backend/src/couchers/servicers/events.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
from datetime import timedelta
from types import SimpleNamespace

import grpc
from google.protobuf import empty_pb2
Expand Down Expand Up @@ -35,6 +34,7 @@
Timestamp_from_datetime,
create_coordinate,
dt_from_millis,
make_user_context,
millis_from_dt,
now,
to_aware_datetime,
Expand Down Expand Up @@ -264,7 +264,7 @@ def generate_event_create_notifications(payload: jobs_pb2.GenerateEventCreateNot
for user in users:
if are_blocked(session, user.id, creator.id):
continue
context = SimpleNamespace(user_id=user.id)
context = make_user_context(user_id=user.id)
notify(
user_id=user.id,
topic_action="event:create_approved" if payload.approved else "event:create_any",
Expand All @@ -291,7 +291,7 @@ def generate_event_update_notifications(payload: jobs_pb2.GenerateEventUpdateNot
logger.info(user_id)
if are_blocked(session, user_id, updating_user.id):
continue
context = SimpleNamespace(user_id=user_id)
context = make_user_context(user_id=user_id)
notify(
user_id=user_id,
topic_action="event:update",
Expand Down Expand Up @@ -319,7 +319,7 @@ def generate_event_cancel_notifications(payload: jobs_pb2.GenerateEventCancelNot
logger.info(user_id)
if are_blocked(session, user_id, cancelling_user.id):
continue
context = SimpleNamespace(user_id=user_id)
context = make_user_context(user_id=user_id)
notify(
user_id=user_id,
topic_action="event:cancel",
Expand All @@ -342,7 +342,7 @@ def generate_event_delete_notifications(payload: jobs_pb2.GenerateEventDeleteNot

for user_id in set(subscribed_user_ids + attending_user_ids):
logger.info(user_id)
context = SimpleNamespace(user_id=user_id)
context = make_user_context(user_id=user_id)
notify(
user_id=user_id,
topic_action="event:delete",
Expand Down Expand Up @@ -1117,7 +1117,7 @@ def InviteEventOrganizer(self, request, context):
)
session.flush()

other_user_context = SimpleNamespace(user_id=request.user_id)
other_user_context = make_user_context(user_id=request.user_id)

notify(
user_id=request.user_id,
Expand Down
Loading