public async Task <OneOf <DbUser, NotFound> > UpdateAsync(string id, UserBase user, SnapshotArgs snapshot, CancellationToken cancellationToken = default) { var entry = await _client.GetEntryAsync <DbUser>(id, cancellationToken); do { if (entry.Value == null) { return(new NotFound()); } if (!entry.Value.TryApplyBase(user, _services)) { break; } }while (!await entry.TryUpdateAsync(cancellationToken)); if (snapshot != null) { await _snapshots.CreateAsync(entry.Value, snapshot, cancellationToken); } return(entry.Value); }
public async Task <DbUser> GetOrCreateUserAsync(DiscordOAuthUser user, CancellationToken cancellationToken = default) { await using (await _locker.EnterAsync($"oauth:discord:{user.Id}", cancellationToken)) { var entry = await GetByIdAsync(user.Id, cancellationToken); // if user already exists, update their info if (entry != null) { do { user.ApplyOn(entry.Value); }while (!await entry.TryUpdateAsync(cancellationToken)); } // otherwise create new user else { entry = _client.Entry(_users.MakeUserObject()); user.ApplyOn(entry.Value); await entry.CreateAsync(cancellationToken); await _snapshots.CreateAsync(entry.Value, new SnapshotArgs { Source = SnapshotSource.User, Committer = entry.Value, Event = SnapshotEvent.AfterCreation, Reason = $"Registered via Discord OAuth2 '{user.Username}'." }, cancellationToken); } return(entry.Value); } }