...
 
......@@ -223,7 +223,7 @@ namespace divecomputer_test {
if (FileRadio.Checked) {
writer = new FileDiveWriter(SaveFileText.Text);
} else if(LogRadio.Checked) {
writer = new LittleLogDiveWriter(Session.WebAppSession.Token, CheckboxReadSinceLast.Checked);
writer = new LittleLogDiveWriter(Session.WebAppSession, CheckboxReadSinceLast.Checked);
} else {
throw new Exception("No target type selected");
}
......
......@@ -10,22 +10,23 @@ namespace DiveLogUploader {
public class WebserviceError: Exception, ISerializable {
public string error;
public string Error;
public HttpStatusCode Code;
public override string Message {
get { return error; }
get { return Error; }
}
public string GetMessage() {
return error;
return Error;
}
public WebserviceError(SerializationInfo info, StreamingContext context) : base() {
error = info.GetString("error");
Error = info.GetString("error");
}
public override string ToString() {
return "WebserviceError: " + error;
return "WebserviceError: " + Error;
}
}
......@@ -123,7 +124,9 @@ namespace DiveLogUploader {
using (var streamReader = new StreamReader(response.GetResponseStream())) {
using (var jsonReader = new JsonTextReader(streamReader)) {
if (response.StatusCode != HttpStatusCode.OK) {
throw serializer.Deserialize<WebserviceError>(jsonReader);
var err = serializer.Deserialize<WebserviceError>(jsonReader);
err.Code = response.StatusCode;
throw err;
}
obj = serializer.Deserialize<TOUT>(jsonReader);
}
......
......@@ -21,7 +21,7 @@ namespace LibDiveComputer {
[JsonIgnore]
public WebApplicationSession WebAppSession { get; private set; }
public string AppToken { get { return WebAppSession.Token; } }
public string AppToken { get { return WebAppSession.RefreshToken; } }
protected Configuration config;
protected bool isAcceptingChanges = false;
......
......@@ -41,7 +41,7 @@ namespace DiveLogUploader {
public UserData Data;
}
public class LoginResponseData {
public class TokenResponseData {
public string jwt;
}
......@@ -95,18 +95,16 @@ namespace DiveLogUploader {
public event ErrorEventHandler OnError;
private string _refreshToken;
private string _token;
private string _accessToken;
public string Token {
get { return _token; }
private set {
_token = value;
OnTokenChanged?.Invoke(this, new EventArgs { });
}
private UserData _data;
public string RefreshToken {
get { return _refreshToken; }
}
private UserData _data;
public UserData Data {
get { return _data; }
set {
......@@ -116,24 +114,30 @@ namespace DiveLogUploader {
}
public bool IsLoggedIn {
get { return Token != null; }
get { return _refreshToken != null; }
}
public WebApplicationSession() {
Token = null;
Data = null;
}
public async void SetToken(string token) {
Token = token;
await GetData();
_refreshToken = null;
_data = null;
}
public void Logout() {
Token = null;
_refreshToken = null;
_accessToken = null;
Data = null;
}
public async void SetToken(string token, bool getData = false) {
_refreshToken = token;
OnTokenChanged?.Invoke(this, new EventArgs { });
if (token != null) {
await GetData();
}
}
public async Task Login(string email, string password) {
var d = JToken.FromObject(new {
email = email,
......@@ -141,43 +145,143 @@ namespace DiveLogUploader {
});
try {
LoginResponseData dat;
dat = await Request.JsonAsync<LoginRequestData, LoginResponseData>(
BASE_URL + "auth/",
TokenResponseData dat;
dat = await Request.JsonAsync<LoginRequestData, TokenResponseData>(
BASE_URL + "auth/refresh-token",
HttpVerb.POST,
new LoginRequestData {
email = email,
password = password
},
TokenHeader(Token)
}
);
if (dat == null) {
Token = null;
SetToken(null);
return;
}
Token = dat.jwt;
await GetData();
SetToken(dat.jwt);
} catch(WebserviceError err) {
} catch (WebserviceError err) {
HandleError(err);
return;
}
}
private async Task GetData() {
public async Task<TOUT> DoRequestAsync<TOUT>(
string path,
HttpVerb verb
) {
if (_accessToken == null) {
await GetAccessTokenAsync();
}
try {
var result = await Request.JsonAsync<UserData>(
BASE_URL + "user/profile",
HttpVerb.GET,
TokenHeader(Token)
return await Request.JsonAsync<TOUT>(
BASE_URL + path,
verb,
TokenHeader(_accessToken)
);
} catch (WebserviceError ex) when (ex.Code == HttpStatusCode.Unauthorized) {
_accessToken = null;
return await DoRequestAsync<TOUT>(path, verb);
}
if (result == null) {
throw new Exception("Invalid response from server");
}
}
public TOUT DoRequest<TOUT>(
string path,
HttpVerb verb
) {
if (_accessToken == null) {
GetAccessToken();
}
try {
return Request.Json<TOUT>(
BASE_URL + path,
verb,
TokenHeader(_accessToken)
);
} catch (WebserviceError ex) when (ex.Code == HttpStatusCode.Unauthorized) {
_accessToken = null;
return DoRequest<TOUT>(path, verb);
}
}
public async Task<TOUT> DoRequestAsync<TIN, TOUT>(
string path,
HttpVerb verb,
TIN data = default(TIN)
) {
if (_accessToken == null) {
await GetAccessTokenAsync();
}
try {
var resp = await Request.JsonAsync<TIN, TOUT>(
BASE_URL + path,
verb,
data,
TokenHeader(_accessToken)
);
return resp;
} catch(WebserviceError ex) when (ex.Code == HttpStatusCode.Unauthorized) {
_accessToken = null;
return await DoRequestAsync<TIN, TOUT>(path, verb, data);
}
}
public TOUT DoRequest<TIN, TOUT>(
string path,
HttpVerb verb,
TIN data = default(TIN)
) {
if (_accessToken == null) {
GetAccessToken();
}
try {
var resp = Request.Json<TIN, TOUT>(
BASE_URL + path,
verb,
data,
TokenHeader(_accessToken)
);
return resp;
} catch (WebserviceError ex) when (ex.Code == HttpStatusCode.Unauthorized) {
_accessToken = null;
return DoRequest<TIN, TOUT>(path, verb, data);
}
}
private void GetAccessToken() {
var dat = Request.Json<TokenResponseData>(
BASE_URL + "auth/access-token",
HttpVerb.GET,
TokenHeader(_refreshToken)
);
_accessToken = dat.jwt;
}
private async Task GetAccessTokenAsync() {
var dat = await Request.JsonAsync<TokenResponseData>(
BASE_URL + "auth/access-token",
HttpVerb.GET,
TokenHeader(_refreshToken)
);
_accessToken = dat.jwt;
}
private async Task GetData() {
try {
var result = await DoRequestAsync<UserData>(
"user/profile",
HttpVerb.GET
);
Data = result;
Data = result ?? throw new Exception("Invalid response from server");
} catch(WebserviceError err) {
HandleError(err);
}
......
......@@ -36,23 +36,22 @@ namespace DiveLogUploader.Writers {
/// </summary>
/// <remarks>LittleDiveLog is a side project still under development</remarks>
public class LittleLogDiveWriter : AsyncDiveWriter {
protected string Token;
protected WebApplicationSession WebSession;
protected int ComputerId;
protected bool UseFingerprint;
public LittleLogDiveWriter(string token, bool useFingerprint): base() {
Token = token;
public LittleLogDiveWriter(WebApplicationSession sess, bool useFingerprint): base() {
WebSession = sess;
UseFingerprint = useFingerprint;
}
public override void SetDevice(Device d) {
base.SetDevice(d);
var resp = Request.Json<Computer, PostComputerResponse>(
WebApplicationSession.BASE_URL + "computer",
var resp = WebSession.DoRequest<Computer, PostComputerResponse>(
"computer",
HttpVerb.POST,
new Computer(d),
WebApplicationSession.TokenHeader(Token)
new Computer(d)
);
ComputerId = resp.computer_id;
......@@ -65,11 +64,10 @@ namespace DiveLogUploader.Writers {
protected override void ProcessDive(Dive d) {
var boundDive = new ComputerBoundDive(d, ComputerId);
var resp = Request.Json<Dive, PostDiveResponse>(
WebApplicationSession.BASE_URL + "dive",
var resp = WebSession.DoRequest<Dive, PostDiveResponse>(
"dive",
HttpVerb.POST,
boundDive,
WebApplicationSession.TokenHeader(Token)
boundDive
);
}
}
......