class ServiceHook(Model): __include_in_export__ = True guid = models.CharField(max_length=32, unique=True, null=True) # hooks may be bound to an api application, or simply registered by a user application = FlexibleForeignKey("sentry.ApiApplication", null=True) actor_id = BoundedPositiveIntegerField(db_index=True) project_id = BoundedPositiveIntegerField(db_index=True, null=True) organization_id = BoundedPositiveIntegerField(db_index=True, null=True) url = models.URLField(max_length=512) secret = EncryptedTextField(default=generate_secret) events = ArrayField(of=models.TextField) status = BoundedPositiveIntegerField(default=0, choices=ObjectStatus.as_choices(), db_index=True) version = BoundedPositiveIntegerField(default=0, choices=((0, "0"), )) date_added = models.DateTimeField(default=timezone.now) objects = BaseManager(cache_fields=("guid", )) class Meta: app_label = "sentry" db_table = "sentry_servicehook" __repr__ = sane_repr("guid", "project_id") @property def created_by_sentry_app(self): return self.application_id and self.sentry_app @property def sentry_app(self): try: return SentryApp.objects.get(application_id=self.application_id) except SentryApp.DoesNotExist: return def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.guid is None: self.guid = uuid4().hex def __str__(self): return str(self.guid) def build_signature(self, body): return hmac.new(key=self.secret.encode("utf-8"), msg=body.encode("utf-8"), digestmod=sha256).hexdigest() def get_audit_log_data(self): return {"url": self.url} def add_project(self, project): """ Add a project to the service hook. """ ServiceHookProject.objects.create(project_id=project.id, service_hook_id=self.id)
class ServiceHook(Model): __core__ = True guid = models.CharField(max_length=32, unique=True, null=True) # hooks may be bound to an api application, or simply registered by a user application = FlexibleForeignKey('sentry.ApiApplication', null=True) actor_id = BoundedPositiveIntegerField(db_index=True) project_id = BoundedPositiveIntegerField(db_index=True) organization_id = BoundedPositiveIntegerField(db_index=True, null=True) url = models.URLField(max_length=512) secret = EncryptedTextField(default=generate_secret) events = ArrayField(of=models.TextField) status = BoundedPositiveIntegerField(default=0, choices=ObjectStatus.as_choices(), db_index=True) version = BoundedPositiveIntegerField(default=0, choices=((0, '0'), )) date_added = models.DateTimeField(default=timezone.now) objects = BaseManager(cache_fields=('guid', )) class Meta: app_label = 'sentry' db_table = 'sentry_servicehook' __repr__ = sane_repr('guid', 'project_id') @property def created_by_sentry_app(self): return (self.application_id and self.sentry_app) @property def sentry_app(self): try: return SentryApp.objects.get(application_id=self.application_id) except SentryApp.DoesNotExist: return def __init__(self, *args, **kwargs): super(ServiceHook, self).__init__(*args, **kwargs) if self.guid is None: self.guid = uuid4().hex def __unicode__(self): return six.text_type(self.guid) def build_signature(self, body): return hmac.new( key=self.secret.encode('utf-8'), msg=body.encode('utf-8'), digestmod=sha256, ).hexdigest() def get_audit_log_data(self): return {'url': self.url}
class ApiApplication(Model): __core__ = True client_id = models.CharField( max_length=64, unique=True, default=lambda: ApiApplication.generate_token()) client_secret = EncryptedTextField( default=lambda: ApiApplication.generate_token()) owner = FlexibleForeignKey('sentry.User') name = models.CharField( max_length=64, blank=True, default=lambda: petname.Generate(2, ' ', letters=10).title()) status = BoundedPositiveIntegerField(default=0, choices=( (ApiApplicationStatus.active, _('Active')), (ApiApplicationStatus.inactive, _('Inactive')), ), db_index=True) allowed_origins = models.TextField(blank=True, null=True) redirect_uris = models.TextField() homepage_url = models.URLField(null=True) privacy_url = models.URLField(null=True) terms_url = models.URLField(null=True) date_added = models.DateTimeField(default=timezone.now) objects = BaseManager(cache_fields=('client_id', )) class Meta: app_label = 'sentry' db_table = 'sentry_apiapplication' __repr__ = sane_repr('name', 'owner_id') def __unicode__(self): return self.name @classmethod def generate_token(cls): return uuid4().hex + uuid4().hex @property def is_active(self): return self.status == ApiApplicationStatus.active def is_allowed_response_type(self, value): return value in ('code', 'token') def is_valid_redirect_uri(self, value): v_netloc = urlparse(value).netloc for ruri in self.redirect_uris.split('\n'): if v_netloc != urlparse(ruri).netloc: continue if value.startswith(ruri): return True return False def get_default_redirect_uri(self): return self.redirect_uris.split('\n', 1)[0] def get_allowed_origins(self): if not self.allowed_origins: return [] return [a for a in self.allowed_origins.split('\n') if a] def get_audit_log_data(self): return { 'client_id': self.client_id, 'name': self.name, 'redirect_uris': self.redirect_uris, 'allowed_origins': self.allowed_origins, 'status': self.status, }
class ApiApplication(Model): __core__ = True client_id = models.CharField(max_length=64, unique=True, default=generate_token) client_secret = EncryptedTextField(default=generate_token) owner = FlexibleForeignKey("sentry.User") name = models.CharField(max_length=64, blank=True, default=generate_name) status = BoundedPositiveIntegerField( default=0, choices=( (ApiApplicationStatus.active, _("Active")), (ApiApplicationStatus.inactive, _("Inactive")), ), db_index=True, ) allowed_origins = models.TextField(blank=True, null=True) redirect_uris = models.TextField() homepage_url = models.URLField(null=True) privacy_url = models.URLField(null=True) terms_url = models.URLField(null=True) date_added = models.DateTimeField(default=timezone.now) objects = BaseManager(cache_fields=("client_id", )) class Meta: app_label = "sentry" db_table = "sentry_apiapplication" __repr__ = sane_repr("name", "owner_id") def __str__(self): return self.name @property def is_active(self): return self.status == ApiApplicationStatus.active def is_allowed_response_type(self, value): return value in ("code", "token") def is_valid_redirect_uri(self, value): v_netloc = urlparse(value).netloc for ruri in self.redirect_uris.split("\n"): if v_netloc != urlparse(ruri).netloc: continue if value.startswith(ruri): return True return False def get_default_redirect_uri(self): return self.redirect_uris.split("\n", 1)[0] def get_allowed_origins(self): if not self.allowed_origins: return [] return [a for a in self.allowed_origins.split("\n") if a] def get_audit_log_data(self): return { "client_id": self.client_id, "name": self.name, "redirect_uris": self.redirect_uris, "allowed_origins": self.allowed_origins, "status": self.status, }