mirror of
https://github.com/elyby/chrly.git
synced 2024-12-23 05:30:06 +05:30
Rename the signature key param.
Rename the signature verification key endpoint. Update CHANGELOG and README files
This commit is contained in:
parent
6f148a8791
commit
2bc9f8eb57
@ -6,8 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased] - xxxx-xx-xx
|
||||
### Added
|
||||
- `/profile/{username}` endpoint.
|
||||
- `/signing-key` endpoint.
|
||||
- `/profile/{username}` endpoint, which returns a profile and its textures, equivalent of the Mojang's
|
||||
[UUID -> Profile + Skin/Cape endpoint](https://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape).
|
||||
- `/signature-verification-key` endpoint, which returns the public key in `DER` format for signature verification.
|
||||
|
||||
### Fixed
|
||||
- [#29](https://github.com/elyby/chrly/issues/29) If a previously cached UUID no longer exists,
|
||||
@ -15,7 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Use correct status code for error about empty response from Mojang's API.
|
||||
|
||||
### Changed
|
||||
- All skinsystem's endpoints are now returns `500` status code when an error occurred during request processing.
|
||||
- **BREAKING**: `/cloaks/{username}` and `/textures/{username}` endpoints will no longer return a cape if there are no
|
||||
textures for the requested username.
|
||||
- All endpoints are now returns `500` status code when an error occurred during request processing.
|
||||
|
||||
## [4.5.0] - 2020-05-01
|
||||
### Added
|
||||
|
84
README.md
84
README.md
@ -15,8 +15,9 @@ production ready.
|
||||
## Installation
|
||||
|
||||
You can easily install Chrly using [docker-compose](https://docs.docker.com/compose/). The configuration below (save
|
||||
it as `docker-compose.yml`) can be used to start a Chrly server. It relies on `CHRLY_SECRET` environment variable
|
||||
that you must set before running `docker-compose up -d`. Other possible variables are described below.
|
||||
it as `docker-compose.yml`) can be used to start a Chrly server. It relies on `CHRLY_SECRET` and `CHRLY_SIGNING_KEY`
|
||||
environment variables that you must set before running `docker-compose up -d`. Other possible variables are described
|
||||
below.
|
||||
|
||||
```yml
|
||||
version: '2'
|
||||
@ -33,6 +34,7 @@ services:
|
||||
- "80:80"
|
||||
environment:
|
||||
CHRLY_SECRET: replace_this_value_in_production
|
||||
CHRLY_SIGNING_KEY: base64:LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlCT3dJQkFBSkJBTmJVcFZDWmtNS3BmdllaMDhXM2x1bWRBYVl4TEJubVVEbHpIQlFIM0RwWWVmNVdDTzMyClREVTZmZUlKNThBMGxBeXdndFo0d3dpMmRHSE96LzFoQXZjQ0F3RUFBUUpBSXRheFNIVGU2UEtieUVVLzlweGoKT05kaFlSWXdWTExvNTZnbk1ZaGt5b0VxYWFNc2ZvdjhoaG9lcGtZWkJNdlpGQjJiRE9zUTJTYUorRTJlaUJPNApBUUloQVBzc1MwK0JSOXcwYk9kbWpHcW1kRTlOck41VUpRY09XMTNzMjkrNlF6VUJBaUVBMnZXT2VwQTVBcGl1CnBFQTNwd29HZGtWQ3JOU25uS2pEUXpEWEJucGQzL2NDSUVGTmQ5c1k0cVVHNEZXZFhONlJubVhMN1NqMHVaZkgKRE13enU4ckVNNXNCQWlFQWh2ZG9ETnFMbWJNZHEzYytGc1BTT2VMMWQyMVpwL0pLOGtiUHRGbUhOZjhDSVFEVgo2RlNaRHd2V2Z1eGFNN0JzeWNRT05rakRCVFBOdStscWN0SkJHbkJ2M0E9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
|
||||
|
||||
redis:
|
||||
image: redis:4.0-32bit
|
||||
@ -41,6 +43,11 @@ services:
|
||||
- ./data/redis:/data
|
||||
```
|
||||
|
||||
**Tip**: to generate a value for the `CHRLY_SIGNING_KEY` use the command below and then join it with a `base64:` prefix.
|
||||
```sh
|
||||
openssl genrsa 4096 | base64 -w0
|
||||
```
|
||||
|
||||
Chrly uses some volumes to persist storage for capes and Redis database. The configuration above mounts them to
|
||||
the host machine to do not lose data on container recreations.
|
||||
|
||||
@ -48,11 +55,10 @@ the host machine to do not lose data on container recreations.
|
||||
|
||||
Application's configuration is based on the environment variables. You can adjust config by modifying `environment` key
|
||||
inside your `docker-compose.yml` file. After value will have been changed, container should be stopped and recreated.
|
||||
If environment variables have been changed, Docker will automatically recreate the container, so you only need to `stop`
|
||||
and `up` it:
|
||||
If environment variables have been changed, Docker will automatically recreate the container, so you only need to `up`
|
||||
it again:
|
||||
|
||||
```sh
|
||||
docker-compose stop app
|
||||
docker-compose up -d app
|
||||
```
|
||||
|
||||
@ -182,7 +188,7 @@ If something goes wrong, you can always access logs by executing `docker-compose
|
||||
|
||||
## Endpoints
|
||||
|
||||
Each endpoint that accepts `username` as a part of an url takes it case insensitive. `.png` part can be omitted too.
|
||||
Each endpoint that accepts `username` as a part of an url takes it case-insensitive. The `.png` postfix can be omitted.
|
||||
|
||||
#### `GET /skins/{username}.png`
|
||||
|
||||
@ -220,11 +226,71 @@ That request is handy in case when your server implements authentication for a g
|
||||
operation) and you have to respond with hasJoined request with an actual user textures. You have to simply send request
|
||||
to the Chrly server and put the result in your hasJoined response.
|
||||
|
||||
#### `GET /profile/{username}`
|
||||
|
||||
This endpoint behaves exactly like the
|
||||
[Mojang's UUID -> Profile + Skin/Cape endpoint](https://wiki.vg/Mojang_API#UUID_-.3E_Profile_.2B_Skin.2FCape), but using
|
||||
a username instead of the UUID. Just like in the Mojang's API, you can append `?unsigned=false` part to URL to sign
|
||||
the `textures` property. If the textures for the requested username aren't found, it'll request them through the
|
||||
Mojang's API, but the Mojang's signature will be discarded and the textures will be re-signed using the signature key
|
||||
for your Chrly instance.
|
||||
|
||||
Response example:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "0f657aa8bfbe415db7005750090d3af3",
|
||||
"name": "username",
|
||||
"properties": [
|
||||
{
|
||||
"name": "textures",
|
||||
"signature": "signature value",
|
||||
"value": "base64 encoded value"
|
||||
},
|
||||
{
|
||||
"name": "chrly",
|
||||
"value": "how do you tame a horse in Minecraft?"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The base64 `value` string for the `textures` property decoded:
|
||||
|
||||
```json
|
||||
{
|
||||
"timestamp": 1614387238630,
|
||||
"profileId": "0f657aa8bfbe415db7005750090d3af3",
|
||||
"profileName": "username",
|
||||
"textures": {
|
||||
"SKIN": {
|
||||
"url": "http://example.com/skin.png"
|
||||
},
|
||||
"CAPE": {
|
||||
"url": "http://example.com/cape.png"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If username can't be found locally and can't be obtained from the Mojang's API, empty response with `204` status code
|
||||
will be sent.
|
||||
|
||||
Note that this endpoint will try to use the UUID for the stored profile in the database. This is an edge case, related
|
||||
to the situation where the user is available in the database but has no textures, which caused them to be retrieved
|
||||
from the Mojang's API.
|
||||
|
||||
#### `GET /signature-verification-key`
|
||||
|
||||
This endpoint returns a public key that can be used to verify textures signatures. The key is provided in `DER` format,
|
||||
so it can be used directly in the Authlib, without modifying the signature checking algorithm.
|
||||
|
||||
#### `GET /textures/signed/{username}`
|
||||
|
||||
Actually, it's [Ely.by](http://ely.by) feature called [Server Skins System](http://ely.by/server-skins-system), but if
|
||||
you have your own source of Mojang's signatures, then you can pass it with textures and it'll be displayed in response
|
||||
of this endpoint. Received response should be directly sent to the client without any modification via game server API.
|
||||
Actually, this is the [Ely.by](https://ely.by)'s feature called
|
||||
[Server Skins System](https://ely.by/server-skins-system), but if you have your own source of Mojang's signatures,
|
||||
then you can pass it with textures and it'll be displayed in response of this endpoint. Received response should be
|
||||
directly sent to the client without any modification via game server API.
|
||||
|
||||
Response example:
|
||||
|
||||
|
@ -20,11 +20,9 @@ var signer = di.Options(
|
||||
)
|
||||
|
||||
func newTexturesSigner(config *viper.Viper) (*Signer, error) {
|
||||
// TODO: add CHANGELOG and README entries about this variable
|
||||
// TODO: rename param variable
|
||||
keyStr := config.GetString("textures.signer.pem")
|
||||
keyStr := config.GetString("chrly.signing.key")
|
||||
if keyStr == "" {
|
||||
return nil, errors.New("texturesSigner.pem must be set in order to sign textures")
|
||||
return nil, errors.New("chrly.signing.key must be set in order to sign textures")
|
||||
}
|
||||
|
||||
var keyBytes []byte
|
||||
|
@ -71,7 +71,7 @@ func (ctx *Skinsystem) Handler() *mux.Router {
|
||||
router.HandleFunc("/skins", ctx.skinGetHandler).Methods(http.MethodGet)
|
||||
router.HandleFunc("/cloaks", ctx.capeGetHandler).Methods(http.MethodGet)
|
||||
// Utils
|
||||
router.HandleFunc("/signing-key", ctx.signingKeyHandler).Methods(http.MethodGet)
|
||||
router.HandleFunc("/signature-verification-key", ctx.signatureVerificationKeyHandler).Methods(http.MethodGet)
|
||||
|
||||
return router
|
||||
}
|
||||
@ -102,7 +102,6 @@ func (ctx *Skinsystem) skinGetHandler(response http.ResponseWriter, request *htt
|
||||
ctx.skinHandler(response, request)
|
||||
}
|
||||
|
||||
// TODO: write CHANGELOG about breaking change in this method
|
||||
func (ctx *Skinsystem) capeHandler(response http.ResponseWriter, request *http.Request) {
|
||||
profile, err := ctx.getProfile(request, true)
|
||||
if err != nil {
|
||||
@ -182,7 +181,6 @@ func (ctx *Skinsystem) signedTexturesHandler(response http.ResponseWriter, reque
|
||||
_, _ = response.Write(responseJson)
|
||||
}
|
||||
|
||||
// TODO: add README entry about this method
|
||||
func (ctx *Skinsystem) profileHandler(response http.ResponseWriter, request *http.Request) {
|
||||
profile, err := ctx.getProfile(request, true)
|
||||
if err != nil {
|
||||
@ -235,8 +233,7 @@ func (ctx *Skinsystem) profileHandler(response http.ResponseWriter, request *htt
|
||||
_, _ = response.Write(responseJson)
|
||||
}
|
||||
|
||||
// TODO: add README entry about this method
|
||||
func (ctx *Skinsystem) signingKeyHandler(response http.ResponseWriter, request *http.Request) {
|
||||
func (ctx *Skinsystem) signatureVerificationKeyHandler(response http.ResponseWriter, request *http.Request) {
|
||||
publicKey, err := ctx.TexturesSigner.GetPublicKey()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -1108,12 +1108,12 @@ var signingKeyTestsCases = []*skinsystemTestCase{
|
||||
},
|
||||
}
|
||||
|
||||
func (suite *skinsystemTestSuite) TestSigningKey() {
|
||||
func (suite *skinsystemTestSuite) TestSignatureVerificationKey() {
|
||||
for _, testCase := range signingKeyTestsCases {
|
||||
suite.RunSubTest(testCase.Name, func() {
|
||||
testCase.BeforeTest(suite)
|
||||
|
||||
req := httptest.NewRequest("GET", "http://chrly/signing-key", nil)
|
||||
req := httptest.NewRequest("GET", "http://chrly/signature-verification-key", nil)
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
if testCase.PanicErr != "" {
|
||||
|
Loading…
Reference in New Issue
Block a user