Skip to content

Commit

Permalink
Add a command to test mail
Browse files Browse the repository at this point in the history
This adds a command to test the mail system.

Additionally, some unused string resources were removed, and a missing
string resource was added. Also, the documentation now correctly
imports the missing monitoring chapter.

Fix: #76
  • Loading branch information
io7m committed Jun 16, 2023
1 parent e388690 commit fd8de14
Show file tree
Hide file tree
Showing 39 changed files with 1,411 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,8 @@
<entry key="notLoggedIn">Error: Not logged in!</entry>
<entry key="connectFailure">An error occurred whilst trying to connect to the identity server.</entry>

<entry key="Expected Content Type">Expected Content Type</entry>
<entry key="Expected Response Type">Expected Response Type</entry>
<entry key="Received Response Type">Received Response Type</entry>
<entry key="Received an unexpected response type.">Received an unexpected response type.</entry>

<entry key="errorContentType"><![CDATA[The server sent an unexpected content type.
Command: {0}
Expected: {1}
Received: {2}
]]></entry>

<entry key="errorResponseType"><![CDATA[The server sent an unexpected message response type.
Request ID: {0}
Command: {1}
Expected: {2}
Received: {3}
]]></entry>

<entry key="errorResponse"><![CDATA[The server sent an error response.
Request ID: {0}
Command: {1}
Status: {2}
Error Code: {3}
Error Message: {4}
]]></entry>

<entry key="errorMalformedParameter">Malformed parameter: {0}</entry>

</properties>
Original file line number Diff line number Diff line change
Expand Up @@ -107,28 +107,6 @@ public IdDatabase(
measurement.record(this.connectionTimeNow);
})
);

this.resources.add(
meter.gaugeBuilder("idstore_db_connections_active")
.setDescription("The number of connections that are currently active.")
.ofLongs()
.buildWithCallback(measurement -> {
measurement.record(
(long) this.dataSource.getHikariPoolMXBean().getActiveConnections()
);
})
);

this.resources.add(
meter.gaugeBuilder("idstore_db_connections_total")
.setDescription("The total number of available connections.")
.ofLongs()
.buildWithCallback(measurement -> {
measurement.record(
(long) this.dataSource.getHikariPoolMXBean().getTotalConnections()
);
})
);
}

LongCounter counterTransactions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<xi:include href="install.xml"/>
<xi:include href="configuration.xml"/>
<xi:include href="model.xml"/>
<xi:include href="monitoring.xml"/>
<xi:include href="cmdline.xml"/>
<xi:include href="shell-admin.xml"/>
<xi:include href="api.xml"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@
<Cell>USER_READ</Cell>
<Cell>The bearer of this permission is permitted to read existing user accounts.</Cell>
</Row>
<Row>
<Cell>MAIL_TEST</Cell>
<Cell>The bearer of this permission is permitted to send test emails.</Cell>
</Row>
</Table>
</FormalItem>
</Subsection>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Section id="157840ab-7cc0-434a-a6a5-ee2fdbfd2848" title="mail-test" xmlns="urn:com.io7m.structural:8:0">
<Subsection title="Name">
<Paragraph>
<Term type="command">mail-test</Term>
- Send a test email.
</Paragraph>
</Subsection>
<Subsection title="Description">
<Paragraph>
The
<Term type="command">mail-test</Term>
command checks to see if the mail system is working by sending a test email.
</Paragraph>
<Paragraph>
For obvious reasons, the command can only check that the <Term type="package">idstore</Term>
server is capable of sending mail through its configured mail service - it cannot automatically
verify that the target will actually receive the sent mail.
</Paragraph>
<FormalItem title="Parameters">
<Table type="parameterTable">
<Columns>
<Column>Parameter</Column>
<Column>Type</Column>
<Column>Cardinality</Column>
<Column>Default</Column>
<Column>Description</Column>
</Columns>
<Row>
<Cell>
<Term type="parameter">--email</Term>
</Cell>
<Cell>
<Term type="type">com.io7m.idstore.model.IdEmail</Term>
</Cell>
<Cell>
<Term type="expression">[1]</Term>
</Cell>
<Cell>
<Term type="constant"/>
</Cell>
<Cell>The target email address.</Cell>
</Row>
<Row>
<Cell>
<Term type="parameter">--token</Term>
</Cell>
<Cell>
<Term type="type">com.io7m.idstore.model.IdShortHumanToken</Term>
</Cell>
<Cell>
<Term type="expression">[0, 1]</Term>
</Cell>
<Cell>
<Term type="constant"/>
</Cell>
<Cell>The short token to include in the email. If a value is not provided, one is randomly generated.</Cell>
</Row>
</Table>
</FormalItem>
</Subsection>
<Subsection title="Example">
<FormalItem title="Example">
<Verbatim><![CDATA[[idstore]# mail-test --email user@example.com
Mail sent successfully.
Token: 220384
]]></Verbatim>
</FormalItem>
</Subsection>
</Section>

Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
<xi:include href="scmd-help.xml"/>
<xi:include href="scmd-login.xml"/>
<xi:include href="scmd-logout.xml"/>
<xi:include href="scmd-mail-test.xml"/>
<xi:include href="scmd-self.xml"/>
<xi:include href="scmd-set.xml"/>
<xi:include href="scmd-user-ban-create.xml"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,18 @@ public Set<IdAdminPermission> implies()
{
return Set.of();
}
},

/**
* A permission that allows testing the mail system.
*/

MAIL_TEST {
@Override
public Set<IdAdminPermission> implies()
{
return Set.of();
}
};

private static final Set<IdAdminPermission> ADMIN_WRITE_EMAIL_IMPLIES_SELF =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright © 2023 Mark Raynsford <code@io7m.com> https://www.io7m.com
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

package com.io7m.idstore.model;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Objects;
import java.util.regex.Pattern;

/**
* A short human-readable token.
*
* @param value The token string
*/

public record IdShortHumanToken(String value)
{
/**
* The pattern that defines a valid token.
*/

public static final Pattern VALID_NUMBER =
Pattern.compile("[0-9]{6}");

/**
* A generic token.
*
* @param value The token string
*/

public IdShortHumanToken
{
Objects.requireNonNull(value, "value");

if (!VALID_NUMBER.matcher(value).matches()) {
throw new IdValidityException(
"Token value %s must match %s".formatted(value, VALID_NUMBER));
}
}

/**
* Generate a random token.
*
* @param random The secure random instance
*
* @return A random token
*/

public static IdShortHumanToken generate(
final SecureRandom random)
{
Objects.requireNonNull(random, "random");

final var builder = new StringBuilder(6);
for (int index = 0; index < 6; ++index) {
builder.append(random.nextInt(10));
}
return new IdShortHumanToken(builder.toString());
}

/**
* Generate a random token, using a default strong RNG instance.
*
* @return A random token
*/

public static IdShortHumanToken generate()
{
try {
return generate(SecureRandom.getInstanceStrong());
} catch (final NoSuchAlgorithmException e) {
throw new IllegalStateException(e);
}
}

@Override
public String toString()
{
return this.value;
}
}

0 comments on commit fd8de14

Please sign in to comment.