O OCI Object storage possui uma funcionalidade muito legal chamada PAR (Pre-Authenticated Requests) que gera uma URL única e temporária que te permite interagir com buckets/objetos sem autenticação, então na prática você poderia ter um bucket privado e compartilhar os arquivos dele com quem quiser, pensando nisso e baseado nesse artigo aqui resolvi criar uma interface em APEX que recebe arquivos como uma caixa postal, a pessoa tem seu endereço (PAR) e te entrega o arquivo.
O PAR
Um PAR pode ser criado de diversas formas(console web, api, cli..) e com diversas opções:
Cada PAR precisa de um nome e de parâmetros de acesso, no nosso caso precisamos criar um do tipo Bucket com permissão de escrita (Permit Object writes), você também pode configurar um prazo de validade da URL, isso é muito util quando você quer compartilhar um arquivo com alguém e quer ter certeza que após determinado tempo o arquivo não esteja mais acessível.
Ao criar o PAR, copie a URL para uma localização segura pois ela só é exibida uma única vez!
APEX
Aqui no meu caso estou usando um APEX como serviço, mas você pode usar o que estiver a sua disposição, também no meu caso, optei por fazer uma aplicação pública(sem login) e para isso precisei alterar algumas opções, no workspace internal eu precisei ir em Manage Instance -> Security e habilitar a opção Allow Public File upload:
Após isso, criei meu Workspace(que aqui se chama upload) e criei uma página simples, tive que alterar a opção Authentication para public, lembrando que talvez no seu caso você não queira/precise fazer isso:
Esses são os meus componentes:
Basicamente precisamos de um objeto do tipo File Browse, um campo de texto(que vai receber nosso PAR) e um botão que vai juntar tudo isso em uma ação única.
File Browse
Esse objeto é bem simples, ele faz uma ponte entre um arquivo em sua máquina e uma tabela no banco do APEX, você pode criar uma tabela customizada para armazenar seus objetos, mas nesse caso estou usando a padrão que é a apex_application_temp_files, arraste esse recurso para a sua página, ele possui alguns modelos, aqui estou usando um que você arrasta os arquivos da sua máquina para ele, edite a seguinte opção para garantir que o objeto vá ser apagado logo após o envio:
Caso queira, você também pode adicionar algumas validações como tamanho máximo e formato de arquivo aceito, aqui no meu caso não alterei mais nada.
Campo texto
Aqui usei um objeto do tipo Text Field com o tipo URL
Marquei a opção Required para que fique uma mensagem informando que um valor precisa ser passado e também adicionei uma validação (no botão de upload) para caso ele esteja vazio que o upload não comece.
Botão de upload
Para esse botão usei a opção “Hot” com duas ações dinâmicas, uma que pega o valor do campo texto (P1_PAR) e faz o uso do apex_web_service para fazer a requisçao de envio e outra para validar se o campo texto possui um valor.
A de upload é do tipo submit page e tem a seguinte configuração:
Quando um evento do tipo Click acontecer no botão, ele vai fazer um submit page que tem o seguinte processo atrelado a ele:
O código que ele chama é o que está no tutorial de interação com o Object storage com algumas pequenas alterações, aqui por exemplo não fazemos autenticação e nossa URL vai ser passada pelo usuário:
declare
l_request_url varchar2(32767);
l_content_length number;
l_response clob;
upload_failed_exception exception;
begin
for file in (
select * from apex_application_temp_files
where name = :P2_FILE
) loop
l_request_url := :P1_PAR || apex_util.url_encode(file.filename);
apex_web_service.g_request_headers(1).name :=
'Content-Type';
apex_web_service.g_request_headers(1).value :=
file.mime_type;
l_response := apex_web_service.make_rest_request(
p_url => l_request_url
, p_http_method => 'PUT'
, p_body_blob => file.blob_content
);
if apex_web_service.g_status_code != 200 then
raise upload_failed_exception;
end if;
end loop;
delete from apex_application_temp_files where name = :P2_FILE;
end;
A parte importante desse código são as variáveis :P2_FILE (nome do nosso objeto File Browse) e :P1_PAR(nome do nosso campo de texto).
A validação se o campo texto possui valor é a seguinte:
Juntando tudo isso nós temos uma página bem simples :
Utilização
Crie um PAR com a opção Permit object writes marcada:
Na página da aplicação no campo de texto coloque o seu PAR e selecione o arquivo:
Ao clicar em Upload ele já deve começar a ser enviado:
E o arquivo logo deve aparecer no bucket:
Caso a pessoa não entre o PAR, a nossa validação entra em vigor:
Bem pessoal, espero que tenham gostado dessa integração e espero que acompanhem a evolução dela pois ainda vou fazer algumas melhorias.