I have a function to authenticate my users, which works because I tested it.
Authenticate function:
create or replace function authenticate(p_username in VARCHAR2, p_password in VARCHAR2)
return BOOLEAN
is
l_password varchar2(4000);
l_stored_password varchar2(4000);
l_count number;
begin
select count(*) into l_count from users where username = p_username;
if l_count > 0 then
-- First, we fetch the stored hashed password
select password into l_stored_password
from users where upper(username) = upper(p_username);
-- we have to apply the custom hash function to the password
l_password := custom_hash(p_username, p_password);
-- Finally, we compare them to see if they are the same and return
-- either TRUE or FALSE
if l_password = l_stored_password then
return true;
else
return false;
end if;
else
-- The username provided is not in the users table
return false;
end if;
end;
Yet my authentication in Apex doesn't work, I activated the authentication scheme and linked to authenticate function.
I'm using apex 4.2
This is how I've got mine setup:
Scheme Type: Custom
Authentication Function Name: my_auth_func
Source:
FUNCTION my_auth_func (p_username IN VARCHAR2, p_password IN VARCHAR2)
RETURN BOOLEAN
IS
is_authenticated BOOLEAN := FALSE;
BEGIN
--authentication logic, etc...
RETURN is_authenticated;
END
Related
I have created this function and it works:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
if
(p_ssnr is not null and p_password is not null) then
v_number:= 1;
else
v_number:= 0;
end if;
return v_number;
end;
If I then type: select log_in('social security number','the password') from dual; then I get a "1"
so it works. But you could basically type whatever you want and it will work so it is not a clean code. Since you can't include subquery in the if statement, how can you create the function so you only return 1 when you actually type a social security number (ssnr) and a password that matches the actual customer table? and otherwise you return 0?
NOt sure if you can have multiple rows for same customer. If yes, then use this:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
select case when count(*) > 0 then 1 else 0 end
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;
If not then this should be fine:
create or replace function log_in(
p_ssnr in customer.ssnr%type,
p_password in customer.password%type)
return number
as
v_number number(1);
begin
count(*)
into v_number
from customer
where ssnr = p_ssnr and password = p_password;
return v_number;
end;
Need to create a function that verifies a password (more than 5 characters, different from the previous one, it isn't neither "password" nor "123456")
I tried this but i get errors
CREATE OR REPLACE FUNCTION my_verification_function (
username VARCHAR2,
password VARCHAR2,
old_password VARCHAR2)
RETURN BOOLEAN IS
BEGIN
IF LENGTH(password) < 6 THEN RETURN FALSE;
ELSE IF (password = "password" OR password = '123' OR password = old_password) THEN RETURN FALSE
ELSE RETURN TRUE;
END IF;
END my_verification_function;$
CREATE OR REPLACE FUNCTION my_verification_function (
username VARCHAR2,
pass VARCHAR2,
old_password VARCHAR2)
RETURN varchar2 IS
BEGIN
IF LENGTH(pass) < 6 THEN RETURN 'FALSE';
ELSIF (pass = 'password' OR pass = '123456' OR pass = old_password) THEN RETURN 'FALSE';
ELSE RETURN 'TRUE';
END IF;
END;
Several notes:
1) You should use ELSIF instead of ELSE IF
2) If you need call this function in "pure" SQL, BOOLEAN type will give you error, so you can use VARCHAR2 instead.
3) Don't use reserved words like PASSWORD
It should be done like this:
CREATE OR REPLACE FUNCTION my_verification_function (
username VARCHAR2, password VARCHAR2, old_password VARCHAR2)
RETURN BOOLEAN AS
BEGIN
IF LENGTH(password) < 6 THEN
RETURN FALSE;
ELSIF (password = "password" OR password = '123' OR password = old_password) THEN
RETURN FALSE
ELSE
RETURN TRUE;
END IF;
END my_verification_function;
/
alter profile default limit password_verify_function my_verification_function;
Parameter name USERNAEM and PASSWORD seems to be no problem, since Oracle provided default function (located in ORACLE_BASE/ORACLE_HOME/RDBMS/ADMIN/UTLPWDMG.SQL) uses them also.
I am trying to make a PL/SQL function that when given the customer number looks to see if the order was sent to the customer address. If the customer's address matches the order address then the function needs to return True. This is what I came up with but I can't get it to work. Any help would be appreciated.
CREATE OR REPLACE Function CorrectAddress
(aCustNo IN Customer.CustNo%TYPE) RETURN VARCHAR IS
aCustStreet Customer.CustStreet%TYPE;
aCustCity Customer.CustCity%TYPE;
aCustState Customer.CustState%TYPE;
aOrdStreet OrderTbl.OrdStreet%TYPE;
aOrdCity OrderTbl.OrdCity%TYPE;
aOrdState OrderTbl.OrdState%TYPE;
RightAdd VARCHAR;
BEGIN
SELECT Customer.CustStreet, Customer.CustCity, Customer.CustState OrderTbl.OrdStreet, OrderTbl.OrdCity, OrderTbl.OrdState
INTO aCustStreet, aCustCity, aCustState, aOrdStreet, aOrdCity, aOrdState
FROM Customer, OrdertTbl
WHERE Customer.CustNo = OrderTbl.CustNo;
IF aCustStreet = aOrdStreet AND aCustCity = aOrdCity AND aCustState = aOrdState THEN RightAdd := True;
ELSE RightAdd := False;
END IF;
END;
Try this one, why did you want to return 'varchar', is it your custom type? if you want to return true/false you have to come with 'boolean', also you need to check whether you have rows in the table, for that you need to put exception handler
`CREATE OR REPLACE Function CorrectAddress
(aCustNo IN Customer.CustNo%TYPE) RETURN boolean IS
aCustStreet Customer.CustStreet%TYPE;
aCustCity Customer.CustCity%TYPE;
aCustState Customer.CustState%TYPE;
aOrdStreet OrderTbl.OrdStreet%TYPE;
aOrdCity OrderTbl.OrdCity%TYPE;
aOrdState OrderTbl.OrdState%TYPE;
`BEGIN
SELECT
Customer.CustStreet,
Customer.CustCity,
Customer.CustState,
OrderTbl.OrdStreet,
OrderTbl.OrdCity,
OrderTbl.OrdState
INTO
aCustStreet,
aCustCity,
aCustState,
aOrdStreet,
aOrdCity,
aOrdState
FROM
Customer,
OrdertTbl
WHERE Customer.CustNo = OrderTbl.CustNo;`
`IF aCustStreet = aOrdStreet AND aCustCity = aOrdCity AND aCustState = aOrdState THEN
return true;
ELSE
return false;
END IF;`
`Exception
when no_data_found then
return false;`
`END;`
why not do something in these lines, much cleaner to read and why use all these fields when they are not needed (haven't tested the plsql block, but for the general idea check below);
declare
V_COUNTER number := 0;
V_RESULT boolean;
begin
select
count('x')
into
V_COUNTER
from
Order o
inner join Customer c on c.Street = o.Street and
c.City = o.City and
c.State = o.State
where
o.Orderid = 100100;
if V_COUNTER = 0 then
V_RESULT := False;
else
V_RESULT := True;
end if;
end;
How to invoke a webservice through pl/sql block for which we know url,username and password.
And how to see the response?
Give some sample code...
Thanks in advance
I have used the following piece of code:
CREATE OR REPLACE FUNCTION READ_DATA_FROM_WS (url IN VARCHAR2,
username IN VARCHAR2,
password IN VARCHAR2)
RETURN CLOB
IS
req UTL_HTTP.req;
resp UTL_HTTP.resp;
DATA VARCHAR2 (2000);
data1 CLOB;
def_timeout PLS_INTEGER;
l_envelope VARCHAR2(32767);
BEGIN
req := utl_http.begin_request(url, 'POST','HTTP/1.0');
UTL_HTTP.set_authentication (req, username, password);
utl_http.set_header(req, 'Content-Type', 'text/xml');
resp := utl_http.get_response(req);
IF (resp.status_code = UTL_HTTP.http_ok)
THEN
UTL_HTTP.set_body_charset (resp, 'UTF-8');
BEGIN
LOOP
UTL_HTTP.read_text (resp, DATA);
data1 := data1 || DATA;
END LOOP;
EXCEPTION
WHEN UTL_HTTP.end_of_body
THEN
UTL_HTTP.end_response (resp);
UTL_HTTP.set_transfer_timeout (def_timeout);
WHEN OTHERS
THEN
NULL;
END;
UTL_HTTP.set_transfer_timeout (def_timeout);
ELSE
UTL_HTTP.end_response (resp);
DBMS_OUTPUT.put_line ('HTTP response status code: ' || resp.status_code);
END IF;
RETURN (data1);
END read_data_from_ws;
/
I have used web services with pl/sql without problems!
I'm using this one (+ my own improvements): http://www.oracle-base.com/dba/miscellaneous/soap_api.sql
Be sure that you define name spaces correctly, and I think you should only use this for retrieving ASCII not binary data...
Here is some sample code. Left some pieces out but it gives you an idea. The function returns the capabilities XML for a WMS webservice.
function getcapabilities(p_url varchar2
,p_version varchar2) return xmltype is
pragma autonomous_transaction;
req utl_http.req;
resp utl_http.resp;
c varchar2(255);
l_clob clob;
begin
dbms_lob.createtemporary(lob_loc => l_clob, cache => true, dur => dbms_lob.call);
-- -----------------------------------
-- OPEN TEMPORARY LOB FOR READ / WRITE
-- -----------------------------------
dbms_lob.open(lob_loc => l_clob, open_mode => dbms_lob.lob_readwrite);
utl_http.set_proxy(proxy => <proxy>, no_proxy_domains => <no_proxy>);
/* request that exceptions are raised for error Status Codes */
utl_http.set_response_error_check(enable => true);
/* allow testing for exceptions like Utl_Http.Http_Server_Error */
utl_http.set_detailed_excp_support(enable => true);
if instr(p_url, '?') > 0
then
req := utl_http.begin_request(p_url || '&REQUEST=GetCapabilities&SERVICE=WMS&VERSION=' ||
p_version);
else
req := utl_http.begin_request(p_url || '?REQUEST=GetCapabilities&SERVICE=WMS&VERSION=' ||
p_version);
end if;
utl_http.set_header(req, 'User-Agent', 'Mozilla/4.0');
resp := utl_http.get_response(req);
begin
loop
utl_http.read_text(r => resp, data => c);
/* function that adds a string to a clob */
add_to_clob(l_clob, c);
end loop;
exception
when utl_http.end_of_body then
null;
when others then
raise;
end;
utl_http.end_response(resp);
dbms_lob.close(lob_loc => l_clob);
/* this was for some Oracle bug */
execute immediate 'alter session set events =''31156 trace name context forever, level 2''';
commit;
return xmltype.createxml(l_clob);
end;
Even if there is a way to do this it would be a very bad practice!
Also, there are so many problems here. What will this service return? How are you gonna parse the results to something that sql can understand? How are you going to handle errors coming back from the service?
Just return whatever it is you need to return to the application and have the app invoke the web service.
Can anyone help me to protect a selection group or component.
For examples
If ('Readme.txt').selected or ('compact').selected = True then
begin "Password wizard page";
else
result := true;
end;
Something like that to this working script :P
function CheckPassword(Password: String): Boolean;
begin
result := false;
if (Password='component') or (Password='type') then
result := true;
end;
I'm not sure I completely understood your question, but maybe this helps. Here are a few functions you only need to add to the [code] section of the Components.iss sample, and one of the components ("help") can only be installed when the user enters the correct password.
Since you need the password later in the installation, and not always, you can not use the standard setup password page. You will instead create your own page and insert it after the components selection page:
[Code]
var
PasswordPage: TInputQueryWizardPage;
procedure InitializeWizard();
begin
PasswordPage := CreateInputQueryPage(wpSelectComponents,
'Your caption goes here',
'Your description goes here',
'Your subcaption goes here');
PasswordPage.Add(SetupMessage(msgPasswordEditLabel), True);
end;
Note that this uses the translated password caption, you may need to make the other three strings translatable as well.
Next you will need to hide that page if the user has not selected the component for installation:
function ShouldSkipPage(PageID: Integer): Boolean;
begin
Result := False;
if PageID = PasswordPage.ID then begin
// show password page only if help file is selected for installation
Result := not IsComponentSelected('help');
end;
end;
Finally you need to check the password, and prevent the user from going to the next page if the password is wrong:
function NextButtonClick(CurPageID: Integer): Boolean;
begin
Result := True;
if CurPageID = PasswordPage.ID then begin
// stay on this page if password is wrong
if PasswordPage.Edits[0].Text <> 'my-secret-password' then begin
MsgBox(SetupMessage(msgIncorrectPassword), mbError, MB_OK);
Result := False;
end;
end;
end;