Create Password Verification Function for Enterprise PostgreSQL - enterprisedb

How is it possible to create a function in EDB PostgreSQL to check the password?
The password should contain:
at least 1 upper case
at least 1 lower case
at least 1 digit
at least 8 characters long
at least 1 special character
So far I searched and got
CREATE OR REPLACE FUNCTION verify_password(user_name varchar2, new_password varchar2, old_password varchar2)
RETURN boolean IMMUTABLE
IS
BEGIN
IF (length(new_password) < 5)
THEN
raise_application_error(-20001, 'too short');
END IF;
IF substring(new_password FROM old_password) IS NOT NULL
THEN
raise_application_error(-20002, 'includes old password');
END IF;
RETURN true;
END;
Above functions works fine but I am not able to add checks for uppercase, lowercase and special character.
If I add lines on checks for uppercase, lowercase and special character I am able to create the function but when password checks comes in it does not seem to work.

Related

Number to character conversion error in trigger. [ORACLE 11G ]

I'm trying to make a trigger that returns an error with a specific message when the user tries to insert a new record to Addresses table and provides the wrong post code. Two IF statements check if the number of characters in the given post-code is right (it should be 6: 2 numbers, 1 dash and 3 numbers). Another IF statement checks if the position of the dash is 3. When I try to insert a post-code with too few characters (for example '12932') it works fine and returns the right message. The problem begins when I provide the post-code in which the dash position is incorrect (for example '1-9000'). In such case it returns an error (PL/SQL: numeric or value error: character to number conversion error, line 15). What could be the reason? Because personally I can't find any char to number conversions. Thanks.
Code:
CREATE OR REPLACE TRIGGER post_code_trigger
BEFORE INSERT OR UPDATE ON Addresses
FOR EACH ROW
DECLARE
code_length NUMBER;
index_of_dash NUMBER;
code_tmp VARCHAR(6);
BEGIN
code_tmp := :NEW.Post_code;
code_length := LENGTH(code_tmp);
index_of_dash := INSTR(code_tmp, '-');
IF(code_length <> 6) THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code contains the wrong number of characters.');
ELSE
IF (index_of_dash <> 3) THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');
END IF;
END IF;
END;
/
INSERT INTO Addresses (address_ID, city, post_code, province, street_name, house_number) VALUES (2, 'Warsaw','1-9000','mazowieckie','Sylvester Stallone Street', 67);
In the body of the code, indekx_of_dash does not match index_of_dash in the declaration. Once you fix that typo, it works.
It can be simplified to:
CREATE OR REPLACE TRIGGER post_code_trigger
BEFORE INSERT OR UPDATE ON Addresses
FOR EACH ROW
DECLARE
BEGIN
IF LENGTH(:NEW.Post_code) <> 6 THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code contains the wrong number of characters.');
ELSIF INSTR(:NEW.Post_code, '-') <> 3 THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain "-" character or it is in the wrong posiition. Sample post code "26-500" ');
END IF;
END;
/
But you probably don't want to use a trigger and just want a CHECK constraint.
ALTER TABLE addresses ADD CONSTRAINT addresses_postcode_format
CHECK (post_code LIKE '??-???');
db<>fiddle here
Ok, I found a solution. Firstly I simplified my code according to the MT0's answer. Then I deleted the '-' part from the error message. Now everything works as it should. Thank you.
IF INSTR(:NEW.Post_code, '-') <> 3 THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain a dash character or it is in the wrong posiition. Sample post code "26-500" ');
instead of
ELSIF INSTR(:NEW.Post_code, '-') <> 3 THEN
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');
When you originally posted your question you had this line:
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain "-" character or it is in the wrong posiition. Sample post code "26-500" ');
Your real code actually has (but with Polish text):
RAISE_APPLICATION_ERROR(-20000, 'Post code doesnt contain '-' character or it is in the wrong posiition. Sample post code "26-500" ');
The problem then is the '-' in the middle of that. The single quotes around the dash end one string, and start another; and the dash is now outside the string literal(s), so Oracle interprets it as a minus sign. That causes it to implicitly convert the two shorter string literals either side to numbers, so they can be subtracted from each other. So you're really doing:
to_number('Post code doesnt contain ')
-
to_number(' character or it is in the wrong posiition. Sample post code "26-500" ')
The error is occurring when it tries to convert those strings, because they clearly do not represent numbers.
With the dash enclosed in double-quotes instead the whole thing is one string literal again, so there is no confusion or attempt to perform a calculation.
Incidentally, you seem to have avoided an issue with quotes with doesnt instead of doesn't, though presumably only in the translated version. But if you wanted to use single quotes within a string, you can either escape them:
'Post code doesn''t contain ''-'' character or it is in the wrong position. Sample post code ''26-500'''
or use the alternative quoting mechanism:
q'[Post code doesn't contain '-' character or it is in the wrong position. Sample post code '26-500']'
db<>fiddle demo

Detect specific string including wildcards and isolate wildcards in PLPGSQL

Is it possible in PostgreSQL 9.4 (PLPGSQL) to detect if a string contains a certain string including wildcards and get the wildcards, ex.:
IF NEW.my_string CONTAINS 'patternXYZ' THEN
NEW.my_values := getXYZ(my_string)
END IF;
Which would result in NEW.my_values to contain XYZ (which can be anything in the string, but only the 3 characters).
SELECT
CASE
WHEN (NEW.my_string like '%patternXYZ%')
THEN substring(NEW.my_string from '+pattern+')
ELSE '00'
END AS data
FROM my_table;
Pattern should be the parameter for query.

SQL Regular expression Function

I'm trying to understand the meaning of this regular expression function and it purpose in the select statement.
create or replace FUNCTION REPS_MTCH(string_orig IN VARCHAR2 , string_new IN VARCHAR2, score IN NUMBER)
RETURN PLS_INTEGER AS
BEGIN
IF string_orig IS NULL AND string_new IS NULL THEN
RETURN 0;
ELSIF utl_match.jaro_winkler_similarity(replace(REGEXP_REPLACE(UPPER(string_orig), '[^a-z|A-Z|0-9]+', ''),' ',''),replace(REGEXP_REPLACE(UPPER(string_new), '[^a-z|A-Z|0-9]+', ''),' ','')) >= score THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
//the REPS_MTCH function is being called in this select statement. the select statement is to match names in the the Temp table name as REPS_MTCH_D_STDNT_TMP against the master table named as REPS_MTCH_D_STDNT_MSTR. what is the purpose of the REPS_MTCH function in this select statement?
SELECT
REPS_MTCH(REPS_MTCH_D_STDNT_TMP.FIRST_NAME,REPS_MTCH_D_STDNT_MSTR.FIRST_NAME,85) AS first_match_score,
what is the purpose of the REPS_MTCH function in this select statement?
In the above function the REGEXP_REPLACE is removing all occurrences any non alpha numeric or pipe (|) characters. After that the REGEXP_REPLACE is also wrapped in a redundant call to the regular REPLACE function which simply removes the spaces which were already removed by the REGEXP_REPLACE calls. The test could be rewritten as follows and still behave the identically since the inputs are first UPPERcased before the replace operations occur:
ELSIF utl_match.jaro_winkler_similarity(
REGEXP_REPLACE(UPPER(string_orig), '[^A-Z|0-9]+', '')
,REGEXP_REPLACE(UPPER(string_new) , '[^A-Z|0-9]+', '')
) >= score
THEN RETURN 1;
I simply removed the extra replace operation, the unnecessary lower case a-z and the extra pipe (|) character from the regular expression's character classes.
The JARO_WINKLER_SIMILARITY function just computes a score from 0 not similar to 100 identical of the remaining alpha numeric and pipe characters. You can check out the wikipedia entry on Jaro Winkler distances if you want to know more about them.

Regular Expression PL/SQL

I am trying to use some regular expressions in PL/SQL.
I try to check the following pattern: LOKATIONS_ID => /LAND/ORT/GEBÄUDE/
I've tried this one:
create or replace function check_lok_id(lok_id in varchar2) return boolean
is
begin
if regexp_like (lok_id, '^(/[A-Z]+?){3}/$)')
then
return true;
else
return false;
end if;
end;
But unfortunately this one and several other regular expressions i've tested so far doesn't work.
Any suggestions?
Your example won't match because the umlauted character Ä is not in the range A-Z.
Try this regex:
^(/\w+?){3}/$
Or if you want to match only uppercase letters, but from all languages:
^(/[[:upper:]]+?){3}/$
See live demo

How to find character code in PL/SQL?

I want to find character code of particular character in string.
For instance if I have a string
"Hello"
How do i find the character code of all or particular characters in the string.
I see that PL/SQL has a ASCII() and ASCIISTR() functions but I could not find any character related functions.
create or replace function asciistr2(s IN varchar2)
RETURN varchar2
IS
result varchar2(32767) := '';
BEGIN
FOR i IN 1..Length(s)
LOOP
dbms_output.put_line(ASCII(substr(s,i,1)));
result := result || ASCII(substr(s,i,1));
END LOOP;
return result;
END;
Select asciistr2('HELLO') from dual
Result: 7269767679
dbms_output
72
69
76
76
79
What exactly would you expect? Looking at your question, it seems to me that ASCII() would give you what you need, see this ASCII tutorial. You can loop
Or are you referring to the Unicode value?