blob: 5859cf05689b3d2c965421ee28319a028eb92a7b [file] [log] [blame]
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is govered by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""Protocol buffers for Monorail users."""
from protorpc import messages
class ActionLimit(messages.Message):
"""In-memory business object for action rate limiting.
We will keep track of the number of actions
of various types by individual users and limit each user's ability
to perform a large number of those actions. E.g., no one user can
create too many new projects.
Our application code checks three kinds of action limits:
1. A soft limit on the number of actions in a period of time.
If this soft limit is exceeded, the user will need to solve a CAPTCHA.
2. A hard limit on the number of actions in a period of time.
if this hard limit is exceeded, the requested actions will fail.
3. A lifetime limit. The user cannot perform this type of action more
than this many times, ever. We can adjust the lifetime limit
for individual users who contact us.
The numeric values for the actual limits are coded as constants in our
application. Only the lifetime limit is stored in this PB, and then only
if it differs from the default.
"""
# Number of times that the user has performed this type of action recently.
recent_count = messages.IntegerField(1, required=True, default=0)
# Time of most recent counter reset in seconds.
# If (Now - reset_timestamp) > threshold, recent_count may be zeroed.
reset_timestamp = messages.IntegerField(2, required=True, default=0)
# Number of times that the user has performed this type of action ever.
lifetime_count = messages.IntegerField(3, required=True, default=0)
# This field is only present for users who have contacted us and
# asked us to increase their lifetime limit. When present, this value
# overrides the application's built-in default limit.
lifetime_limit = messages.IntegerField(4, default=0)
# This field is only present for users who have contacted us and
# asked us to increase their period limit. When present, this value
# overrides the application's built-in default limit.
period_soft_limit = messages.IntegerField(5, default=0)
period_hard_limit = messages.IntegerField(6, default=0)
class IssueUpdateNav(messages.Enum):
"""Pref for where a project member goes after an issue update."""
UP_TO_LIST = 0 # Back to issue list or grid view.
STAY_SAME_ISSUE = 1 # Show the same issue with the update.
NEXT_IN_LIST = 2 # Triage mode: go to next issue, if any.
class User(messages.Message):
"""In-memory busines object for representing users."""
# Is this user a site administer?
is_site_admin = messages.BooleanField(4, required=True, default=False)
# User notification preferences. These preferences describe when
# a user is sent a email notification after an issue has changed.
# The user is notified if either of the following is true:
# 1. notify_issue_change is True and the user is named in the
# issue's Owner or CC field.
# 2. notify_starred_issue_change is True and the user has starred
# the issue.
notify_issue_change = messages.BooleanField(5, default=True)
notify_starred_issue_change = messages.BooleanField(6, default=True)
# This user has been banned, and this string describes why. All access
# to Monorail pages should be disabled.
banned = messages.StringField(7, default='')
# User action counts and limits.
project_creation_limit = messages.MessageField(ActionLimit, 8)
issue_comment_limit = messages.MessageField(ActionLimit, 9)
issue_attachment_limit = messages.MessageField(ActionLimit, 10)
issue_bulk_edit_limit = messages.MessageField(ActionLimit, 11)
ignore_action_limits = messages.BooleanField(13, default=False)
after_issue_update = messages.EnumField(
IssueUpdateNav, 29, default=IssueUpdateNav.STAY_SAME_ISSUE)
# Should we obfuscate the user's email address and require solving a captcha
# to reveal it entirely? The default value corresponds to requiring users to
# opt into publishing their identities, but our code ensures that the
# opposite takes place for Gmail accounts.
obscure_email = messages.BooleanField(26, default=True)
# The email address chosen by the user to reveal on the site.
email = messages.StringField(27)
# The user has seen these cue cards and dismissed them.
dismissed_cues = messages.StringField(32, repeated=True)
# Sticky state for show/hide widget on people details page.
keep_people_perms_open = messages.BooleanField(33, default=False)
deleted = messages.BooleanField(39, default=False)
deleted_timestamp = messages.IntegerField(40, default=0)
preview_on_hover = messages.BooleanField(42, default=True)
flag_spam_limit = messages.MessageField(ActionLimit, 43)
api_request_limit = messages.MessageField(ActionLimit, 44)
def MakeUser():
"""Create and return a new user record in RAM."""
user = User()
user.project_creation_limit = ActionLimit()
user.issue_comment_limit = ActionLimit()
user.issue_attachment_limit = ActionLimit()
user.issue_bulk_edit_limit = ActionLimit()
user.flag_spam_limit = ActionLimit()
user.api_request_limit = ActionLimit()
return user