mirror of
https://github.com/bitwarden/server.git
synced 2025-04-06 05:28:15 -05:00
Refactor SlackService to use a dedicated model to parse responses
This commit is contained in:
parent
fb7d24286d
commit
2227b3b867
45
src/Core/AdminConsole/Models/Slack/SlackApiResponse.cs
Normal file
45
src/Core/AdminConsole/Models/Slack/SlackApiResponse.cs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace Bit.Core.Models.Slack;
|
||||||
|
|
||||||
|
public abstract class SlackApiResponse
|
||||||
|
{
|
||||||
|
public bool Ok { get; set; }
|
||||||
|
[JsonPropertyName("response_metadata")]
|
||||||
|
public SlackResponseMetadata ResponseMetadata { get; set; } = new();
|
||||||
|
public string Error { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackResponseMetadata
|
||||||
|
{
|
||||||
|
[JsonPropertyName("next_cursor")]
|
||||||
|
public string NextCursor { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackChannelListResponse : SlackApiResponse
|
||||||
|
{
|
||||||
|
public List<SlackChannel> Channels { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackUserResponse : SlackApiResponse
|
||||||
|
{
|
||||||
|
public SlackUser User { get; set; } = new();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackChannel
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackUser
|
||||||
|
{
|
||||||
|
public string Id { get; set; } = string.Empty;
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SlackDmResponse : SlackApiResponse
|
||||||
|
{
|
||||||
|
public SlackChannel Channel { get; set; } = new();
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
using System.Text.Json;
|
|
||||||
using System.Web;
|
using System.Web;
|
||||||
|
using Bit.Core.Models.Slack;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace Bit.Core.Services;
|
namespace Bit.Core.Services;
|
||||||
@ -16,7 +16,7 @@ public class SlackService(
|
|||||||
|
|
||||||
public async Task<string> GetChannelIdAsync(string token, string channelName)
|
public async Task<string> GetChannelIdAsync(string token, string channelName)
|
||||||
{
|
{
|
||||||
return (await GetChannelIdsAsync(token, new List<string> { channelName }))?.FirstOrDefault();
|
return (await GetChannelIdsAsync(token, new List<string> { channelName })).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<string>> GetChannelIdsAsync(string token, List<string> channelNames)
|
public async Task<List<string>> GetChannelIdsAsync(string token, List<string> channelNames)
|
||||||
@ -29,48 +29,32 @@ public class SlackService(
|
|||||||
{
|
{
|
||||||
var uriBuilder = new UriBuilder(baseUrl);
|
var uriBuilder = new UriBuilder(baseUrl);
|
||||||
var queryParameters = HttpUtility.ParseQueryString(uriBuilder.Query);
|
var queryParameters = HttpUtility.ParseQueryString(uriBuilder.Query);
|
||||||
|
|
||||||
queryParameters["types"] = "public_channel,private_channel";
|
queryParameters["types"] = "public_channel,private_channel";
|
||||||
queryParameters["limit"] = "1000";
|
queryParameters["limit"] = "1000";
|
||||||
if (!string.IsNullOrEmpty(nextCursor))
|
if (!string.IsNullOrEmpty(nextCursor))
|
||||||
{
|
{
|
||||||
queryParameters["cursor"] = nextCursor;
|
queryParameters["cursor"] = nextCursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
uriBuilder.Query = queryParameters.ToString();
|
uriBuilder.Query = queryParameters.ToString();
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, uriBuilder.Uri);
|
var request = new HttpRequestMessage(HttpMethod.Get, uriBuilder.Uri);
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
|
|
||||||
var response = await _httpClient.SendAsync(request);
|
var response = await _httpClient.SendAsync(request);
|
||||||
var jsonResponse = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
|
var result = await response.Content.ReadFromJsonAsync<SlackChannelListResponse>();
|
||||||
var root = jsonResponse.RootElement;
|
|
||||||
if (root.GetProperty("ok").GetBoolean())
|
if (result != null && result.Ok)
|
||||||
{
|
{
|
||||||
var channelList = root.GetProperty("channels");
|
matchingChannelIds.AddRange(result.Channels
|
||||||
|
.Where(channel => channelNames.Contains(channel.Name))
|
||||||
foreach (var channel in channelList.EnumerateArray())
|
.Select(channel => channel.Id));
|
||||||
{
|
nextCursor = result.ResponseMetadata.NextCursor;
|
||||||
if (channelNames.Contains(channel.GetProperty("name").GetString() ?? string.Empty))
|
|
||||||
{
|
|
||||||
matchingChannelIds.Add(channel.GetProperty("id").GetString() ?? string.Empty);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.TryGetProperty("response_metadata", out var metadata))
|
|
||||||
{
|
|
||||||
nextCursor = metadata.GetProperty("next_cursor").GetString() ?? string.Empty;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nextCursor = string.Empty;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.LogError("Error retrieving slack userId: " + root.GetProperty("error").GetString());
|
nextCursor = string.Empty;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (!string.IsNullOrEmpty(nextCursor));
|
} while (!string.IsNullOrEmpty(nextCursor));
|
||||||
|
|
||||||
return matchingChannelIds;
|
return matchingChannelIds;
|
||||||
@ -92,32 +76,25 @@ public class SlackService(
|
|||||||
await _httpClient.SendAsync(request);
|
await _httpClient.SendAsync(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SendDirectMessageByEmailAsync(string token, string message, string email)
|
|
||||||
{
|
|
||||||
var channelId = await GetDmChannelByEmailAsync(token, email);
|
|
||||||
if (!string.IsNullOrEmpty(channelId))
|
|
||||||
{
|
|
||||||
await SendSlackMessageByChannelId(token, message, channelId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task<string> GetUserIdByEmailAsync(string token, string email)
|
private async Task<string> GetUserIdByEmailAsync(string token, string email)
|
||||||
{
|
{
|
||||||
var request = new HttpRequestMessage(HttpMethod.Get, $"https://slack.com/api/users.lookupByEmail?email={email}");
|
var request = new HttpRequestMessage(HttpMethod.Get, $"https://slack.com/api/users.lookupByEmail?email={email}");
|
||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
var response = await _httpClient.SendAsync(request);
|
var response = await _httpClient.SendAsync(request);
|
||||||
var content = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
|
var result = await response.Content.ReadFromJsonAsync<SlackUserResponse>();
|
||||||
var root = content.RootElement;
|
|
||||||
|
|
||||||
if (root.GetProperty("ok").GetBoolean())
|
if (result == null)
|
||||||
{
|
{
|
||||||
return root.GetProperty("user").GetProperty("id").GetString() ?? string.Empty;
|
logger.LogError("Error retrieving Slack user ID: Unknown error");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.LogError("Error retrieving slack userId: " + root.GetProperty("error").GetString());
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
if (!result.Ok)
|
||||||
|
{
|
||||||
|
logger.LogError("Error retrieving Slack user ID: " + result.Error);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.User.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<string> OpenDmChannel(string token, string userId)
|
private async Task<string> OpenDmChannel(string token, string userId)
|
||||||
@ -127,17 +104,19 @@ public class SlackService(
|
|||||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||||
request.Content = payload;
|
request.Content = payload;
|
||||||
var response = await _httpClient.SendAsync(request);
|
var response = await _httpClient.SendAsync(request);
|
||||||
var content = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
|
var result = await response.Content.ReadFromJsonAsync<SlackDmResponse>();
|
||||||
var root = content.RootElement;
|
|
||||||
|
|
||||||
if (root.GetProperty("ok").GetBoolean())
|
if (result == null)
|
||||||
{
|
{
|
||||||
return content.RootElement.GetProperty("channel").GetProperty("id").GetString() ?? string.Empty;
|
logger.LogError("Error opening DM channel: Unknown error");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.LogError("Error opening DM channel: " + root.GetProperty("error").GetString());
|
|
||||||
return string.Empty;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
if (!result.Ok)
|
||||||
|
{
|
||||||
|
logger.LogError("Error opening DM channel: " + result.Error);
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.Channel.Id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user