Пример #1
0
        public async Task <IActionResult> AuthPassword()
        {
            OAuthPasswordAuth auth;

            using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
            {
                auth = JsonConvert.DeserializeObject <OAuthPasswordAuth>(await reader.ReadToEndAsync());
            }

            var oauthClient = await DboAuthClient.GetClient(_ctx, auth.ClientId);

            if (oauthClient == null)
            {
                return(BadRequest(new { code = 403, message = "Client Doesn't exists!" }));
            }
            if (oauthClient.Secret != auth.ClientSecret)
            {
                return(BadRequest(new { code = 404, message = "invalid secret!" }));
            }

            var user = await DbUser.GetDbUser(_ctx, auth.Username);

            if (user == null || !user.IsPassword(Hex.ToHex(Crypto.GetMd5(auth.Password))))
            {
                return(BadRequest(new { code = 400, message = "Username or password is incorrect" }));
            }

            var key = Convert.FromBase64String(_cfg.Esc);

            return(Authorized(key, new[] { new Claim(ClaimTypes.Name, user.Id.ToString()) }));
        }
Пример #2
0
        public Sora(SoraDbContext ctx,
                    IServiceProvider provider,
                    PresenceService ps,
                    ChannelService cs,
                    EventManager ev
                    )
        {
            _provider = provider;
            _ctx      = ctx;
            _ps       = ps;
            _cs       = cs;
            _ev       = ev;

            #region DEFAULT COMMANDS

            RegisterCommandClass <RestrictCommand>();
            RegisterCommandClass <DebugCommand>();

            #endregion

            ctx.Migrate();

            // this will fail if bot already exists!
            DbUser.RegisterUser(_ctx, Permission.From(Permission.GROUP_ADMIN), "Sora", "*****@*****.**",
                                Crypto.RandomString(32), false, PasswordVersion.V2, 100);

            _dbUser = DbUser.GetDbUser(ctx, 100).Result;
        }
Пример #3
0
        public IActionResult UploadScreenshot([FromServices] Config config)
        {
            if (!Directory.Exists("data/screenshots"))
            {
                Directory.CreateDirectory("data/screenshots");
            }

            var screenshot = Request.Form.Files.GetFile("ss");
            var rand       = Crypto.RandomString(16);

            using var stream = screenshot.OpenReadStream();
            using var fs     = System.IO.File.OpenWrite($"data/screenshots/{rand}");

            Image.FromStream(stream)
            .Save(fs, ImageFormat.Jpeg);

            return(Ok($"http://{config.Server.ScreenShotHostname}/ss/{rand}"));
        }
Пример #4
0
        public async Task <IActionResult> AuthWebsite()
        {
            PasswordAuth auth;

            using (var reader = new StreamReader(Request.Body, Encoding.UTF8))
            {
                auth = JsonConvert.DeserializeObject <PasswordAuth>(await reader.ReadToEndAsync());
            }

            var user = await DbUser.GetDbUser(_ctx, auth.Username);

            if (user == null)
            {
                return(BadRequest(new { code = 401, message = "Username is incorrect!" }));
            }
            if (!user.IsPassword(Hex.ToHex(Crypto.GetMd5(auth.Password))))
            {
                return(BadRequest(new { code = 402, message = "Password is incorrect" }));
            }

            var key = Convert.FromBase64String(_cfg.Esc);

            return(Authorized(key, new[] { new Claim(ClaimTypes.Name, user.Id.ToString()) }));
        }
Пример #5
0
        public async Task <IActionResult> GetScoreResult(
            [FromQuery(Name = "v")] ScoreboardType type,
            [FromQuery(Name = "c")] string fileMd5,
            [FromQuery(Name = "f")] string f,
            [FromQuery(Name = "m")] PlayMode playMode,
            [FromQuery(Name = "i")] int i,
            [FromQuery(Name = "mods")] Mod mods,
            [FromQuery(Name = "us")] string us,
            [FromQuery(Name = "ha")] string pa,
            [FromServices] IServiceProvider serviceProvider,
            [FromServices] SoraDbContext ctx,
            [FromServices] DbContextPool <SoraDbContext> ctxPool,
            [FromServices] Pisstaube pisstaube,
            [FromServices] Cache cache)
        {
            try
            {
                var dbUser = await DbUser.GetDbUser(ctx, us);

                if (dbUser?.IsPassword(pa) != true)
                {
                    return(Ok("error: pass"));
                }

                var cacheHash =
                    Hex.ToHex(
                        Crypto.GetMd5(
                            $"{fileMd5}{playMode}{mods}{type}{dbUser.Id}{dbUser.UserName}"
                            )
                        );

                if (cache.TryGet($"sora:Scoreboards:{cacheHash}", out string cachedData))
                {
                    return(Ok(cachedData));
                }

                var scores = DbScore.GetScores(ctx, fileMd5, dbUser, playMode,
                                               type == ScoreboardType.Friends,
                                               type == ScoreboardType.Country,
                                               type == ScoreboardType.Mods,
                                               mods);

                BeatmapSet set      = null;
                DbScore    ownScore = null;

                var beatmap = DbBeatmap.GetBeatmap(ctx, fileMd5);
                if (beatmap == null)
                {
                    var apiSet = await pisstaube.FetchBeatmapSetAsync(fileMd5);

                    if (apiSet == null)
                    {
                        goto JustContinue;
                    }

                    var beatmaps         = DbBeatmap.FromBeatmapSet(apiSet).ToList();
                    var beatmapChecksums = beatmaps.Select(s => s.FileMd5);
                    var dbBeatmaps       =
                        ctx.Beatmaps.Where(rset => beatmapChecksums.Any(lFileMd5 => rset.FileMd5 == lFileMd5))
                        .ToList();

                    var pool = serviceProvider.GetRequiredService <DbContextPool <SoraDbContext> >();
                    Task.WaitAll(beatmaps.Select(rawBeatmap => Task.Run(async() =>
                    {
                        var context = pool.Rent();

                        try
                        {
                            var dbBeatmap = dbBeatmaps.FirstOrDefault(s => s.FileMd5 == rawBeatmap.FileMd5);

                            if (dbBeatmap != null && (dbBeatmap.Flags & DbBeatmapFlags.RankedFreeze) != 0)
                            {
                                rawBeatmap.RankedStatus = dbBeatmap.RankedStatus;
                                rawBeatmap.Flags        = dbBeatmap.Flags;
                            }

                            context.Beatmaps.AddOrUpdate(rawBeatmap);
                            await context.SaveChangesAsync();
                        }
                        finally
                        {
                            pool.Return(context);
                        }
                    })).ToArray());

                    beatmap = beatmaps.FirstOrDefault(s => s.FileMd5 == fileMd5);
                }

                await foreach (var score in DbScore.GetScores(ctx, fileMd5, dbUser, playMode, false, false, false, mods, true))
                {
                    ownScore = score;
                    break;
                }

                if (beatmap != null)
                {
                    set = new BeatmapSet
                    {
                        SetID        = beatmap.Id,
                        Artist       = beatmap.Artist,
                        Title        = beatmap.Title,
                        RankedStatus = beatmap.RankedStatus,

                        ChildrenBeatmaps = new List <Beatmap>
                        {
                            new Beatmap
                            {
                                FileMD5     = beatmap.FileMd5,
                                DiffName    = beatmap.DiffName,
                                ParentSetID = beatmap.SetId,
                                BeatmapID   = beatmap.Id,
                                Mode        = beatmap.PlayMode,
                            },
                        },
                    }
                }
                ;

JustContinue:
                var sboard = new Scoreboard(set?.ChildrenBeatmaps.FirstOrDefault(bm => bm.FileMD5 == fileMd5),
                                            set, scores, ownScore);

                cache.Set($"sora:Scoreboards:{cacheHash}", cachedData = await sboard.ToOsuString(ctxPool), TimeSpan.FromSeconds(30));
                return(Ok(cachedData));
            }
            catch (Exception ex)
            {
                Logger.Err(ex);
                return(Ok("Failed"));
            }
        }
Пример #6
0
        public async Task Receive()
        {
            var stream = _client.GetStream();
            var bytes  = new byte[4096];

            _writer = new StreamWriter(stream);

            // TODO: Finish http://www.networksorcery.com/enp/protocol/irc.htm
            try
            {
                int i;
                while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
                {
                    if (_exit)
                    {
                        return;
                    }

                    var data = Encoding.UTF8.GetString(bytes, 0, i).Split("\n");

                    foreach (var cmd in data.Select(d => d.Split(" "))
                             .Where(cmd => !string.IsNullOrEmpty(cmd[0]))
                             .Where(cmd => !string.IsNullOrWhiteSpace(cmd[0])))
                    {
                        switch (cmd[0])
                        {
                        case "USER":
                            if (_authorized)
                            {
                                SendCodeMessage(462, "Unauthorized command (already authorized!)");
                                continue;
                            }

                            if (cmd.Length < 2)
                            {
                                SendCodeMessage(451, "You have not registered");
                                continue;
                            }

                            _nickname = cmd[1].Trim();
                            var rUser = DbUser.GetDbUser(_ctx, cmd[1].Trim()).Result;
                            if (rUser == null)
                            {
                                SendCodeMessage(451, "You have not registered");
                                continue;
                            }

                            _user = rUser;

                            if (_authorized)
                            {
                                SendCodeMessage(462, "Unauthorized command (already authorized!)");
                                continue;
                            }

                            if (rUser?.IsPassword(Hex.ToHex(Crypto.GetMd5(_pass.Trim()))) != true)
                            {
                                if (string.IsNullOrEmpty(_nickname))
                                {
                                    _nickname = "anonymous";
                                }

                                Logger.Info(_pass);

                                SendCodeMessage(464, "Password incorrect");
                                continue;
                            }

                            _presence      = new Presence();
                            _presence.User = _user;

                            _presence["STATUS"] = new UserStatus();
                            _presence["IRC"]    = true;

                            WriteConnectionResponse();
                            WriteStatus();
                            WriteMotd();

                            _authorized = true;
                            break;

                        case "JOIN":
                            if (_presence == null || !_authorized)
                            {
                                SendCodeMessage(444, "You're not logged in");
                                break;
                            }

                            if (_cs.TryGet(cmd[1].Trim(), out var channel))
                            {
                                SendCodeMessage(403, $"{cmd[1]}: No such Channel!");
                                break;
                            }

                            channel.Join(_presence);

                            /*
                             * if (!)
                             * {
                             *  SendCodeMessage(482, "You're not allowed to Join this Channel!");
                             *  break;
                             * }
                             */

                            if (channel.Topic == "")
                            {
                                SendCodeMessage(331, "No topic is set", channel: channel.Name);
                            }
                            else
                            {
                                SendCodeMessage(332, channel.Topic, channel: channel.Name);
                            }

                            var uList = string.Join(
                                " ", channel.Presences
                                .Select(
                                    ps =>
                            {
                                var ret = ps.User.UserName.Replace(" ", "_");

                                if (ps.User.Permissions.HasPermission(Permission.GROUP_CHAT_MOD))
                                {
                                    ret = "@" + ret;
                                }
                                else if (ps.User.Permissions.HasPermission(
                                             Permission.GROUP_DONATOR
                                             ))
                                {
                                    ret = "+" + ret;
                                }

                                return(ret);
                            })
                                .ToArray()
                                );
                            uList += " @olSora";
                            SendCodeMessage(353, $"{uList}", channel: "= " + channel.Name);
                            SendCodeMessage(366, "End of NAMES list", channel: channel.Name);
                            break;

                        case "PING":
                            if (_presence == null || !_authorized)
                            {
                                SendCodeMessage(444, "You're not logged in");
                                break;
                            }

                            await _evmng.RunEvent(EventType.BanchoPong, new BanchoPongArgs { Pr = _presence });

                            SendMessage($"PONG {_cfg.Server.Hostname}: {cmd[1]}");
                            break;

                        case "PASS":
                            _pass = cmd[1];
                            break;

                        case "QUIT":
                            _client.Close();
                            _parent.RemoveTcpClient(this);
                            return;

                        // Ignored Commands
                        case "NICK":
                        case "CAP":
                            break;

                        default:
                            Logger.Debug(string.Join(" ", cmd));
                            if (!_authorized)
                            {
                                SendCodeMessage(444, "You're not logged in");
                            }
                            break;
                        }
                    }

                    _writer.Flush();
                }
            }
            catch (Exception e)
            {
                Logger.Err(e);
                _client.Close();
            }
        }