1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 10:43:04 +08:00

Add registration API call and related error handling

This commit is contained in:
Dean Herbert 2018-12-05 17:13:22 +09:00
parent f3f449c749
commit 1ca00f6662
4 changed files with 142 additions and 22 deletions

View File

@ -5,7 +5,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Net; using System.Net;
using System.Net.Http;
using System.Threading; using System.Threading;
using Newtonsoft.Json.Linq;
using osu.Framework.Configuration; using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Logging; using osu.Framework.Logging;
@ -189,13 +191,37 @@ namespace osu.Game.Online.API
this.password = password; this.password = password;
} }
public void CreateAccount(string email, string username, string password) public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
{ {
Debug.Assert(State == APIState.Offline); Debug.Assert(State == APIState.Offline);
var req = new RegistrationRequest(); var req = new RegistrationRequest
{
Url = $@"{Endpoint}/users",
Method = HttpMethod.Post,
Username = username,
Email = email,
Password = password
};
req.Perform(); try
{
req.Perform();
}
catch (Exception e)
{
try
{
return JObject.Parse(req.ResponseString).SelectToken("form_error", true).ToObject<RegistrationRequest.RegistrationRequestErrors>();
}
catch
{
// if we couldn't deserialize the error message let's throw the original exception outwards.
throw e;
}
}
return null;
} }
/// <summary> /// <summary>

View File

@ -1,11 +1,12 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
using osu.Framework.IO.Network; using osu.Framework.IO.Network;
namespace osu.Game.Online.API namespace osu.Game.Online.API
{ {
internal class RegsitrationRequest : JsonWebRequest<OAuthToken> public class RegistrationRequest : WebRequest
{ {
internal string Username; internal string Username;
internal string Email; internal string Email;
@ -13,11 +14,28 @@ namespace osu.Game.Online.API
protected override void PrePerform() protected override void PrePerform()
{ {
AddParameter("user", Username); AddParameter("user[username]", Username);
AddParameter("user_email", Email); AddParameter("user[user_email]", Email);
AddParameter("password", Password); AddParameter("user[password]", Password);
base.PrePerform(); base.PrePerform();
} }
public class RegistrationRequestErrors
{
public UserErrors User;
public class UserErrors
{
[JsonProperty("username")]
public string[] Username;
[JsonProperty("user_email")]
public string[] Email;
[JsonProperty("password")]
public string[] Password;
}
}
} }
} }

View File

@ -0,0 +1,35 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Game.Graphics.Containers;
using osuTK.Graphics;
namespace osu.Game.Overlays.AccountCreation
{
public class ErrorTextFlowContainer : OsuTextFlowContainer
{
private readonly List<Drawable> errorDrawables = new List<Drawable>();
public ErrorTextFlowContainer()
: base(cp => { cp.TextSize = 12; })
{
}
public void ClearErrors()
{
errorDrawables.ForEach(d => d.Expire());
}
public void AddErrors(string[] errors)
{
ClearErrors();
if (errors == null) return;
foreach (var error in errors)
errorDrawables.AddRange(AddParagraph(error, cp => cp.Colour = Color4.Red));
}
}
}

View File

@ -1,7 +1,9 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
@ -24,9 +26,9 @@ namespace osu.Game.Overlays
{ {
public class AccountCreationOverlay : OsuFocusedOverlayContainer, IOnlineComponent public class AccountCreationOverlay : OsuFocusedOverlayContainer, IOnlineComponent
{ {
private OsuTextFlowContainer usernameDescription; private ErrorTextFlowContainer usernameDescription;
private OsuTextFlowContainer emailAddressDescription; private ErrorTextFlowContainer emailAddressDescription;
private OsuTextFlowContainer passwordDescription; private ErrorTextFlowContainer passwordDescription;
private OsuTextBox usernameTextBox; private OsuTextBox usernameTextBox;
private OsuTextBox emailTextBox; private OsuTextBox emailTextBox;
@ -43,8 +45,6 @@ namespace osu.Game.Overlays
Size = new Vector2(620, 450); Size = new Vector2(620, 450);
Anchor = Anchor.Centre; Anchor = Anchor.Centre;
Origin = Anchor.Centre; Origin = Anchor.Centre;
State = Visibility.Visible;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
@ -114,9 +114,10 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
TabbableContentContainer = this TabbableContentContainer = this
}, },
usernameDescription = new OsuTextFlowContainer(cp => { cp.TextSize = 12; }) usernameDescription = new ErrorTextFlowContainer
{ {
RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}, },
emailTextBox = new OsuTextBox emailTextBox = new OsuTextBox
{ {
@ -125,9 +126,10 @@ namespace osu.Game.Overlays
Text = api.ProvidedUsername ?? string.Empty, Text = api.ProvidedUsername ?? string.Empty,
TabbableContentContainer = this TabbableContentContainer = this
}, },
emailAddressDescription = new OsuTextFlowContainer(cp => { cp.TextSize = 12; }) emailAddressDescription = new ErrorTextFlowContainer
{ {
RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}, },
passwordTextBox = new OsuPasswordTextBox passwordTextBox = new OsuPasswordTextBox
{ {
@ -135,9 +137,10 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.X, RelativeSizeAxes = Axes.X,
TabbableContentContainer = this, TabbableContentContainer = this,
}, },
passwordDescription = new OsuTextFlowContainer(cp => { cp.TextSize = 12; }) passwordDescription = new ErrorTextFlowContainer
{ {
RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
}, },
new Container new Container
{ {
@ -175,9 +178,7 @@ namespace osu.Game.Overlays
characterCheckText = passwordDescription.AddText("8 characters long"); characterCheckText = passwordDescription.AddText("8 characters long");
passwordDescription.AddText(". Choose something long but also something you will remember, like a line from your favourite song."); passwordDescription.AddText(". Choose something long but also something you will remember, like a line from your favourite song.");
passwordTextBox.Current.ValueChanged += text => { passwordTextBox.Current.ValueChanged += text => { characterCheckText.ForEach(s => s.Colour = text.Length == 0 ? Color4.White : Interpolation.ValueAt(text.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In)); };
characterCheckText.ForEach(s => s.Colour = text.Length == 0 ? Color4.White : Interpolation.ValueAt(text.Length, Color4.OrangeRed, Color4.YellowGreen, 0, 8, Easing.In));
};
} }
private void performRegistration() private void performRegistration()
@ -191,7 +192,47 @@ namespace osu.Game.Overlays
return; return;
} }
api.CreateAccount(emailTextBox.Text, usernameTextBox.Text, passwordTextBox.Text); usernameDescription.ClearErrors();
emailAddressDescription.ClearErrors();
passwordDescription.ClearErrors();
Task.Run(() =>
{
bool success;
RegistrationRequest.RegistrationRequestErrors errors = null;
try
{
errors = api.CreateAccount(emailTextBox.Text, usernameTextBox.Text, passwordTextBox.Text);
success = errors == null;
}
catch (Exception)
{
success = false;
}
Schedule(() =>
{
if (!success)
{
if (errors != null)
{
usernameDescription.AddErrors(errors.User.Username);
emailAddressDescription.AddErrors(errors.User.Email);
passwordDescription.AddErrors(errors.User.Password);
}
else
{
passwordDescription.AddErrors(new[] { "Something happened... but we're not sure what." });
}
registerShake.Shake();
return;
}
api.Login(emailTextBox.Text, passwordTextBox.Text);
});
});
} }
private OsuTextBox nextUnfilledTextbox() private OsuTextBox nextUnfilledTextbox()