Example #1
0
        public IActionResult GetRecentChannelEntries(
            [FromQuery] int count = 20,
            [FromQuery] int skip  = 0
            )
        {
            Ulid _id;

            {
                var id = HttpContext.User.Claims.Where(claim => claim.Type == "sub")
                         .Select(claim => claim.Value)
                         .Single();

                if (Ulid.TryParse(id, out var res))
                {
                    _id = res;
                }
                else
                {
                    return(BadRequest());
                }
            }

            try
            {
                return(Ok(this.db.GetRecentChannels(_id, count, skip)));
            }
            catch (ArgumentOutOfRangeException e)
            {
                return(BadRequest(e));
            }
        }
Example #2
0
        public async Task <IActionResult> Proceed(string linkId)
        {
            var _userId = HttpContext.User.Claims.Where(claim => claim.Type == "sub")
                          .Select(claim => claim.Value)
                          .Single();

            if (!Ulid.TryParse(_userId, out var userId))
            {
                return(BadRequest(new ErrorResult(
                                      "not deserialized", $"'{_userId}' is not a valid Ulid")));
            }


            var link = await db.GetInvitationLink(linkId);

            if (link != null)
            {
                var result = await db.AddUserToChannel(
                    userId,
                    link.ChannelId,
                    link.DefaultPermission,
                    true);

                // TODO: return the user with basic information about the channel added
                return(result switch
                {
                    AddResult.Success => NoContent(),
                    AddResult.AlreadyExist => Conflict(
                        new ErrorResult(
                            "User already in channel"
                            )
                        ),
                    _ => BadRequest(new ErrorResult("Unable to add user to channel"))
                });
Example #3
0
        public async Task <IActionResult> GetMultipleChannelMessages(
            [FromQuery(Name = "channelId")] List <string> channelIds,
            [FromQuery] string start,
            [FromQuery] int count      = 20,
            [FromQuery] bool ascending = false
            )
        {
            List <Ulid>   channelUlids;
            List <string> failedUlids;

            {
                var channelUlidIntermediate = channelIds.Select(channelId =>
                {
                    var res = Ulid.TryParse(channelId, out var ulid);
                    return(res, ulid, channelId);
                }).GroupBy(entry => entry.res).ToDictionary(group => group.Key);
                channelUlids = channelUlidIntermediate[true].Select(entry => entry.ulid).ToList();
                failedUlids  = channelUlidIntermediate[false].Select(entry => entry.channelId).ToList();
            }

            if (!Ulid.TryParse(start, out var startId))
            {
                return(BadRequest());
            }

            var res = await db.GetMessageFromChannelsAsync(
                channelUlids,
                startId,
                count,
                ascending,
                includeChannelName : true);

            return(Ok(res));
        }
Example #4
0
        public async Task <IActionResult> AddChannel(
            [FromBody] AddChannelRequest req)
        {
            Ulid userId;

            {
                var id = HttpContext.User.Claims.Where(claim => claim.Type == "sub")
                         .Select(claim => claim.Value)
                         .Single();

                if (Ulid.TryParse(id, out var res))
                {
                    userId = res;
                }
                else
                {
                    return(BadRequest(new ErrorResult(
                                          "Bad userId", "Malformed bearer token. Please authorize again!")));
                }
            }

            if (req.channelName != null && await db.ChannelNameExists(req.channelName))
            {
                return(BadRequest(
                           new ErrorResult(
                               "Channel already exists", "The name of this channel is already taken")));
            }

            return(Ok(
                       await this.db.NewMailingChannel(
                           req.channelName, req.isPublic, req.channelTitle, userId)));
        }
Example #5
0
        public void Ulid_TryParse_WorksCorrectly()
        {
            Ulid r1;

            Assert.IsFalse(Ulid.TryParse("X", out r1));
            Assert.AreEqual(r1, Ulid.Empty);

            Ulid r2;

            Assert.IsFalse(Ulid.TryParse(string.Empty, out r2));
            Assert.AreEqual(r2, Ulid.Empty);

            Ulid r3;

            Assert.IsFalse(Ulid.TryParse(null, out r3));
            Assert.AreEqual(r3, Ulid.Empty);

            Ulid r4;

            Assert.IsTrue(Ulid.TryParse(Ulid.MinValue.ToString(), out r4));
            Assert.IsTrue(Ulid.MinValue == r4);

            Ulid r5;

            Assert.IsTrue(Ulid.TryParse(Ulid.MaxValue.ToString(), out r5));
            Assert.IsTrue(Ulid.MaxValue == r5);

            Ulid r6;
            var  target = Ulid.NewUlid(KNOWNTIMESTAMP_DTO, new FakeUlidRng());

            Assert.IsTrue(Ulid.TryParse(KNOWNTIMESTAMP_STRING + KNOWNRANDOMSEQ_STRING, out r6));
            Assert.AreEqual(target, r6);
        }
Example #6
0
 public async Task <bool> ChannelNameExists(string name)
 {
     if (Ulid.TryParse(name, out var id))
     {
         return(await db.Channels.AsQueryable().AnyAsync(
                    ch => ch.ChannelUsername == name || ch.ChannelId == id));
     }
     else
     {
         return(await db.Channels.AsQueryable()
                .AnyAsync(ch => ch.ChannelUsername == name));
     }
 }
Example #7
0
        public void TestTryParseExceptions()
        {
            //one too few chars
            Assert.False(Ulid.TryParse("0000000000000000000000000", out _));

            //one too many chars
            Assert.False(Ulid.TryParse("000000000000000000000000000", out _));

            //null
            Assert.False(Ulid.TryParse(null, out _));

            //Invalid char
            Assert.False(Ulid.TryParse("000*0000000000000000000000", out _));
        }
Example #8
0
 public async Task <HatoChannel?> GetChannelFromUsernameOrId(string name)
 {
     if (Ulid.TryParse(name, out var id))
     {
         return(await db
                .Channels
                .AsQueryable()
                .SingleOrDefaultAsync(
                    ch => ch.ChannelId == id ||
                    ch.ChannelUsername == name));
     }
     else
     {
         return(await db.Channels.AsQueryable()
                .SingleOrDefaultAsync(ch => ch.ChannelUsername == name));
     }
 }
Example #9
0
        public async Task <IActionResult> GetUserById(string id)
        {
            Ulid _id;
            {
                if (Ulid.TryParse(id, out var res))
                {
                    _id = res;
                }
                else
                {
                    return(BadRequest());
                }
            }

            var user = await this.db.GetUser(_id);

            return(Ok(user));
        }
Example #10
0
        public async Task <IActionResult> GetChannel([FromRoute] string id)
        {
            // throws exception on error
            Ulid?_id;
            { if (Ulid.TryParse(id, out var res))
              {
                  _id = res;
              }
              else
              {
                  _id = null;
              } }
            var name = id;

            if (_id != null)
            {
                var res = await this._db.GetChannel(_id.Value);

                if (res != null)
                {
                    return(Ok(res));
                }
                else
                {
                    return(NotFound());
                }
            }
            else
            {
                var res = await this._db.GetChannelFromUsername(name);

                if (res != null)
                {
                    return(Ok(res));
                }
                else
                {
                    return(NotFound());
                }
            }
        }
Example #11
0
        public void Ulid_TryParse_WorksCorrectly()
        {
            Assert.IsFalse(Ulid.TryParse("X", out var r1));
            Assert.AreEqual(Ulid.Empty, r1);

            Assert.IsFalse(Ulid.TryParse(string.Empty, out var r2));
            Assert.AreEqual(Ulid.Empty, r2);

            Assert.IsFalse(Ulid.TryParse(null, out var r3));
            Assert.AreEqual(Ulid.Empty, r3);

            Assert.IsTrue(Ulid.TryParse(Ulid.MinValue.ToString(), out var r4));
            Assert.IsTrue(Ulid.MinValue == r4);

            Assert.IsTrue(Ulid.TryParse(Ulid.MaxValue.ToString(), out var r5));
            Assert.IsTrue(Ulid.MaxValue == r5);

            var target = Ulid.NewUlid(KNOWNTIMESTAMP_DTO, new FakeUlidRng());

            Assert.IsTrue(Ulid.TryParse(KNOWNTIMESTAMP_STRING + KNOWNRANDOMSEQ_STRING, out var r6));
            Assert.AreEqual(r6, target);
        }
Example #12
0
        public async Task <IActionResult> GetMe()
        {
            Ulid _id;
            {
                var id = HttpContext.User.Claims.Where(claim => claim.Type == "sub")
                         .Select(claim => claim.Value)
                         .Single();

                if (Ulid.TryParse(id, out var res))
                {
                    _id = res;
                }
                else
                {
                    return(BadRequest());
                }
            }

            var user = await this.db.GetUser(_id);

            return(Ok(user));
        }
Example #13
0
        public async Task <IActionResult> JoinChannel(
            [FromRoute] string id
            )
        {
            var userId = HttpContext.User.Claims.Where(claim => claim.Type == "sub")
                         .Select(claim => claim.Value)
                         .Single();

            if (!Ulid.TryParse(id, out var _channelId))
            {
                return(BadRequest(new ErrorResult(
                                      "not deserialized", $"'{id}' is not a valid Ulid")));
            }

            if (!Ulid.TryParse(userId, out var _userId))
            {
                return(BadRequest(new ErrorResult(
                                      "not deserialized", $"'{userId}' is not a valid Ulid")));
            }

            // Regular join without invitation
            var result = await this._db.AddUserToChannel(
                _userId,
                _channelId,
                addToPrivateChannel : false);

            return(result switch
            {
                AddResult.Success => NoContent(),
                AddResult.AlreadyExist => BadRequest(new ErrorResult(
                                                         "resource already exists",
                                                         "The user has already been in the channel")),
                _ => BadRequest(new ErrorResult(
                                    "Unable to join into channel.",
                                    "Either it doesn't exist at all or it's private.")),
            });
Example #14
0
 void UlidTryParseFailsForInvalidStrings()
 {
     Assert.False(Ulid.TryParse("1234", out _));
     Assert.False(Ulid.TryParse(Guid.NewGuid().ToString(), out _));
 }
Example #15
0
        private async void OnEmailRecv(EmailRecvEvent ev)
        {
            var email            = ev.email;
            var match            = Regex.Match(email.To, "(.*) <(?<name>.+)@.+>");
            var targetChannels   = new List <string?>();
            var targetChannelIds = targetChannels.Select <string?, Ulid?>(str => { if (Ulid.TryParse(str, out Ulid res))
                                                                                   {
                                                                                       return(res);
                                                                                   }
                                                                                   else
                                                                                   {
                                                                                       return(null);
                                                                                   } }).Where(id => id != null).ToList();

            while (match.Success)
            {
                targetChannels.Add(match.Groups["name"].Value);
                match = match.NextMatch();
            }

            var origin         = Regex.Match(email.From, "^(?<nick>.*) <(?<email>.+)>$").Groups;
            var senderEmail    = origin["email"].Value;
            var senderNickname = origin["nick"].Value;

            var allTargetChannels = await this.db.db.Channels
                                    .AsQueryable().Where(ch => targetChannelIds.Contains(ch.ChannelId) ||
                                                         targetChannels.Contains(ch.ChannelUsername)).ToListAsync();

            var allTargetChannelIds = allTargetChannels.Select(ch => ch.ChannelId).ToList();

            var msg = new HatoMessage()
            {
                MsgId = Ulid.Empty,
                // WARN: All timestamps represent the time when this email ARRIVES at the server
                // Timestamp = email.Date,
                SenderEmail    = senderEmail,
                SenderNickname = senderNickname,
                Title          = email.Subject,
                BodyHtml       = email.BodyHtml,
                BodyPlain      = email.BodyPlain,
            };

            var attachments = await UploadAndSaveAttachments(email);

            msg.Attachments = attachments;

            foreach (var channel in allTargetChannels)
            {
                msg._Channel  = channel;
                msg.ChannelId = channel.ChannelId;
                await SaveEmail(msg);
            }

            List <IGrouping <string, string> > allTargetEmails = await GetEmailsFromChannelIds(allTargetChannelIds);

            await SendEmailAndFailure(senderEmail, senderNickname, msg, allTargetEmails);

            await db.db.SaveChangesAsync();
        }
Example #16
0
 public void TestTryParseDefault()
 {
     Assert.True(Ulid.TryParse("00000000000000000000000000", out Ulid valid0));
     Assert.Equal(default, valid0);