def parse_query(project, query, user): # TODO(dcramer): handle query being wrapped in quotes tokens = tokenize_query(query) results = {'tags': {}, 'query': []} for key, token_list in tokens.iteritems(): for value in token_list: if key == 'query': results['query'].append(value) elif key == 'is': if value == 'unassigned': results['unassigned'] = True elif value == 'assigned': results['unassigned'] = False else: try: results['status'] = STATUS_CHOICES[value] except KeyError: pass elif key == 'assigned': if value == 'me': results['assigned_to'] = user else: try: results['assigned_to'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['assigned_to'] = User(id=0) elif key == 'bookmarks': if value == 'me': results['bookmarked_by'] = user else: try: results['bookmarked_by'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['bookmarked_by'] = User(id=0) elif key == 'first-release': results['first_release'] = value elif key == 'release': results['tags']['sentry:release'] = value elif key == 'user': if ':' in value: comp, value = value.split(':', 1) else: comp = 'id' results['tags']['sentry:user'] = get_user_tag( project, comp, value) elif key.startswith('user.'): results['tags']['sentry:user'] = get_user_tag( project, key.split('.', 1)[1], value) else: results['tags'][key] = value results['query'] = ' '.join(results['query']) return results
def from_actor_identifier(cls, actor_identifier): """ Returns an Actor tuple corresponding to a User or Team associated with the given identifier. Forms `actor_identifier` can take: 1231 -> look up User by id "1231" -> look up User by id "user:1231" -> look up User by id "team:1231" -> look up Team by id "maiseythedog" -> look up User by username "*****@*****.**" -> look up User by primary email """ # If we have an integer, fall back to assuming it's a User if isinstance(actor_identifier, six.integer_types): return Actor(actor_identifier, User) # If the actor_identifier is a simple integer as a string, # we're also a User if actor_identifier.isdigit(): return Actor(int(actor_identifier), User) if actor_identifier.startswith("user:"******"team:"): return cls(int(actor_identifier[5:]), Team) try: return Actor(find_users(actor_identifier)[0].id, User) except IndexError: raise serializers.ValidationError( "Unable to resolve actor identifier")
def _handle_unknown_identity(self, identity): """ Flow is activated upon a user logging in to where an AuthIdentity is not present. The flow will attempt to answer the following: - Is there an existing user with the same email address? Should they be merged? - Is there an existing user (via authentication) that shoudl be merged? - Should I create a new user based on this identity? """ request = self.request op = request.POST.get('op') if not request.user.is_authenticated(): try: existing_user = find_users(identity['email'])[0] except IndexError: existing_user = None login_form = self._get_login_form(existing_user) if op == 'confirm' and request.user.is_authenticated(): auth_identity = self._handle_attach_identity(identity) elif op == 'newuser': auth_identity = self._handle_new_user(identity) elif op == 'login' and not request.user.is_authenticated(): # confirm authentication, login op = None if login_form.is_valid(): login(request, login_form.get_user()) request.session.pop('needs_captcha', None) else: request.session['needs_captcha'] = 1 else: op = None if not op: if request.user.is_authenticated(): return self.respond('sentry/auth-confirm-link.html', { 'identity': identity, 'existing_user': request.user, }) return self.respond( 'sentry/auth-confirm-identity.html', { 'existing_user': existing_user, 'identity': identity, 'login_form': login_form, }) user = auth_identity.user user.backend = settings.AUTHENTICATION_BACKENDS[0] login(self.request, user) self.clear_session() return HttpResponseRedirect(get_login_redirect(self.request))
def _handle_unknown_identity(self, identity): """ Flow is activated upon a user logging in to where an AuthIdentity is not present. The flow will attempt to answer the following: - Is there an existing user with the same email address? Should they be merged? - Is there an existing user (via authentication) that shoudl be merged? - Should I create a new user based on this identity? """ request = self.request op = request.POST.get('op') if not request.user.is_authenticated(): try: existing_user = find_users(identity['email'])[0] except IndexError: existing_user = None login_form = self._get_login_form(existing_user) if op == 'confirm' and request.user.is_authenticated(): auth_identity = self._handle_attach_identity(identity) elif op == 'newuser': auth_identity = self._handle_new_user(identity) elif op == 'login' and not request.user.is_authenticated(): # confirm authentication, login op = None if login_form.is_valid(): login(request, login_form.get_user()) request.session.pop('needs_captcha', None) else: request.session['needs_captcha'] = 1 else: op = None if not op: if request.user.is_authenticated(): return self.respond('sentry/auth-confirm-link.html', { 'identity': identity, 'existing_user': request.user, }) return self.respond('sentry/auth-confirm-identity.html', { 'existing_user': existing_user, 'identity': identity, 'login_form': login_form, }) user = auth_identity.user user.backend = settings.AUTHENTICATION_BACKENDS[0] login(self.request, user) self.clear_session() return HttpResponseRedirect(get_login_redirect(self.request))
def parse_query(query, user): # TODO(dcramer): make this better tokens = query.split(' ') results = {'tags': {}, 'query': []} tokens_iter = iter(tokens) for token in tokens_iter: if ':' not in token: results['query'].append(token) continue key, value = token.split(':', 1) if not value: results['query'].append(token) continue if value[0] == '"': nvalue = value while nvalue[-1] != '"': try: nvalue = tokens_iter.next() except StopIteration: break value = '%s %s' % (value, nvalue) if value.endswith('"'): value = value[1:-1] else: value = value[1:] if key == 'is': try: results['status'] = STATUS_CHOICES[value] except KeyError: pass elif key == 'assigned': if value == 'me': results['assigned_to'] = user else: try: results['assigned_to'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['assigned_to'] = User(id=0) elif key == 'first-release': results['first_release'] = value elif key == 'release': results['tags']['sentry:release'] = value elif key == 'user': results['tags']['sentry:user'] = value else: results['tags'][key] = value results['query'] = ' '.join(results['query']) return results
def parse_user_value(value, user): if value == 'me': return user try: return find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered return User(id=0)
def clean_user(self): value = (self.cleaned_data.get('user') or '').strip() if not value: return users = find_users(value, with_valid_password=False) if not users: raise forms.ValidationError(_("We were unable to find a matching user.")) if len(users) > 1: raise forms.ValidationError(_("Multiple accounts were found matching this email address.")) return users[0]
def clean_user(self): value = self.cleaned_data.get('user') if value: users = find_users(value) if not users: raise forms.ValidationError(_("We were unable to find a matching user.")) if len(users) > 1: raise forms.ValidationError(_("Multiple accounts were found matching this email address.")) return users[0] return None
def parse_user_value(value, user): if value == "me": return user try: return find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered return User(id=0)
def user_param_to_user(value): from sentry.utils.auth import find_users users = find_users(value) if not users: click.abort('No user matching `{}`'.format(value)) if len(users) > 1: click.abort('Found more than one user matching `{}`'.format(value)) user = users[0] if not user.is_superuser: click.abort('User `{}` does not have superuser status'.format(user.username)) return user
def parse_user_value(value, user): from sentry.models import User # Django 1.9 setup issue from sentry.utils.auth import find_users # Django 1.9 setup issue if value == 'me': return user try: return find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered return User(id=0)
def user_param_to_user(value): from sentry.utils.auth import find_users users = find_users(value) if not users: click.abort('No user matching `{}`'.format(value)) if len(users) > 1: click.abort('Found more than one user matching `{}`'.format(value)) user = users[0] if not user.is_superuser: click.abort('User `{}` does not have superuser status'.format( user.username)) return user
def parse_query(project, query, user): # TODO(dcramer): handle query being wrapped in quotes tokens = tokenize_query(query) results = {'tags': {}, 'query': []} for key, token_list in tokens.iteritems(): for value in token_list: if key == 'query': results['query'].append(value) elif key == 'is': if value == 'unassigned': results['unassigned'] = True elif value == 'assigned': results['unassigned'] = False else: try: results['status'] = STATUS_CHOICES[value] except KeyError: pass elif key == 'assigned': if value == 'me': results['assigned_to'] = user else: try: results['assigned_to'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['assigned_to'] = User(id=0) elif key == 'first-release': results['first_release'] = value elif key == 'release': results['tags']['sentry:release'] = value elif key == 'user': if ':' in value: comp, value = value.split(':', 1) else: comp = 'id' results['tags']['sentry:user'] = get_user_tag( project, comp, value) elif key.startswith('user.'): results['tags']['sentry:user'] = get_user_tag( project, key.split('.', 1)[1], value) else: results['tags'][key] = value results['query'] = ' '.join(results['query']) return results
def user_param_to_user(value): from sentry.utils.auth import find_users users = find_users(value) if not users: raise click.ClickException("No user matching `{}`".format(value)) if len(users) > 1: raise click.ClickException( "Found more than one user matching `{}`".format(value)) user = users[0] if not user.is_superuser: raise click.ClickException( "User `{}` does not have superuser status".format(user.username)) return user
def to_internal_value(self, data): if not data: return None if isinstance(data, six.integer_types) or data.isdigit(): try: return User.objects.get(id=data) except User.DoesNotExist: pass try: return find_users(data)[0] except IndexError: raise serializers.ValidationError("Unable to find user")
def from_native(self, data): if not data: return None if isinstance(data, (int, long)) or data.isdigit(): try: return User.objects.get(id=data) except User.DoesNotExist: pass try: return find_users(data)[0] except IndexError: raise serializers.ValidationError('Unable to find user')
def clean_user(self): value = (self.cleaned_data.get('user') or '').strip() if not value: return users = find_users(value, with_valid_password=False) if not users: raise forms.ValidationError(_("We were unable to find a matching user.")) users = [u for u in users if not u.is_managed] if not users: raise forms.ValidationError(_("The account you are trying to recover is managed and does not support password recovery.")) if len(users) > 1: raise forms.ValidationError(_("Multiple accounts were found matching this email address.")) return users[0]
def handle(self, username, **options): users = find_users(username, with_valid_password=False) if not users: sys.stdout.write("No account found with given username.\n") return for user in users: password_hash, created = LostPasswordHash.objects.get_or_create( user=user) if not password_hash.is_valid(): password_hash.date_added = timezone.now() password_hash.set_hash() password_hash.save() echo("{} ({}) - {}".format(user.username, user.email, password_hash.get_absolute_url()))
def handle(self, username, **options): users = find_users(username, with_valid_password=False) if not users: sys.stdout.write("No account found with given username.\n") return for user in users: password_hash, created = LostPasswordHash.objects.get_or_create( user=user, ) if not password_hash.is_valid(): password_hash.date_added = timezone.now() password_hash.set_hash() password_hash.save() print('{} ({}) - {}'.format( user.username, user.email, password_hash.get_absolute_url(), ))
def from_actor_id(cls, actor_id): # If we have an integer, fall back to assuming it's a User if isinstance(actor_id, six.integer_types): return Actor(actor_id, User) # If the actor_id is a simple integer as a string, # we're also a User if actor_id.isdigit(): return Actor(int(actor_id), User) if actor_id.startswith('user:'******'team:'): return cls(int(actor_id[5:]), Team) try: return Actor(find_users(actor_id)[0].id, User) except IndexError: raise serializers.ValidationError('Unable to resolve actor id')
def clean_user(self): value = (self.cleaned_data.get("user") or "").strip() if not value: return users = find_users(value, with_valid_password=False) if not users: return # If we find more than one user, we likely matched on email address. # We silently bail here as we emailing the 'wrong' person isn't great. # They will have to retry with their username which is guaranteed # to be unique if len(users) > 1: return users = [u for u in users if not u.is_managed] if not users: raise forms.ValidationError( _("The account you are trying to recover is managed and does not support password recovery." )) return users[0]
def clean_user(self): value = (self.cleaned_data.get('user') or '').strip() if not value: return users = find_users(value, with_valid_password=False) if not users: return # If we find more than one user, we likely matched on email address. # We silently bail here as we emailing the 'wrong' person isn't great. # They will have to retry with their username which is guaranteed # to be unique if len(users) > 1: return users = [u for u in users if not u.is_managed] if not users: raise forms.ValidationError( _( "The account you are trying to recover is managed and does not support password recovery." ) ) return users[0]
def _handle_unknown_identity(self, identity): """ Flow is activated upon a user logging in to where an AuthIdentity is not present. The flow will attempt to answer the following: - Is there an existing user with the same email address? Should they be merged? - Is there an existing user (via authentication) that shoudl be merged? - Should I create a new user based on this identity? """ request = self.request op = request.POST.get('op') if not request.user.is_authenticated(): # TODO(dcramer): its possible they have multiple accounts and at # least one is managed (per the check below) try: existing_user = auth.find_users(identity['email'], is_active=True)[0] except IndexError: existing_user = None # If they already have an SSO account and the identity provider says # the email matches we go ahead and let them merge it. This is the # only way to prevent them having duplicate accounts, and because # we trust identity providers, its considered safe. if existing_user and existing_user.is_managed: # we only allow this flow to happen if the existing user has # membership, otherwise we short circuit because it might be # an attempt to hijack membership of another organization has_membership = OrganizationMember.objects.filter( user=existing_user, organization=self.organization, ).exists() if has_membership: if not auth.login(request, existing_user, after_2fa=request.build_absolute_uri(), organization_id=self.organization.id): return HttpResponseRedirect( auth.get_login_redirect(self.request)) # assume they've confirmed they want to attach the identity op = 'confirm' else: # force them to create a new account existing_user = None login_form = self._get_login_form(existing_user) elif request.user.is_managed: # per the above, try to auto merge if the user was originally an # SSO account but is still logged in has_membership = OrganizationMember.objects.filter( user=request.user, organization=self.organization, ).exists() if has_membership: # assume they've confirmed they want to attach the identity op = 'confirm' if op == 'confirm' and request.user.is_authenticated(): auth_identity = self._handle_attach_identity(identity) elif op == 'newuser': auth_identity = self._handle_new_user(identity) elif op == 'login' and not request.user.is_authenticated(): # confirm authentication, login op = None if login_form.is_valid(): # This flow is special. If we are going through a 2FA # flow here (login returns False) we want to instruct the # system to return upon completion of the 2fa flow to the # current URL and continue with the dialog. # # If there is no 2fa we don't need to do this and can just # go on. if not auth.login(request, login_form.get_user(), after_2fa=request.build_absolute_uri(), organization_id=self.organization.id): return HttpResponseRedirect( auth.get_login_redirect(self.request)) else: auth.log_auth_failure(request, request.POST.get('username')) else: op = None if not op: if request.user.is_authenticated(): return self.respond( 'sentry/auth-confirm-link.html', { 'identity': identity, 'existing_user': request.user, 'identity_display_name': self._get_display_name(identity), 'identity_identifier': self._get_identifier(identity) }) return self.respond( 'sentry/auth-confirm-identity.html', { 'existing_user': existing_user, 'identity': identity, 'login_form': login_form, 'identity_display_name': self._get_display_name(identity), 'identity_identifier': self._get_identifier(identity) }) user = auth_identity.user user.backend = settings.AUTHENTICATION_BACKENDS[0] # XXX(dcramer): this is repeated from above if not auth.login(request, user, after_2fa=request.build_absolute_uri(), organization_id=self.organization.id): return HttpResponseRedirect(auth.get_login_redirect(self.request)) self.clear_session() return HttpResponseRedirect(auth.get_login_redirect(self.request))
def parse_query(project, query, user): # TODO(dcramer): handle query being wrapped in quotes tokens = tokenize_query(query) results = {'tags': {}, 'query': []} for key, token_list in six.iteritems(tokens): for value in token_list: if key == 'query': results['query'].append(value) elif key == 'is': if value == 'unassigned': results['unassigned'] = True elif value == 'assigned': results['unassigned'] = False else: try: results['status'] = STATUS_CHOICES[value] except KeyError: raise InvalidQuery(u"'is:' had unknown status code '{}'.".format(value)) elif key == 'assigned': if value == 'me': results['assigned_to'] = user else: try: results['assigned_to'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['assigned_to'] = User(id=0) elif key == 'bookmarks': if value == 'me': results['bookmarked_by'] = user else: try: results['bookmarked_by'] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results['bookmarked_by'] = User(id=0) elif key == 'first-release': results['first_release'] = parse_release(project, value) elif key == 'release': results['tags']['sentry:release'] = parse_release(project, value) elif key == 'user': if ':' in value: comp, value = value.split(':', 1) else: comp = 'id' results['tags']['sentry:user'] = get_user_tag( project, comp, value) elif key == 'has': if value == 'user': value = 'sentry:user' elif value == 'release': value = 'sentry:release' results['tags'][value] = ANY elif key == 'age': results.update(get_date_params(value, 'age_from', 'age_to')) elif key.startswith('user.'): results['tags']['sentry:user'] = get_user_tag( project, key.split('.', 1)[1], value) elif key == 'event.timestamp': results.update(get_date_params(value, 'date_from', 'date_to')) else: results['tags'][key] = value results['query'] = ' '.join(results['query']) return results
def parse_query(project, query, user): # TODO(dcramer): handle query being wrapped in quotes tokens = query.split(" ") results = {"tags": {}, "query": []} tokens_iter = iter(tokens) for token in tokens_iter: # ignore empty tokens if not token: continue if ":" not in token: results["query"].append(token) continue key, value = token.split(":", 1) if not value: results["query"].append(token) continue if value[0] == '"': nvalue = value while nvalue[-1] != '"': try: nvalue = tokens_iter.next() except StopIteration: break value = "%s %s" % (value, nvalue) if value.endswith('"'): value = value[1:-1] else: value = value[1:] if key == "is": try: results["status"] = STATUS_CHOICES[value] except KeyError: pass elif key == "assigned": if value == "me": results["assigned_to"] = user else: try: results["assigned_to"] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results["assigned_to"] = User(id=0) elif key == "first-release": results["first_release"] = value elif key == "release": results["tags"]["sentry:release"] = value elif key == "user": if ":" in value: comp, value = value.split(":", 1) else: comp = "id" results["tags"]["sentry:user"] = get_user_tag(project, comp, value) elif key.startswith("user."): results["tags"]["sentry:user"] = get_user_tag(project, key.split(".", 1)[1], value) else: results["tags"][key] = value results["query"] = " ".join(results["query"]) return results
def _handle_unknown_identity(self, identity): """ Flow is activated upon a user logging in to where an AuthIdentity is not present. The flow will attempt to answer the following: - Is there an existing user with the same email address? Should they be merged? - Is there an existing user (via authentication) that shoudl be merged? - Should I create a new user based on this identity? """ request = self.request op = request.POST.get('op') if not request.user.is_authenticated(): # TODO(dcramer): its possible they have multiple accounts and at # least one is managed (per the check below) try: existing_user = auth.find_users(identity['email'], is_active=True)[0] except IndexError: existing_user = None # If they already have an SSO account and the identity provider says # the email matches we go ahead and let them merge it. This is the # only way to prevent them having duplicate accounts, and because # we trust identity providers, its considered safe. if existing_user and existing_user.is_managed: # we only allow this flow to happen if the existing user has # membership, otherwise we short circuit because it might be # an attempt to hijack membership of another organization has_membership = OrganizationMember.objects.filter( user=existing_user, organization=self.organization, ).exists() if has_membership: if not auth.login(request, existing_user, after_2fa=request.build_absolute_uri()): return HttpResponseRedirect(auth.get_login_redirect( self.request)) # assume they've confirmed they want to attach the identity op = 'confirm' else: # force them to create a new account existing_user = None login_form = self._get_login_form(existing_user) elif request.user.is_managed: # per the above, try to auto merge if the user was originally an # SSO account but is still logged in has_membership = OrganizationMember.objects.filter( user=request.user, organization=self.organization, ).exists() if has_membership: # assume they've confirmed they want to attach the identity op = 'confirm' if op == 'confirm' and request.user.is_authenticated(): auth_identity = self._handle_attach_identity(identity) elif op == 'newuser': auth_identity = self._handle_new_user(identity) elif op == 'login' and not request.user.is_authenticated(): # confirm authentication, login op = None if login_form.is_valid(): # This flow is special. If we are going through a 2FA # flow here (login returns False) we want to instruct the # system to return upon completion of the 2fa flow to the # current URL and continue with the dialog. # # If there is no 2fa we don't need to do this and can just # go on. if not auth.login(request, login_form.get_user(), after_2fa=request.build_absolute_uri()): return HttpResponseRedirect(auth.get_login_redirect( self.request)) request.session.pop('needs_captcha', None) else: auth.log_auth_failure(request, request.POST.get('username')) request.session['needs_captcha'] = 1 else: op = None if not op: if request.user.is_authenticated(): return self.respond('sentry/auth-confirm-link.html', { 'identity': identity, 'existing_user': request.user, 'identity_display_name': self._get_display_name(identity), 'identity_identifier': self._get_identifier(identity) }) return self.respond('sentry/auth-confirm-identity.html', { 'existing_user': existing_user, 'identity': identity, 'login_form': login_form, 'identity_display_name': self._get_display_name(identity), 'identity_identifier': self._get_identifier(identity) }) user = auth_identity.user user.backend = settings.AUTHENTICATION_BACKENDS[0] auth.login(self.request, user) self.clear_session() return HttpResponseRedirect(auth.get_login_redirect(self.request))
def parse_query(project, query, user): # TODO(dcramer): handle query being wrapped in quotes tokens = tokenize_query(query) results = {"tags": {}, "query": []} for key, token_list in tokens.iteritems(): for value in token_list: if key == "query": results["query"].append(value) elif key == "is": if value == "unassigned": results["unassigned"] = True elif value == "assigned": results["unassigned"] = False else: try: results["status"] = STATUS_CHOICES[value] except KeyError: pass elif key == "assigned": if value == "me": results["assigned_to"] = user else: try: results["assigned_to"] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results["assigned_to"] = User(id=0) elif key == "bookmarks": if value == "me": results["bookmarked_by"] = user else: try: results["bookmarked_by"] = find_users(value)[0] except IndexError: # XXX(dcramer): hacky way to avoid showing any results when # an invalid user is entered results["bookmarked_by"] = User(id=0) elif key == "first-release": results["first_release"] = value elif key == "release": results["tags"]["sentry:release"] = value elif key == "user": if ":" in value: comp, value = value.split(":", 1) else: comp = "id" results["tags"]["sentry:user"] = get_user_tag(project, comp, value) elif key == "age": flag, offset = parse_simple_range(value) date_value = timezone.now() - offset if flag == "+": results["date_to"] = date_value elif flag == "-": results["date_from"] = date_value results["date_filter"] = "first_seen" elif key.startswith("user."): results["tags"]["sentry:user"] = get_user_tag(project, key.split(".", 1)[1], value) else: results["tags"][key] = value results["query"] = " ".join(results["query"]) return results