Please login or register.

Login with username, password and session length
Advanced search  

News:

You need/want an older version of sNews ? Download an older/unsupported version here.

Author Topic: coding enquiry  (Read 3996 times)

philmoz

  • High flyer
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 1988
    • fiddle 'n fly
coding enquiry
« on: February 04, 2009, 04:02:17 am »

I am messing about with 1.7, and am looking at doing a custom multi-user environment, but my question would be applicable to any version of snews.

When writing procedural code, is it 'acceptable' to only allow access to functions only if conditions met?
I want to avoid having to exit any function that fails an access test, and would rather 'hide' them from script by using the access test prior to function definition.
(I am aware that I would then have to check that functions exist where they may be called within script to avoid errors.)

eg...

if(_ADMIN && _USERLEVEL < 3){
function func1(){}
function func2(){}
}
if(_ADMIN && _USERLEVEL < 2){
function func3(){}
function func4(){}
}
The above would only allow access to these functions provided user is logged in (_ADMIN) and user has a suitable level.
Normally, I would have done the test in each function....

function func1(){
if(_ADMIN && _USERLEVEL < 3){
...do...
}else{set and return $default1 or exit}
return $var1
}
function func2(){
if(_ADMIN && _USERLEVEL < 3){
...do...
}else{set and return $default2 or exit}
return $var2
}

etc
Logged
Of all the things I have lost, it is my mind that I miss the most.

centered

  • Guest
Re: coding enquiry
« Reply #1 on: February 04, 2009, 04:27:15 am »

You can define the level of the user upon validation of login and use that as a constant.

Just thinking, and it may be a wrong way, but...

 - Sudo code -

GET[username]
GET[password]
select userlevel from db where user = GET[username] and pass = GET[password]
define(_ADMIN, code here)
define(_USERLEVEL, code here && _ADMIN)

function that_needs_adminL1() {
 if (_USERLEVEL > 1)
    code
}

function level_two_func() {
 if (_USERLEVEL = 2)
  funcA()
  funcB()
  funcC()
else die('not on my level')
}
level_two_func()

Could be wrong... but just a quick idea
Logged

philmoz

  • High flyer
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 1988
    • fiddle 'n fly
Re: coding enquiry
« Reply #2 on: February 04, 2009, 04:46:57 am »

You can define the level of the user upon validation of login and use that as a constant.

Just thinking, and it may be a wrong way, but...

 - Sudo code -

GET[username]
GET[password]
select userlevel from db where user = GET[username] and pass = GET[password]
define(_ADMIN, code here)
define(_USERLEVEL, code here && _ADMIN)

function that_needs_adminL1() {
 if (_USERLEVEL > 1)
    code
}

function level_two_func() {
 if (_USERLEVEL = 2)
  funcA()
  funcB()
  funcC()
else die('not on my level')
}
level_two_func()

Could be wrong... but just a quick idea

I already have  data to perform checks.. ie _USERLEVEL, I just would like to know if it is 'acceptable' programming (I know it works) to wrap functions in a conditional in order to allow/deny access to them depending on conditional outcome, and at same time remove need to perform identical test in each function.

I suppose it is little different (maybe no different) to including a function library file if condition is met...
eg, instead of
if(_ADMIN && _USERLEVEL < 3){
function func1(){}
function func2(){}
}

it would be
if(_ADMIN && _USERLEVEL < 3){
include('lib2.php');
}
where lib2.php is
<?php
function func1(){}
function func2(){}
?>

yes??
Logged
Of all the things I have lost, it is my mind that I miss the most.

Joost

  • Guest
Re: coding enquiry
« Reply #3 on: February 04, 2009, 05:32:37 am »

A tough topic, since it is about security.
The most important thing is clarity, I think. If you can built a system this way, without adding confusion, it should be al right. However, looking at these examples, you're basically delegating permission checking to function function_exists.

Personally, I am in favour of separating program flows, as I already mentioned somewhere else.
I have, what I call a "process flow", which deals with database mutation (update, delete etc.).

Two code snippets:

Code: ($_POST Starts the taskmanager) [Select]
<?php
#   -----------------------------------------  POST REQUEST  --------------------------------
 
CASE $_POST : {
if (isset($_POST['login']) ){ CheckIn();
} else TaskManager();
 }
?>

Code: (Taskmanager) [Select]
<?php

function TaskManager(){
if( ! 
YOURIN ) die('fuck you !'); #flag
 
CleanInput($_POST);
 
CleanInput($_GET);
 if(isset(
$_GET['dir'])) return;
 
$task = array('proces_content','delete_content','proces_extra','delete_extra','proces_settings','proces_frontpage','proces_cat','proces_blog','change_login','truncate' );
 if ( ! empty(
$_GET['task']) && in_array($_GET['task'],$task) )  $run_task $_GET['task']; else die('unknown task');#flag
 
$run_task();
}

?>

So everything passes function TaskManager, which cleans $_POST and $_GET, verifies the login status and starts the process.

I brought the cleaning process to the top, just recently. That way, you can see in a glance whether the input is being cleaned. In a previous version, it was done in each process function
As we speak, I realize that it might be even  better, to prefix all process functions with the name "proces"  (Dutch for process  ;) ) in order to emphasize their tasks.

That's the type of solution I am looking for.

I have another option, that might be interesting to explore:


if(Iam_god){

 function doThis(){
 do anything
 }

}

elseif(Iam_mortal){

 function doThis(){
 do little
 }

}

You can define the same function different.

I see we crossed posts.
Anyway, it is about clarity. That's what I am trying to say.
« Last Edit: February 04, 2009, 05:37:02 am by Joost »
Logged

philmoz

  • High flyer
  • ULTIMATE member
  • ******
  • Karma: 161
  • Posts: 1988
    • fiddle 'n fly
Re: coding enquiry
« Reply #4 on: February 04, 2009, 08:17:55 am »

A tough topic, since it is about security.
The most important thing is clarity, I think. If you can built a system this way, without adding confusion, it should be al right. However, looking at these examples, you're basically delegating permission checking to function function_exists.
how so? isn't checking for function a simple error catching? The permission process allows/disallows function access...


I have another option, that might be interesting to explore:


if(Iam_god){

 function doThis(){
 do anything
 }

}

elseif(Iam_mortal){

 function doThis(){
 do little
 }

}

You can define the same function different.
the only issue here is if the function is soley for a higher access level user (Iam_god), it shouldn't be available to the lower user, but if the function is called by lower user without there being a lower user function, errors would occur. If you fill the lower level user function with a simple return, then it would have been just as easy to do checking inside a single function.
« Last Edit: February 04, 2009, 08:26:52 am by philmoz »
Logged
Of all the things I have lost, it is my mind that I miss the most.

centered

  • Guest
Re: coding enquiry
« Reply #5 on: February 04, 2009, 01:22:48 pm »

I already have  data to perform checks.. ie _USERLEVEL, I just would like to know if it is 'acceptable' programming (I know it works) to wrap functions in a conditional in order to allow/deny access to them depending on conditional outcome, and at same time remove need to perform identical test in each function.

If it works then it works.  You can also do a switch statement as well:

swtch (uselevel)
  case level1:
func
func
break
case level2:
etc etc

Asking if it is acceptable programming may be subjectable. I could say try this and it still could be acceptable (to some):

class userlevel 1{
  allowed method{}
  allowed method{}
}

class userlevel2 extends userlevel 1 {
  add allowed method{}
}

etc.
Logged