microsoft/teams.net

Public

mirrored fromhttps://github.com/microsoft/teams.netAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
b9bc522d242ad42cba49791c95c73c0f2c1d2358

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

Tests/Microsoft.Teams.Apps.Tests/ServiceUrlValidatorTests.cs

121lines · modecode

1using Microsoft.Teams.Api.Auth;
2
3namespace Microsoft.Teams.Apps.Tests;
4
5public class ServiceUrlValidatorTests
6{
7 // --- Public cloud ---
8
9 [Theory]
10 [InlineData("https://smba.trafficmanager.net/teams/")]
11 [InlineData("https://smba.trafficmanager.net/amer/")]
12 [InlineData("https://smba.onyx.prod.teams.trafficmanager.net")]
13 public void IsAllowed_AcceptsPublicCloudDomains(string serviceUrl)
14 {
15 Assert.True(ServiceUrlValidator.IsAllowed(serviceUrl, CloudEnvironment.Public));
16 }
17
18 // --- Government clouds ---
19
20 [Fact]
21 public void IsAllowed_AcceptsUSGovDomain()
22 {
23 Assert.True(ServiceUrlValidator.IsAllowed("https://smba.infra.gov.teams.microsoft.us/gcch/", CloudEnvironment.USGov));
24 }
25
26 [Fact]
27 public void IsAllowed_AcceptsDoDDomain()
28 {
29 Assert.True(ServiceUrlValidator.IsAllowed("https://smba.infra.dod.teams.microsoft.us/", CloudEnvironment.USGovDoD));
30 }
31
32 [Fact]
33 public void IsAllowed_AcceptsChinaDomain()
34 {
35 Assert.True(ServiceUrlValidator.IsAllowed("https://frontend.botapi.msg.infra.teams.microsoftonline.cn", CloudEnvironment.China));
36 }
37
38 // --- Cross-cloud rejection ---
39
40 [Fact]
41 public void IsAllowed_RejectsGovDomainWithPublicCloud()
42 {
43 Assert.False(ServiceUrlValidator.IsAllowed("https://smba.infra.gov.teams.microsoft.us/", CloudEnvironment.Public));
44 }
45
46 // --- Localhost ---
47
48 [Theory]
49 [InlineData("http://localhost:3978")]
50 [InlineData("https://localhost:443")]
51 [InlineData("http://127.0.0.1:3978")]
52 public void IsAllowed_AcceptsLocalhost(string serviceUrl)
53 {
54 Assert.True(ServiceUrlValidator.IsAllowed(serviceUrl, CloudEnvironment.Public));
55 }
56
57 // --- Rejected domains ---
58
59 [Theory]
60 [InlineData("https://evil.com")]
61 [InlineData("https://botframework.com.evil.com")]
62 [InlineData("https://attacker.net/api")]
63 [InlineData("https://attacker.trafficmanager.net")]
64 public void IsAllowed_RejectsUnknownDomains(string serviceUrl)
65 {
66 Assert.False(ServiceUrlValidator.IsAllowed(serviceUrl, CloudEnvironment.Public));
67 }
68
69 // --- Empty / null ---
70
71 [Theory]
72 [InlineData("")]
73 [InlineData(null)]
74 public void IsAllowed_AcceptsEmptyOrNull(string? serviceUrl)
75 {
76 Assert.True(ServiceUrlValidator.IsAllowed(serviceUrl!, CloudEnvironment.Public));
77 }
78
79 // --- Invalid URLs ---
80
81 [Fact]
82 public void IsAllowed_RejectsInvalidUrl()
83 {
84 Assert.False(ServiceUrlValidator.IsAllowed("not-a-url", CloudEnvironment.Public));
85 }
86
87 // --- Additional domains ---
88
89 [Fact]
90 public void IsAllowed_AcceptsAdditionalDomains()
91 {
92 var additional = new[] { "api.custom-channel.com" };
93 Assert.True(ServiceUrlValidator.IsAllowed("https://api.custom-channel.com", CloudEnvironment.Public, additional));
94 }
95
96 [Fact]
97 public void IsAllowed_RejectsWhenNotInAdditionalDomains()
98 {
99 var additional = new[] { "api.custom-channel.com" };
100 Assert.False(ServiceUrlValidator.IsAllowed("https://evil.com", CloudEnvironment.Public, additional));
101 }
102
103 // --- Wildcard ---
104
105 [Fact]
106 public void IsAllowed_AcceptsAnyDomainWithWildcard()
107 {
108 var additional = new[] { "*" };
109 Assert.True(ServiceUrlValidator.IsAllowed("https://anything.example.com", CloudEnvironment.Public, additional));
110 }
111
112 // --- botframework.com not in default ---
113
114 [Theory]
115 [InlineData("https://webchat.botframework.com")]
116 [InlineData("https://directline.botframework.com")]
117 public void IsAllowed_RejectsBotframeworkByDefault(string serviceUrl)
118 {
119 Assert.False(ServiceUrlValidator.IsAllowed(serviceUrl, CloudEnvironment.Public));
120 }
121}
122