Skip to content

Commit b4a0c91

Browse files
committed
Added a test for the slack kudos.
1 parent f72b174 commit b4a0c91

File tree

9 files changed

+343
-36
lines changed

9 files changed

+343
-36
lines changed

server/src/main/java/com/objectcomputing/checkins/notifications/social_media/SlackSender.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public boolean send(List<String> userIds, String slackBlocks) {
4646
.builder()
4747
.channel(openResponse.getChannel().getId())
4848
.blocksAsString(slackBlocks)
49-
.text("This is a test")
5049
.build();
5150

5251
// Send it to Slack

server/src/main/java/com/objectcomputing/checkins/services/slack/SlackSignatureVerifier.java renamed to server/src/main/java/com/objectcomputing/checkins/services/slack/SlackSignature.java

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.objectcomputing.checkins.services.slack;
22

3+
import com.objectcomputing.checkins.exceptions.BadArgException;
34
import com.objectcomputing.checkins.configuration.CheckInsConfiguration;
45

56
import javax.crypto.Mac;
@@ -12,11 +13,11 @@
1213
import jakarta.inject.Singleton;
1314

1415
@Singleton
15-
public class SlackSignatureVerifier {
16+
public class SlackSignature {
1617
@Inject
1718
private CheckInsConfiguration configuration;
1819

19-
public SlackSignatureVerifier() {}
20+
public SlackSignature() {}
2021

2122
public boolean verifyRequest(String slackSignature, String timestamp, String requestBody) {
2223
try {
@@ -35,7 +36,7 @@ public boolean verifyRequest(String slackSignature, String timestamp, String req
3536

3637
// Compare the computed signature with Slack's signature
3738
return computedSignature.equals(slackSignature);
38-
} catch (Exception e) {
39+
} catch (Exception ex) {
3940
return false;
4041
}
4142
}
@@ -64,4 +65,30 @@ private String hmacSha256(String secret, String message) throws Exception {
6465
}
6566
return hexString.toString();
6667
}
68+
69+
public String generate(String timestamp, String rawBody) {
70+
String baseString = "v0:" + timestamp + ":" + rawBody;
71+
String secret = configuration.getApplication()
72+
.getSlack().getSigningSecret();
73+
74+
try {
75+
// Generate HMAC SHA-256 signature
76+
Mac mac = Mac.getInstance("HmacSHA256");
77+
SecretKeySpec secretKeySpec =
78+
new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8),
79+
"HmacSHA256");
80+
mac.init(secretKeySpec);
81+
byte[] hash = mac.doFinal(
82+
baseString.getBytes(StandardCharsets.UTF_8));
83+
84+
// Convert hash to hex
85+
StringBuilder hexString = new StringBuilder();
86+
for (byte b : hash) {
87+
hexString.append(String.format("%02x", b));
88+
}
89+
return "v0=" + hexString.toString();
90+
} catch (Exception ex) {
91+
throw new BadArgException(ex.toString());
92+
}
93+
}
6794
}

server/src/main/java/com/objectcomputing/checkins/services/slack/SlackSubmissionHandler.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,18 @@ public class SlackSubmissionHandler {
3131
private static final String typeKey = "type";
3232

3333
private final PulseResponseService pulseResponseServices;
34-
private final SlackSignatureVerifier slackSignatureVerifier;
34+
private final SlackSignature slackSignature;
3535
private final PulseSlackCommand pulseSlackCommand;
3636
private final SlackPulseResponseConverter slackPulseResponseConverter;
3737
private final SlackKudosResponseHandler slackKudosResponseHandler;
3838

3939
public SlackSubmissionHandler(PulseResponseService pulseResponseServices,
40-
SlackSignatureVerifier slackSignatureVerifier,
40+
SlackSignature slackSignature,
4141
PulseSlackCommand pulseSlackCommand,
4242
SlackPulseResponseConverter slackPulseResponseConverter,
4343
SlackKudosResponseHandler slackKudosResponseHandler) {
4444
this.pulseResponseServices = pulseResponseServices;
45-
this.slackSignatureVerifier = slackSignatureVerifier;
45+
this.slackSignature = slackSignature;
4646
this.pulseSlackCommand = pulseSlackCommand;
4747
this.slackPulseResponseConverter = slackPulseResponseConverter;
4848
this.slackKudosResponseHandler = slackKudosResponseHandler;
@@ -52,8 +52,7 @@ public HttpResponse commandResponse(String signature,
5252
String timestamp,
5353
String requestBody) {
5454
// Validate the request
55-
if (slackSignatureVerifier.verifyRequest(signature,
56-
timestamp, requestBody)) {
55+
if (slackSignature.verifyRequest(signature, timestamp, requestBody)) {
5756
// Convert the request body to a map of values.
5857
FormUrlEncodedDecoder formUrlEncodedDecoder = new FormUrlEncodedDecoder();
5958
Map<String, Object> body =
@@ -77,8 +76,7 @@ public HttpResponse externalResponse(String signature,
7776
String requestBody,
7877
HttpRequest<?> request) {
7978
// Validate the request
80-
if (slackSignatureVerifier.verifyRequest(signature,
81-
timestamp, requestBody)) {
79+
if (slackSignature.verifyRequest(signature, timestamp, requestBody)) {
8280
// Convert the request body to a map of values.
8381
FormUrlEncodedDecoder formUrlEncodedDecoder =
8482
new FormUrlEncodedDecoder();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.objectcomputing.checkins.services;
2+
3+
import com.objectcomputing.checkins.services.slack.SlackReader;
4+
import com.objectcomputing.checkins.configuration.CheckInsConfiguration;
5+
6+
import io.micronaut.context.annotation.Replaces;
7+
import io.micronaut.context.annotation.Requires;
8+
import io.micronaut.core.util.StringUtils;
9+
import io.micronaut.http.HttpResponse;
10+
import io.micronaut.http.HttpStatus;
11+
12+
import com.slack.api.model.Message;
13+
14+
import jakarta.inject.Singleton;
15+
16+
import java.util.List;
17+
import java.util.ArrayList;
18+
import java.util.HashMap;
19+
import java.util.Map;
20+
import java.time.LocalDateTime;
21+
import java.time.ZoneId;
22+
23+
@Singleton
24+
@Replaces(SlackReader.class)
25+
@Requires(property = "replace.slackreader", value = StringUtils.TRUE)
26+
public class SlackReaderReplacement extends SlackReader {
27+
public final Map<String, List<Message>> channelMessages = new HashMap<>();
28+
29+
@Override
30+
public List<Message> read(String channelId, LocalDateTime last) {
31+
List<Message> messages = new ArrayList<>();
32+
if (channelMessages.containsKey(channelId)) {
33+
long ts = last.atZone(ZoneId.systemDefault())
34+
.toInstant().getEpochSecond();
35+
for (Message message : channelMessages.get(channelId)) {
36+
long messageTime = Long.parseLong(message.getTs());
37+
if (messageTime >= ts) {
38+
messages.add(message);
39+
}
40+
}
41+
}
42+
return messages;
43+
}
44+
45+
public void addMessage(String channelId, String userId,
46+
String text, LocalDateTime sendTime) {
47+
Message message = new Message();
48+
message.setTs(String.valueOf(sendTime.atZone(ZoneId.systemDefault())
49+
.toInstant().getEpochSecond()));
50+
message.setText(text);
51+
message.setUser(userId);
52+
53+
if (!channelMessages.containsKey(channelId)) {
54+
channelMessages.put(channelId, new ArrayList<Message>());
55+
}
56+
channelMessages.get(channelId).add(message);
57+
}
58+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.objectcomputing.checkins.services;
2+
3+
import com.objectcomputing.checkins.notifications.social_media.SlackSender;
4+
5+
import io.micronaut.context.annotation.Replaces;
6+
import io.micronaut.context.annotation.Requires;
7+
import io.micronaut.core.util.StringUtils;
8+
9+
import jakarta.inject.Singleton;
10+
11+
import java.util.ArrayList;
12+
import java.util.List;
13+
import java.util.Map;
14+
import java.util.HashMap;
15+
16+
@Singleton
17+
@Replaces(SlackSender.class)
18+
@Requires(property = "replace.slacksender", value = StringUtils.TRUE)
19+
public class SlackSenderReplacement extends SlackSender {
20+
public final Map<String, List<String>> sent = new HashMap<>();
21+
22+
public void reset() {
23+
sent.clear();
24+
}
25+
26+
@Override
27+
public boolean send(List<String> userIds, String slackBlocks) {
28+
for (String userId : userIds) {
29+
if (!sent.containsKey(userId)) {
30+
sent.put(userId, new ArrayList<String>());
31+
}
32+
sent.get(userId).add(slackBlocks);
33+
}
34+
return true;
35+
}
36+
}
37+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.objectcomputing.checkins.services.fixture;
2+
3+
import com.objectcomputing.checkins.services.slack.kudos.AutomatedKudos;
4+
import com.objectcomputing.checkins.services.slack.kudos.AutomatedKudosRepository;
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
9+
public interface AutomatedKudosFixture extends RepositoryFixture {
10+
default List<AutomatedKudos> getAutomatedKudos() {
11+
List<AutomatedKudos> list = new ArrayList<>();
12+
getAutomatedKudosRepository().findAll().forEach(list::add);
13+
return list;
14+
}
15+
}

server/src/test/java/com/objectcomputing/checkins/services/fixture/RepositoryFixture.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import com.objectcomputing.checkins.services.volunteering.VolunteeringRelationshipRepository;
4444
import io.micronaut.runtime.server.EmbeddedServer;
4545
import com.objectcomputing.checkins.services.employee_hours.EmployeeHoursRepository;
46+
import com.objectcomputing.checkins.services.slack.kudos.AutomatedKudosRepository;
4647

4748
public interface RepositoryFixture {
4849
EmbeddedServer getEmbeddedServer();
@@ -213,4 +214,8 @@ default DocumentRepository getDocumentRepository() {
213214
default RoleDocumentationRepository getRoleDocumentationRepository() {
214215
return getEmbeddedServer().getApplicationContext().getBean(RoleDocumentationRepository.class);
215216
}
217+
218+
default AutomatedKudosRepository getAutomatedKudosRepository() {
219+
return getEmbeddedServer().getApplicationContext().getBean(AutomatedKudosRepository.class);
220+
}
216221
}

0 commit comments

Comments
 (0)