public async Task <IActionResult> DoGroupPatch(string groupRef, [FromBody] JObject data) { var system = await ResolveSystem("@me"); var group = await ResolveGroup(groupRef); if (group == null) { throw Errors.GroupNotFound; } if (group.System != system.Id) { throw Errors.NotOwnGroupError; } var patch = GroupPatch.FromJson(data); patch.AssertIsValid(); if (patch.Errors.Count > 0) { throw new ModelParseError(patch.Errors); } var newGroup = await _repo.UpdateGroup(group.Id, patch); return(Ok(newGroup.ToJson(LookupContext.ByOwner))); }
public async Task <IActionResult> GroupCreate([FromBody] JObject data) { var system = await ResolveSystem("@me"); var config = await _repo.GetSystemConfig(system.Id); // Check group cap var existingGroupCount = await _repo.GetSystemGroupCount(system.Id); var groupLimit = config.GroupLimitOverride ?? Limits.MaxGroupCount; if (existingGroupCount >= groupLimit) { throw Errors.GroupLimitReached; } var patch = GroupPatch.FromJson(data); patch.AssertIsValid(); if (!patch.Name.IsPresent) { patch.Errors.Add(new ValidationError("name", "Key 'name' is required when creating new group.")); } if (patch.Errors.Count > 0) { throw new ModelParseError(patch.Errors); } using var conn = await _db.Obtain(); using var tx = await conn.BeginTransactionAsync(); var newGroup = await _repo.CreateGroup(system.Id, patch.Name.Value, conn); newGroup = await _repo.UpdateGroup(newGroup.Id, patch, conn); _ = _dispatch.Dispatch(newGroup.Id, new UpdateDispatchData() { Event = DispatchEvent.CREATE_GROUP, EventData = patch.ToJson(), }); await tx.CommitAsync(); return(Ok(newGroup.ToJson(LookupContext.ByOwner))); }
public async Task <IActionResult> BulkGroupPrivacy([FromBody] JObject inner) { HttpContext.Items.TryGetValue("SystemId", out var systemId); if (systemId == null) { throw Errors.GenericAuthError; } var data = new JObject(); data.Add("privacy", inner); var patch = GroupPatch.FromJson(data); patch.AssertIsValid(); if (patch.Errors.Count > 0) { throw new ModelParseError(patch.Errors); } await _db.ExecuteQuery(patch.Apply(new Query("groups").Where("system", systemId))); return(NoContent()); }
private async Task ImportGroup(JObject group) { var id = group.Value <string>("id"); var name = group.Value <string>("name"); var(found, isHidExisting) = TryGetExistingGroup(id, name); var isNewGroup = found == null; var referenceName = isHidExisting ? id : name; _logger.Debug( "Importing group with identifier {FileId} to system {System} (is creating new group? {IsCreatingNewGroup})", referenceName, _system.Id, isNewGroup ); var patch = GroupPatch.FromJson(group); patch.AssertIsValid(); if (patch.Errors.Count > 0) { var err = patch.Errors[0]; if (err is FieldTooLongError) { throw new ImportException($"Field {err.Key} in group {name} is too long " + $"({(err as FieldTooLongError).ActualLength} > {(err as FieldTooLongError).MaxLength})."); } if (err.Text != null) { throw new ImportException($"group {name}: {err.Text}"); } throw new ImportException($"Field {err.Key} in group {name} is invalid."); } var groupId = found; if (isNewGroup) { var newGroup = await _repo.CreateGroup(_system.Id, patch.Name.Value, _conn); groupId = newGroup.Id; } _knownGroupIdentifiers[id] = groupId.Value; await _repo.UpdateGroup(groupId.Value, patch, _conn); var groupMembers = group.Value <JArray>("members"); var currentGroupMembers = (await _conn.QueryAsync <MemberId>( "select member_id from group_members where group_id = @groupId", new { groupId = groupId.Value } )).ToList(); await using (var importer = _conn.BeginBinaryImport("copy group_members (group_id, member_id) from stdin (format binary)")) { foreach (var memberIdentifier in groupMembers) { if (!_knownMemberIdentifiers.TryGetValue(memberIdentifier.ToString(), out var memberId)) { throw new Exception( $"Attempted to import group member with member identifier {memberIdentifier} but could not find a recently imported member with this id!"); } if (currentGroupMembers.Contains(memberId)) { continue; } await importer.StartRowAsync(); await importer.WriteAsync(groupId.Value.Value, NpgsqlDbType.Integer); await importer.WriteAsync(memberId.Value, NpgsqlDbType.Integer); } await importer.CompleteAsync(); } }