Example #1
0
        public async Task CanRoundTripWithCaching()
        {
            var token = new SlackToken {
                AccessToken     = "MY KEY",
                IncomingWebhook = new SlackToken.IncomingWebHook {
                    Url = "MY Url"
                }
            };

            var project = ProjectData.GenerateSampleProject();

            project.Data[Project.KnownDataKeys.SlackToken] = token;

            await _repository.AddAsync(project, o => o.ImmediateConsistency());

            var actual = await _repository.GetByIdAsync(project.Id, o => o.Cache());

            Assert.Equal(project.Name, actual?.Name);
            var actualToken = actual.GetSlackToken();

            Assert.Equal(token.AccessToken, actualToken?.AccessToken);

            var actualCache = await _cache.GetAsync <ICollection <FindHit <Project> > >("Project:" + project.Id);

            Assert.True(actualCache.HasValue);
            Assert.Equal(project.Name, actualCache.Value.Single().Document.Name);
            var actualCacheToken = actual.GetSlackToken();

            Assert.Equal(token.AccessToken, actualCacheToken?.AccessToken);
        }
Example #2
0
        public async Task <SlackToken> GetAccessTokenAsync(string code)
        {
            if (String.IsNullOrEmpty(code))
            {
                throw new ArgumentNullException(nameof(code));
            }

            var data = new Dictionary <string, string> {
                { "client_id", _appOptions.SlackOptions.SlackId },
                { "client_secret", _appOptions.SlackOptions.SlackSecret },
                { "code", code },
                { "redirect_uri", new Uri(_appOptions.BaseURL).GetLeftPart(UriPartial.Authority) }
            };

            string url      = $"https://slack.com/api/oauth.access?{data.ToQueryString()}";
            var    response = await _client.PostAsync(url).AnyContext();

            byte[] body = await response.Content.ReadAsByteArrayAsync().AnyContext();

            var result = _serializer.Deserialize <OAuthAccessResponse>(body);

            if (!result.ok)
            {
                _logger.LogWarning("Error getting access token: {Message}, Response: {Response}", result.error ?? result.warning, result);
                return(null);
            }

            var token = new SlackToken {
                AccessToken = result.access_token,
                Scopes      = result.scope?.Split(new [] { "," }, StringSplitOptions.RemoveEmptyEntries) ?? new string[0],
                UserId      = result.user_id,
                TeamId      = result.team_id,
                TeamName    = result.team_name
            };

            if (result.incoming_webhook != null)
            {
                token.IncomingWebhook = new SlackToken.IncomingWebHook {
                    Channel          = result.incoming_webhook.channel,
                    ChannelId        = result.incoming_webhook.channel_id,
                    ConfigurationUrl = result.incoming_webhook.configuration_url,
                    Url = result.incoming_webhook.url
                };
            }

            return(token);
        }
        public async Task <IHttpActionResult> AddSlackAsync(string id, string code)
        {
            if (String.IsNullOrWhiteSpace(code))
            {
                return(BadRequest());
            }

            var project = await GetModelAsync(id, false);

            if (project == null)
            {
                return(NotFound());
            }

            if (project.Data.ContainsKey(Project.KnownDataKeys.SlackToken))
            {
                return(StatusCode(HttpStatusCode.NotModified));
            }

            SlackToken token = null;

            try {
                token = await _slackService.GetAccessTokenAsync(code);
            } catch (Exception ex) {
                _logger.Error().Exception(ex)
                .Message($"Error getting slack access token: {ex.Message}")
                .Property("Code", code)
                .Tag("Slack")
                .Identity(CurrentUser.EmailAddress)
                .Property("User", CurrentUser)
                .SetActionContext(ActionContext)
                .Write();
            }

            if (token == null)
            {
                return(BadRequest());
            }

            project.AddDefaultNotificationSettings(Project.NotificationIntegrations.Slack);
            project.Data[Project.KnownDataKeys.SlackToken] = token;
            await _repository.SaveAsync(project, o => o.Cache());

            return(Ok());
        }
        public async Task <IActionResult> AddSlackAsync(string id, [FromQuery] string code)
        {
            if (String.IsNullOrWhiteSpace(code))
            {
                return(BadRequest());
            }

            var project = await GetModelAsync(id, false);

            if (project == null)
            {
                return(NotFound());
            }

            if (project.Data.ContainsKey(Project.KnownDataKeys.SlackToken))
            {
                return(StatusCode(StatusCodes.Status304NotModified));
            }

            SlackToken token = null;

            try {
                token = await _slackService.GetAccessTokenAsync(code);
            } catch (Exception ex) {
                using (_logger.BeginScope(new ExceptionlessState().Organization(project.OrganizationId).Project(project.Id).Property("Code", code).Tag("Slack").Identity(CurrentUser.EmailAddress).Property("User", CurrentUser).SetHttpContext(HttpContext)))
                    _logger.LogError(ex, "Error getting slack access token: {Message}", ex.Message);
            }

            if (token == null)
            {
                return(BadRequest());
            }

            project.AddDefaultNotificationSettings(Project.NotificationIntegrations.Slack);
            project.Data[Project.KnownDataKeys.SlackToken] = token;
            await _repository.SaveAsync(project, o => o.Cache());

            return(Ok());
        }