Example #1
0
        /**
         * Login de utilizadores já existentes. Devem ser recebidos o username e password.
         * Sempre que o login é feito com sucesso, é enviado um ID de sessão único para o cliente
         * que é usado por este para se identificar sempre que envia algum pedido.
         */
        public async override Task <UserLoginModel> Login(UserLoginLookupModel request, ServerCallContext context)
        {
            UserLoginModel output = new UserLoginModel();

            // Transformação de todos os carateres do nome para upper case
            string username = request.Username;//.ToUpper();

            // Encriptação da password
            SHA512 sha512 = SHA512Managed.Create();

            byte[] bytes    = sha512.ComputeHash(Encoding.UTF8.GetBytes(request.Password));
            string password = Convert.ToBase64String(bytes);

            // Verifica-se se o utilizador existe na base de dados e se a password está correta
            Models.User u = _context.User.FirstOrDefault(u => u.Username == request.Username && u.Password == password);

            if (u == null)
            {
                // Se não existir nenhuma entrada na base de dados com o username e password igual, então o output tem de ser autenticação inválida.
                output.Valid     = false;
                output.SessionID = "";
            }
            else
            {
                // Sempre que um utilizador se autentica, é gerado sempre um novo ID de sessão.
                // É usado um ciclo para, no caso do ID de sessão gerado já existir, poder gerar um novo
                bool success;
                do
                {
                    success = true;
                    try
                    {
                        u.GenerateSessionID();
                        _context.SaveChanges();

                        // Altera o id de sessão do cliente, na base de dados da API.
                        await APIServerCommunication.UserLogin(u.SessionID, u.Id);
                    }
                    // Exceção que é lançada sempre que é quebrado o constraint UNIQUE do ID de sessão, no caso do ID de sessão gerado já existir
                    catch (DbUpdateException e) when(e.InnerException is SqlException sqlEx && (sqlEx.Number == 2627 || sqlEx.Number == 2601))
                    {
                        success = false;
                    }
                }while (success == false);

                // Se o login for feito com sucesso, é enviada uma confirmação ao cliente, com o seu ID de sessão
                output.Valid     = true;
                output.SessionID = u.SessionID;
            }

            return(await Task.FromResult(output));
        }