-
-
Notifications
You must be signed in to change notification settings - Fork 0
How to Develop
This document will walk you through how to set up a local development environment for Agony Forge. By following this guide you'll be able to log into the demo MUD on your local machine and see how it works. You will also be able to make changes to the code and test them.
These instructions will not be sufficient by themselves to get a game on the internet for others to play. There are some additional steps to get there, such as creating an AWS hosted message queue, an AWS hosted DynamoDB, enabling HTTPS for a secure connection, and how to run the server on an actual server instead of your own computer. We'll tackle those things in different articles later on.
Our goal for this walkthrough is simple. We're going to set up the bare minimum resources required in AWS while keeping costs to an absolute minimum. At the end you will be able to log into your MUD that is running on your own computer using your Amazon account. Please be sure to check AWS pricing whenever you set up anything new, to avoid surprises. At the time of writing this, the costs for everything we'll need would be under a dollar a month in most regions.
Here is what we're going to set up:
- A security profile on the Amazon Developer website.
- A secret in AWS Secrets Manager, to avoid storing it in GitHub.
- An AWS Cognito User Pool to authenticate users and store their information.
- The configuration for Agony Forge demo MUD itself.
Here is what you'll need to have before we get started:
- An AWS account, and some familiarity with Cloud Formation.
- Git, and some familiarity with how to clone a project from GitHub.
- Docker, and some familiarity with how to use docker-compose.
- JDK 17 or better (I use Corretto, but other JVMs should work too).
Your security profile is how you tell Amazon about your application that you want Amazon accounts to be able to log into. Once you have it set up they will give you a client ID and a client secret which are a randomly generated username and password for your application. They are what we will use to link AWS to Amazon so Amazon customers can log into your MUD.
Head over to the developer website and log in with your Amazon username and password. It's the one you use to shop on Amazon, not the one you use for AWS. Once you have signed in, look for "Login with Amazon". It should look something like this:
Click the "Create a new Security Profile" button! On the next page you'll need to choose a name and description. Since this is a local development copy of your MUD the names don't matter that much. The URL to a privacy policy is also a required field, but again since this is just a development application it doesn't need to be a "real" privacy policy.
After filling out the form it should take you back to the list of Security Profiles, and you should see the one you just created on the list. For now go into it and look at the "Web Settings" tab to find the Client ID and Client Secret. We'll need those for setting up Cognito, and after Cognito is set up we'll need to come back here and add one more setting.
Now that we have the Client ID and Client Secret from Amazon, we need to store them safely in your AWS account. Head over to AWS Secrets Manager to get started, and click the "Store a New Secret" button over on the right side.
We're going to select "Other Type of Secret" so we can store both the Client ID and Client Secret as two Key/Value Pairs inside the same entry in Secrets Manager. Finally, click "Next" at the bottom to go to the next step!
Now that you've set the contents of your secret, you need to give it a name and a description. Try to choose something descriptive and accurate such as "Amazon Client Credentials" and a description to remind you that it's the Amazon client credentials for your MUD. When you've got it filled out, click "Next" at the bottom.
The last step configures automatic rotation for secrets, which is a good idea if they're passwords, but in this case we don't need to. Don't change anything on this page! Just click "Next"!
The final page will let you review everything before you commit to it. If everything looks reasonable, click "Store" at the bottom to store your secret.
Now that we have the Client ID and secret securely stored in Secrets Manager, we're ready to run the Cloud Formation template to create a Cognito User Pool. The User Pool will store all our user accounts and automatically handles the connection between the MUD and users authenticating through the Amazon website. There are a ton of settings on User Pools and they can be very complicated but using a Cloud Formation template will let us skip almost all of the configuration steps.
Find /cloudformation/cognito.yaml
in the Agony Forge project and head over to Cloud Formation in the AWS console. Click on "Create stack" and pick "With new resources (standard)" to start creating a new Cloud Formation stack. We're going to upload the template from our computer. Select the file and click "Next".
The next page will ask for a name for the stack, and list all the template's parameters. There are default values but we are going to have to change some of them. Let's go through them one at a time.
Variable Name | Description |
---|---|
Cloud Formation Stack Name | Just choose something descriptive that you'll understand later, like agony-forge-cognito . |
AwsClientId | In Secrets Manager you created two Key/Value Pairs. This is the key for the Client ID. In the screen shot I just called it clientId . |
AwsClientSecret | In Secrets Manager this is the key for Client Secret. In the screen shot I called it clientSecret . |
CognitoDomain | This is a prefix for a domain name that will be created by AWS. You need to choose something unique, like the name of your MUD, your name, or even some random letters. It just can't be the same as one somebody else is already using. |
DefaultRedirectURI | The default here is fine. This is where users get redirected to after successfully logging in. |
LogoutURLs | The default here is fine. This is where users get redirected to after logging out. |
OAuthCallbackURLs | The default here is fine. This is a list of URLs that are allowed for Cognito to redirect users to as part of the OAuth2 flow. |
SecretName | In Secrets Manager you gave your secret a name on the second page. Put that name here so Cloud Formation can find the secret. |
UserPoolName | The default here is fine. The name of the Cognito User Pool to create. |
Once the parameters are all filled out, click "Next"! You shouldn't need to change anything on the next two pages, so click "Next" on both of them. On the final page the button is "Submit" instead. If you're ready to run the template, click the button!
In the "Events" tab of your Cloud Formation stack you can watch the progress as everything gets created. This stack shouldn't take very long to complete.
One common error at this point could be that you chose a CognitoDomain
that is already in use. If you get an error message indicating that, or if there is some other error, you will need to delete the stack and re-create it. If you get stuck at this point, please feel free to ask for help by opening an issue or a discussion here on GitHub.
When it says that it has completed successfully, you can move over to the "Resources" tab and go visit your new User Pool by clicking the link to it.
We have one small change we need to make to the Amazon Security Profile now that we have successfully created the Cognito User Pool. Go back to your Security Profile, click the "Web Settings" tab, and edit it. You will need to add a URL to "Allowed Return URLs". These are a list of URLs that Amazon is allowed to redirect users to after completing the OAuth flow. The URL you need to add is https://REPLACE.auth.REGION.amazoncognito.com/oauth2/idpresponse
where "REPLACE" is the value you chose for CognitoDomain
in your Cloud Formation template and "REGION" is the name of the region where you created your User Pool, such as "us-west-2".
Finally! We have all the Amazon and AWS stuff we need. We just have a little configuration left to do locally before we can run the demo MUD.
First, make a copy of mud.EXAMPLE.env
in the root directory of the project, and name the copy mud.env
. This file sets environment variables that will be available to Spring inside its Docker container. mud.env
is included in .gitignore
to protect it from being pushed to GitHub but please be cautious because it will contain secrets that should never be included in version control.
The only section we need to worry about in mud.env
is the bottom section. Everything else is all ready to go for local development. There are two sets of variables in the bottom section.
Variables beginning with SPRING_SECURITY_OAUTH2_CLIENT_REGISTRATION_COGNITO_...
:
Variable Name | Description |
---|---|
CLIENTID | This is the client ID from your Amazon Security Profile. |
CLIENTSECRET | This is the client secret from your Amazon Security Profile. |
SCOPE | Always equal to "openid". |
REDIRECTURI | The default value is fine here. This is where the OAuth flow will redirect users to when they begin the login process. |
CLIENTNAME | The name of your Cognito User Pool with "-client" added to the end. |
LOGOUTURL | Replace "agonyforge" in this URL with the domain name prefix you chose for the CognitoDomain parameter of the Cloud Formation template. Also, replace the us-west-2 region with the AWS region you created your User Pool in, if it is different. |
Variables beginning with SPRING_SECURITY_OAUTH2_CLIENT_PROVIDER_COGNITO_...
:
Variable Name | Description |
---|---|
ISSUERURI | The URI to your User Pool. It's going to be https://cognito-idp.REGION.amazonaws.com/ (replace REGION with your region) plus the "user pool ID" from AWS on the end. You can find this ID by going to Cognito, clicking into your User Pool and looking in the top section named "User pool overview". The "user pool ID" is clickable to copy the value into your clipboard. |
USERNAMEATTRIBUTE | Always equal to "username". This is the unique attribute Cognito uses to distinguish one user from another. Amazon assigns unique usernames for everyone, and this is how we know to use that instead of an email address or some other attribute. |
Time to see if everything worked! Build and run everything with:
$ ./gradlew clean build
$ docker-compose up
Pitest takes a long time to run, and you can skip it with ./gradlew clean build -x pitest
.
If you don't want any tests at all, try ./gradlew clean build -x test -x pitest
.
Once the logs stop scrolling, one of the last log messages should say something about a BrokerAvailabilityEvent
. That probably means everything is up and running! Try visiting http://localhost:8080 in your browser. If everything is working, you should see a screen with a Login button.
When you click the button for the first time, you'll get redirected to Amazon where it will ask you to log in. Then it will ask you to authorize connecting your application to your account. Finally, it will redirect you back to the MUD where you should now see the main menu.
Finally, if you run into any unexpected errors or other problems please feel free to open an issue or a discussion on GitHub. Try not to show any secrets in your post or if you take screenshots, and otherwise be as descriptive as you can. You are also welcome to join our Discord by clicking the badge at the top of the README.