def getVisibleUsers(users, request): """ Search users Return a list of persons of the system, optionaly filtered using the available modifiers. The objects returned by this endpoint are intended for user listing and searching, so only username and displayName attributes of a person are returned. If you need the full profile of a user, use the `GET` endpoint of the `User` resource. """ query = {} search_params = searchParams(request) filter_fields = ["username", "displayName", "objectType", 'subscribedTo'] if asbool(search_params.get('twitter_enabled', False)): filter_fields.append("twitterUsername") found_users = users.search(query, show_fields=filter_fields, sort_by_field="username", flatten=0, **search_params) # Filter user results. User filtered_users = [user for user in found_users if request.actor.is_allowed_to_see(user)] handler = JSONResourceRoot(request, flatten(filtered_users, squash=['subscribedTo']), remaining=found_users.remaining) return handler.buildResponse()
def rebuildSubscriptions(context, request): """ Rebuild context subscriptions Performs sanity checks on existing subscriptions """ existing_contexts = {} contexts = request.db.contexts.dump() for context in contexts: context.updateUsersSubscriptions(force_update=True) context.updateContextActivities(force_update=True) existing_contexts[context['hash']] = context users = request.db.users.search({'subscribedTo.0': {'$exists': True}}) for user in users: for subscription in user.get('subscribedTo', []): if subscription['hash'] not in existing_contexts: fake_deleted_context = Context.from_object(request, subscription) user.removeSubscription(fake_deleted_context) else: subscription.pop('vetos', None) subscription.pop('grants', None) user.save() handler = JSONResourceRoot(request, []) return handler.buildResponse()
def view_user_tokens(user, request): """ Delete all platform tokens """ tokens = user.get_tokens() handler = JSONResourceRoot(request, tokens) return handler.buildResponse()
def rebuildTokens(context, request): """ Rebuild tokens Move any user that has old style tokens to the new tokens collection """ # Find all users with tokens users_with_tokens = request.db.db.users.find({'$or': [{'iosDevices.0': {'$exists': True}}, {'androidDevices.0': {'$exists': True}}]}) platforms = [ ('ios', 'iosDevices'), ('android', 'androidDevices') ] for user in users_with_tokens: for platform, oldfield in platforms: tokens = user.get(oldfield, []) for token in tokens: newtoken = Token.from_object(request, { 'platform': platform, 'token': token, 'objectId': 'token', '_owner': user['username'], '_creator': user['username'], }) newtoken.setDates() newtoken.insert() # Clean old token fields request.db.db.users.update({}, {'$unset': {'iosDevices': '', 'androidDevices': ''}}, multi=True) handler = JSONResourceRoot(request, []) return handler.buildResponse()
def getContexts(contexts, request): """ Get all contexts """ found_contexts = contexts.search({}, flatten=1, **searchParams(request)) handler = JSONResourceRoot(request, found_contexts) return handler.buildResponse()
def getSecurity(security, request): """ Get security settings Expose the current MAX security roles and its members """ handler = JSONResourceRoot(request, security.flatten()) return handler.buildResponse()
def getGlobalComments(comments, request): """ Get global comments """ is_head = request.method == 'HEAD' activities = request.db.activity.search({'verb': 'comment'}, flatten=1, count=is_head, **searchParams(request)) handler = JSONResourceRoot(request, activities, stats=is_head) return handler.buildResponse()
def getMessages(message, request): """ Get all messages """ is_head = request.method == 'HEAD' activities = request.db.messages.search({'verb': 'post'}, flatten=1, count=is_head, **searchParams(request)) handler = JSONResourceRoot(request, activities, stats=is_head) return handler.buildResponse()
def view_platform_user_tokens(user, request): """ Get all user tokens for platform """ platform = request.matchdict['platform'] tokens = user.get_tokens(platform) handler = JSONResourceRoot(request, tokens) return handler.buildResponse()
def getGlobalActivities(context, request): """ Get global activities Returns all post activities generated in the system by anyone. """ is_head = request.method == 'HEAD' activities = request.db.activity.search({'verb': 'post'}, flatten=1, count=is_head, **searchParams(request)) handler = JSONResourceRoot(request, activities, stats=is_head) return handler.buildResponse()
def getUserTimeline(user, request): """ Get user timeline """ query = timelineQuery(user) activities = sorted_query(request, request.db.activity, query, flatten=1) handler = JSONResourceRoot(request, activities) return handler.buildResponse()
def clearContextTags(context, request): """ Delete all context tags """ context['tags'] = [] context.save() context.updateContextActivities(force_update=True) context.updateUsersSubscriptions(force_update=True) handler = JSONResourceRoot(request, []) return handler.buildResponse()
def getPublicContexts(contexts, request): """ Get all public contexts Returns a list of all public subscribable contexts """ found_contexts = contexts.search({'permissions.subscribe': 'public'}, **searchParams(request)) handler = JSONResourceRoot(request, flatten(found_contexts, squash=['owner', 'creator', 'published'])) return handler.buildResponse()
def getConversationMessages(conversation, request): """ Get all messages from a conversation """ query = {'contexts.id': str(conversation['_id'])} # Sorting by _id, as id is indeed the same as published messages = request.db.messages.search(query, sort_direction=DESCENDING, sort_by_field="_id", keep_private_fields=False, **searchParams(request)) inverted = flatten(messages, reverse=True) handler = JSONResourceRoot(request, inverted, remaining=messages.remaining) return handler.buildResponse()
def getContextActivities(context, request): """ Get context activities Returns all the activities posted on a context :rest hash The hash of the context url where the activties where posted """ url = context['url'] # regex query to find all contexts within url escaped = re.escape(url) url_regex = {'$regex': '^%s' % escaped} # Search posts associated with contexts that have this context's # url as prefix a.k.a "recursive contexts" query = {} # Search query.update({'verb': 'post'}) # 'post' activities query.update({'contexts.url': url_regex}) # equal or child of url # Check if we have permission to unrestrictely view activities from recursive contexts: can_list_activities_unsubscribed = isinstance(request.has_permission(list_activities_unsubscribed), ACLAllowed) # If we can't view unsubcribed contexts, filter from which contexts we get activities by listing # the contexts that the user has read permission on his subscriptions. Public contexts are only searched here # because if we can list_activities_unsubscribed, main query already includes them. readable_contexts_urls = [] if not can_list_activities_unsubscribed: # Include all urls from subscriptions to contexts whose url # is a child of of main context url, for subscription in request.actor['subscribedTo']: if 'read' in subscription.get('permissions', []) \ and subscription['objectType'] == 'context'\ and subscription['url'].startswith(url): readable_contexts_urls.append(subscription['url']) # We'll include also all contexts that are public whitin the url public_query = {'permissions.read': 'public', 'url': url_regex} for result in request.db.contexts.search(public_query, show_fields=['url']): readable_contexts_urls.append(result['url']) # if any url collected, include it on the query if readable_contexts_urls: query['contexts.url'] = {'$in': readable_contexts_urls} activities = [] # Execute search only if we have read permision on some contexts or we have usubscribed access to activities. if readable_contexts_urls or can_list_activities_unsubscribed: activities = sorted_query(request, request.db.activity, query, flatten=1) is_head = request.method == 'HEAD' handler = JSONResourceRoot(request, activities, stats=is_head) return handler.buildResponse()
def getActivityComments(activity, request): """ Get activity comments Return the comments for an activity. """ replies = activity.get('replies', {}) items = replies result = flatten(items, keep_private_fields=False) handler = JSONResourceRoot(request, result) return handler.buildResponse()
def rebuildKeywords(context, request): """ Rebuild keywords of all activities """ activities = request.db.activity.search({'verb': 'post'}) for activity in activities: activity['object'].setKeywords() activity.setKeywords() activity.save() handler = JSONResourceRoot(request, []) return handler.buildResponse()
def getUsersRoles(security, request): """ Get users roles """ users = {} for role in ALLOWED_ROLES: for username in security['roles'].get(role, []): users.setdefault(username, {}) users[username][role] = True user_roles = [{'username': username, 'roles': [{'name': role, 'active': user_roles.get(role, False)} for role in ALLOWED_ROLES]} for username, user_roles in users.items()] handler = JSONResourceRoot(request, user_roles) return handler.buildResponse()
def getUserActivities(user, request): """ Get user activities Returns all post visible activities generated by a user in his timeline or contexts. Include only contexts shared between user and creator if different """ can_list_activities_unsubscribed = isinstance(request.has_permission(list_activities_unsubscribed), ACLAllowed) query = visible_user_activities_query(user, request, filter_non_shared=not can_list_activities_unsubscribed) is_head = request.method == 'HEAD' activities = request.db.activity.search(query, keep_private_fields=False, flatten=1, count=is_head, **searchParams(request)) handler = JSONResourceRoot(request, activities, stats=is_head) return handler.buildResponse()
def rebuildUser(context, request): """ Rebuild users Sets sensible defaults and perform consistency checks. Checks that owner of the object must be the same as the user object """ users = request.db.users.dump() for user in users: if user['_owner'] != user['username']: user['_owner'] = user['username'] user.save() handler = JSONResourceRoot(request, []) return handler.buildResponse()
def add_user_to_role(security, request): """ Grants a role to a user """ role = request.matchdict['role'] user = request.matchdict['user'] if role not in ALLOWED_ROLES: raise ValidationError('Role "{}" is not a valid role'.format(role)) added = security.add_user_to_role(user, role) status_code = 201 if added else 200 if added: security.save() handler = JSONResourceRoot(request, security.flatten()['roles'][role], status_code=status_code) return handler.buildResponse()
def getContextComments(context, request): """ Get context activities comments """ is_head = request.method == 'HEAD' query = { 'verb': 'comment', 'object.inReplyTo.contexts': { '$in': [context['hash']] } } comments = request.db.activity.search(query, flatten=1, count=is_head, **searchParams(request)) handler = JSONResourceRoot(request, comments, stats=is_head) return handler.buildResponse()
def getPushTokensForConversation(tokens, request): """ Return conversation tokens """ cid = request.matchdict['id'] query = {'talkingIn.id': cid} user_tokens = [] users = request.db.users.search(query, show_fields=["username"], sort_by_field="username", flatten=1) usernames = [user['username'] for user in users] if usernames: user_tokens = tokens.search({'_owner': {'$in': usernames}}, **searchParams(request)) handler = JSONResourceRoot(request, formatted_tokens(user_tokens)) return handler.buildResponse()
def rebuildDates(context, request): """ Rebuild dates of activities Now currently sets the lastComment id field """ activities = request.db.activity.search({'verb': 'post'}) for activity in activities: # Remove ancient commented field if 'commented' in activity: del activity['commented'] if activity.get('replies', []): activity['lastComment'] = ObjectId(activity['replies'][-1]['id']) activity.save() handler = JSONResourceRoot(request, []) return handler.buildResponse()
def getConversations(conversations, request): """ Get user conversations """ # List subscribed conversations, and use it to make the query # This way we can filter 2-people conversations that have been archived conversations_search = request.actor.getConversations() def conversations_info(): for conversation in conversations_search: yield conversation.getInfo(request.actor['username']) sorted_conversations = sorted(conversations_info(), reverse=True, key=lambda conv: conv['lastMessage']['published']) handler = JSONResourceRoot(request, sorted_conversations) return handler.buildResponse()
def getPushTokensForConversation(tokens, request): """ Return conversation tokens """ cid = request.matchdict['id'] query = {'talkingIn.id': cid} user_tokens = [] users = request.db.users.search(query, show_fields=["username"], sort_by_field="username", flatten=1) usernames = [user['username'] for user in users] if usernames: # Modifico el limit a -1 para que me devuelva todos los usuarios de la mongo no solo el limite de 10 # user_tokens = tokens.search({'_owner': {'$in': usernames}}, **searchParams(request)) user_tokens = tokens.search({'_owner': {'$in': usernames}}, {'limit': -1}) handler = JSONResourceRoot(request, formatted_tokens(user_tokens)) return handler.buildResponse()
def getPushTokensForContext(tokens, request): """ Return context tokens """ cid = request.matchdict['hash'] contexts = MADMaxCollection(request, 'contexts', query_key='hash') ctxt = contexts[cid] user_tokens = [] users = ctxt.subscribedUsers() usernames = [user['username'] for user in users] if usernames: user_tokens = tokens.search({'_owner': {'$in': usernames}}, **searchParams(request)) handler = JSONResourceRoot(request, formatted_tokens(user_tokens)) return handler.buildResponse()
def updateContextTags(context, request): """ Add context tags """ tags = request.decoded_payload # Validate tags is a list of strings valid_tags = isinstance(tags, list) if valid_tags: valid_tags = False not in [isinstance(tag, (str, unicode)) for tag in tags] if not valid_tags: raise ValidationError("Sorry, We're expecting a list of strings...") context['tags'].extend(tags) context['tags'] = list(set(context['tags'])) context.save() context.updateContextActivities(force_update=True) context.updateUsersSubscriptions(force_update=True) handler = JSONResourceRoot(request, context['tags']) return handler.buildResponse()
def getUserSubscriptions(user, request): """ Get all user subscriptions """ subscriptions = user.get('subscribedTo', []) search_params = searchParams(request) tags = set(search_params.pop('tags', [])) # XXX Whhen refactoring subscriptions storage to a different collection # Change this for a search on subscriptions collection if tags: filtered_subscriptions = [] for subscription in subscriptions: if tags.intersection(set(subscription.get('tags', []))) == tags: filtered_subscriptions.append(subscription) subscriptions = filtered_subscriptions handler = JSONResourceRoot(request, subscriptions) return handler.buildResponse()
def getContextSubscriptions(context, request): """ Get all context subscriptions """ found_users = request.db.users.search({"subscribedTo.hash": context['hash']}, flatten=0, show_fields=["username", "subscribedTo"], **searchParams(request)) def format_subscriptions(): for user in found_users: user_subscription = user.getSubscription(context) subscription = { 'username': user['username'], 'permissions': user_subscription['permissions'], 'vetos': user_subscription.get('vetos', []), 'grants': user_subscription.get('grants', []), 'hash': user_subscription['hash'] } yield subscription handler = JSONResourceRoot(request, format_subscriptions()) return handler.buildResponse()