Check-in [7d1a3fe5b0]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:[CORE][BASE][MODULES] - Major code rewrite to get rid of mid-steps in module loading, improve URL param parsing with a dedicated function, apply changes to our custom modules and set the base skeleton for new module creation. Version update to 0.0.3-alpha.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 7d1a3fe5b03821d8bd5d87c717d4bac700037875
User & Date: julcar 2020-09-29 07:47:54
Context
2020-09-29
08:14
[MODULES] - Fix a bug that did not allowed to save page copies with alike names. check-in: 993dc278c6 user: julcar tags: trunk
07:47
[CORE][BASE][MODULES] - Major code rewrite to get rid of mid-steps in module loading, improve URL param parsing with a dedicated function, apply changes to our custom modules and set the base skeleton for new module creation. Version update to 0.0.3-alpha. check-in: 7d1a3fe5b0 user: julcar tags: trunk
2020-09-26
08:09
[MODULES] - Fix a little bug in page listing check-in: 7348021f6d user: julcar tags: 0.0.3-alpha, trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to core/modules.bas.

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33


34




35
1
2











3










4

5
6
7
8
9
10
11

12
13
14

15
16
17
18
19


-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-

-
+






-

+
+
-
+
+
+
+

#INCLUDE "modules\modules.bi"

SUB LoadModule (ModuleName AS STRING)
  'Main module procedure trigger
  SELECT CASE ModuleName
    CASE "users"
      LoadUsersInterface()
    CASE "admin"
      LoadAdminPanel()
    CASE ELSE
  END SELECT
END SUB

'FIXME: Potentially dead code inside this function
FUNCTION ModuleVars (ModuleName AS STRING, Key AS STRING) AS STRING
  'This function returns the value from the helper function of each module
  SELECT CASE ModuleName
    CASE "users"
      ModuleVars = ReadUserData(Key)
    CASE ELSE
      ModuleVars = Key
  END SELECT
END FUNCTION

FUNCTION ModuleParser (Key AS STRING) AS STRING
  DIM AS STRING ModuleName, SubKey
  DIM AS STRING ModuleName, SubKey = ""
  'Try to find an underscore inside the command
  IF INSTR(Key, "_") > 0 THEN
    ModuleName = LEFT(Key, INSTR(Key, "_") - 1)
    SubKey = MID(Key, INSTR(Key, "_") + 1, LEN(Key))
  ELSE
    ModuleName = Key
    SubKey = ""
  END IF
  IF ModuleVars > 0 THEN
    'Return the value from the helper function of each module
  ModuleParser = ModuleVars(ModuleName, SubKey)
    ModuleParser = ModuleVars(SubKey)
  ELSE
    ModuleParser = SubKey
  END IF
END FUNCTION

Changes to core/request.bas.

20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
20
21
22
23
24
25
26






















27







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

  Post = URLDecode(SplitVar(StdinQuery, Arg, CHR(38)))
END FUNCTION

FUNCTION QueryString (Arg AS STRING) AS STRING
  QueryString = URLDecode(SplitVar(ENVIRON("QUERY_STRING"), Arg, CHR(38)))
END FUNCTION

FUNCTION UriPart (Arg AS INTEGER) AS STRING
  DIM AS INTEGER StartPos, NextSlash, Count
  DIM AS STRING StrUri, Result
  StrUri = ENVIRON("REQUEST_URI")
  StartPos = 1
  NextSlash = StartPos
  Count = 0
  DO UNTIL NextSlash = 0
    NextSlash = INSTR(StartPos, StrUri, CHR(47))
    IF Arg = Count - 1 THEN
      Result = MID(StrUri, StartPos, NextSlash - StartPos)
      IF INSTR(Result, CHR(46)) > 0 THEN
        Result = LEFT(Result, INSTR(Result, CHR(46)) - 1)
      END IF
      EXIT DO
    END IF
    StartPos = NextSlash + 1
    Count = Count + 1
  LOOP
  UriPart = Result
END FUNCTION

'END NAMESPACE

Changes to core/system.bas.

15
16
17
18
19
20
21






















22
23
24
25
26
27
28
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







    KeyParsed = SplitVar (LanguageContent, Key, LINE_ENDING)
    IF KeyParsed <> "" THEN
      Language = KeyParsed
    ELSE
      Language = Key
    END IF
  END FUNCTION

  FUNCTION URLParam (Arg AS USHORT) AS STRING
    DIM AS USHORT StartPos, NextSlash, Count
    DIM AS STRING StrUri, Result
    StrUri = ENVIRON("REQUEST_URI")
    StartPos = 1
    NextSlash = StartPos
    Count = 1
    DO UNTIL NextSlash = 0
      NextSlash = INSTR(StartPos, StrUri, "/")
      IF Arg = Count - 1 THEN
        Result = MID(StrUri, StartPos, NextSlash - StartPos)
        IF INSTR(Result, ".") > 0 THEN
          Result = LEFT(Result, INSTR(Result, ".") - 1)
        END IF
        EXIT DO
      END IF
      StartPos = NextSlash + 1
      Count += 1
    LOOP
    URLParam = Result
  END FUNCTION

  FUNCTION CreateURL (Scheme AS STRING) AS STRING
    DIM AS STRING ParamValue, Result
    DIM AS SHORT Count, StartPos, NextPos
    Count = 0
    StartPos = 1
    NextPos = StartPos
58
59
60
61
62
63
64














65
66
67
68
69
70
71
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107







+
+
+
+
+
+
+
+
+
+
+
+
+
+







    WEND
    IF CINT(Settings("site_fancy_url")) THEN
      CreateURL = "/" + Result + Settings("site_fancy_url_extension")
    ELSE
      CreateURL = "?" + Result
    END IF
  END FUNCTION

  FUNCTION GetURLParam (VarName AS STRING = "", ParamIndex AS USHORT = 0) AS STRING
    DIM AS STRING Result = ""
    IF CINT(Settings("site_fancy_url")) THEN
      IF ParamIndex > 0 AND URLParam(ParamIndex) <> "" THEN
        Result = URLParam(ParamIndex)
      END IF
    ELSE
      IF QueryString(VarName) <> "" THEN
        Result = QueryString(VarName)
      END IF
    END IF
    GetURLParam = Result
  END FUNCTION

  FUNCTION ServerVars (Key AS STRING) AS STRING
    DIM AS STRING SubKey, Value
    IF INSTR(Key, "_") > 0 THEN
      SubKey = LCASE(MID(Key, 1, INSTR(Key, "_") - 1))
      Value = MID(Key, INSTR(Key, "_") + 1, LEN(Key))
    ELSE

Changes to iguanacms.bi.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16
17
18
19
20
21
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21













-
+







'################################# Iguana CMS ##################################
'Main include file
'Compile it with FreeBasic => 0.24.0
'###############################################################################

#ifdef __FB_WIN32__
  CONST AS STRING PATH_DELIMITER = "\"
  CONST AS STRING LINE_ENDING = CHR(13, 10)
#else
  CONST AS STRING PATH_DELIMITER = "/"
  CONST AS STRING LINE_ENDING = CHR(10)
#endif

CONST AS STRING IguanaVersion = "0.0.2 alpha"
CONST AS STRING IguanaVersion = "0.0.3-alpha"

'##############################
'Paths block
'##############################

CONST AS STRING BasePath = ".." + PATH_DELIMITER
CONST AS STRING RootPath = BasePath + "root" + PATH_DELIMITER
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

52

53
54
55
56
57
58
59
60
61
62
63
64
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56


57
58
59
60
61
62
63







-











+

+



-
-








'##############################
'CGI Functions
'##############################
DECLARE FUNCTION ReadStdin () AS STRING
DECLARE FUNCTION Post (Arg AS STRING) AS STRING
DECLARE FUNCTION QueryString (Arg AS STRING) AS STRING
DECLARE FUNCTION UriPart (Arg AS INTEGER) AS STRING
DECLARE FUNCTION SetCookie (CookieName AS STRING, CookieValue AS STRING, _
 Domain AS STRING, Path AS STRING, ExpiresDate AS STRING, _
 MaxAgeTime AS INTEGER, IsSecure AS INTEGER, IsHttpOnly AS INTEGER) AS STRING
DECLARE FUNCTION GetCookie (CookieName AS STRING) AS STRING
DECLARE FUNCTION SetContentType (MimeType AS STRING) AS STRING

'##############################
'System Functions
'##############################
DECLARE FUNCTION Settings (Key AS STRING) AS STRING
DECLARE FUNCTION Language (Key AS STRING) AS STRING
DECLARE FUNCTION URLParam (Arg AS USHORT) AS STRING
DECLARE FUNCTION CreateURL (Scheme AS STRING) AS STRING
DECLARE FUNCTION GetURLParam (VarName AS STRING = "", ParamIndex AS USHORT = 0) AS STRING
DECLARE FUNCTION ServerVars (Key AS STRING) AS STRING
DECLARE SUB LoadPage (PageName AS STRING)
DECLARE FUNCTION PageParser (Query AS STRING) AS STRING
DECLARE SUB LoadModule (ModuleName AS STRING)
DECLARE FUNCTION ModuleVars (ModuleName AS STRING, Key AS STRING) AS STRING
DECLARE FUNCTION ModuleParser (Key AS STRING) AS STRING
DECLARE FUNCTION TplParser (TplContent AS STRING) AS STRING
DECLARE FUNCTION LoadTplFile (FilePath AS STRING, FileName AS STRING) AS STRING
DECLARE FUNCTION Captcha() AS STRING
DECLARE FUNCTION ValidateCaptcha (Answer AS STRING, Number AS STRING) AS SHORT

'##############################
99
100
101
102
103
104
105





98
99
100
101
102
103
104
105
106
107
108
109







+
+
+
+
+
'##############################
'Variables Initialization
'##############################
SettingsContent = ReadFile (DataPath + "settings.txt")
LanguageContent = ReadFile (DataPath + "languages" + PATH_DELIMITER + Settings("site_language") + ".txt")
TplName = Settings("site_template")
HttpHeader = SetContentType("text/html") + CHR(10, 10)

'Windows-only Debug Macro
#macro PrintLog(LogAction)
  SHELL("echo " + SystemDate() + "-" + SystemTime() + ":" + LogAction + " >> " + BasePath + "logs\logfile.txt")
#endmacro

Changes to index.bas.

1
2
3
4
5
6

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

22
23
24

25
26
27
28
29
30
31
32
33
34
35
36


37
38
39
40
41
42


43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69



70
71
72




73
74
75
76
1
2
3
4
5

6
7














8



9












10
11






12
13









14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29


30
31
32
33


34
35
36
37

38

39





-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
















-
-
+
+
+

-
-
+
+
+
+
-

-

'################################# Iguana CMS ##################################
'Main application file
'Compile it with FreeBasic => 0.24.0
'###############################################################################

#INCLUDE "iguanacms.bi"
#INCLUDE "modules\modules.bi"

DIM AS STRING Request, PageName, Result

'Look for a request
IF CINT(Settings("site_fancy_url")) THEN
  IF UriPart(0) <> "" THEN
    Request = UriPart(0)
  END IF
ELSE
  IF QueryString("module") <> "" THEN
    Request = QueryString("module")
  END IF
END IF

IF Request <> "" THEN
IF PageName <> "" THEN
  'Load a module
  IF Request = "pages" THEN
    'Load the pages module
  'Load the pages module
    IF CINT(Settings("site_fancy_url")) THEN
      IF UriPart(1) <> "" THEN
        PageName = UriPart(1)
      END IF
    ELSE
      IF QueryString("pagename") <> "" THEN
        PageName = QueryString("pagename")
      END IF
    END IF
    IF PageName <> "" THEN
      LoadPage(PageName)
    ELSE
  LoadPage(PageName)
ELSEIF LoadModule > 0 THEN
      'Load the default page
      LoadPage(Settings("site_index_page"))
    END IF
  ELSE
    'Load other module
    LoadModule(Request)
  'Load any other module
  LoadModule()
  END IF
ELSE
  'Load default settings
  SELECT CASE Settings("site_index_type")
    CASE "page"
      LoadPage(Settings("site_index_page"))
    CASE "module"
      LoadModule(Settings("site_index_module"))
  END SELECT
END IF

IF SiteContent = "403" THEN
  'Displays error 403
  SiteContent = LoadTplFile("", "403.html")
END IF

IF SiteContent = "" THEN
  'Displays error 404
  SiteContent = LoadTplFile("", "404.html")
END IF

IF SiteTitle = "" THEN
  SiteTitle = Settings("site_description")
END IF

'Load everything into a variable
Result = LoadTplFile("", "main.html")
'Do the magic
PRINT HttpHeader
PRINT LoadTplFile("", "main.html")

'Do the magic
PRINT HttpHeader
'Free memory
SiteTitle = ""
SiteContent = ""
HttpHeader = ""
PRINT Result

Result = ""
END

Changes to modules/admin.bas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15








-
-
-
-







'Admin panel module

#INCLUDE "modules.bi"

CONST AS STRING ModuleName = "admin"
DIM SHARED ModulePath AS STRING
ModulePath = "modules" + PATH_DELIMITER + ModuleName + PATH_DELIMITER

'arrayIndex = UBOUND(compiledModules) + 1
'REDIM PRESERVE compiledModules(arrayIndex)
'compiledModules(arrayIndex) = "admin"

'NOTE: These constants have the group number assigned to administrators, editors, etc.
'Groups can be modified by editing groups.txt in data folder, you can add as many groups as you need.
'Please adjust constant values according to the file.
CONST AS SHORT AdminGroup = 1, EditorGroup = 2

SUB LoadAdminPanel()
  DIM AS STRING Section, Action, FileName, Result
223
224
225
226
227
228
229
230




219
220
221
222
223
224
225

226
227
228
229







-
+
+
+
+
  ELSE
    'User is not logged in
    Result = "403"
  END IF
  SiteContent = Result
  Result = ""
END SUB
      

IF ModuleRequest = ModuleName THEN
  LoadModule = ProcPtr(LoadAdminPanel)
END IF

Changes to modules/modules.bi.

1
2
3

4
5


6

7
8
9
10




























1
2
3
4


5
6
7
8
9

10

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38



+
-
-
+
+

+

-

-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#INCLUDE "..\iguanacms.bi"
#INCLUDE "..\libs\libs.bi"

'Module triggers
'COMMON SHARED CompiledModules() AS STRING
'DIM SHARED ArrayIndex AS SHORT, CacheItem AS STRING, IsCacheable AS SHORT
COMMON SHARED LoadModule AS SUB()
COMMON SHARED ModuleVars AS FUNCTION (Key AS STRING) AS STRING

'Users module public functions
DECLARE FUNCTION IsAuth() AS SHORT
DECLARE SUB LoadUsersInterface()
DECLARE FUNCTION ReadUserData(Key AS STRING) AS STRING
DECLARE SUB LoadAdminPanel()

'Prepare execution parameters
DIM AS STRING Request, PageName, ModuleRequest

'Look for a request
Request = GetURLParam("module", 1)

IF Request <> "" THEN
  IF Request = "pages" THEN
    'Set the page name
    PageName = GetURLParam("pagename", 2)
    IF PageName = "" THEN
      'Set the default page
      PageName = Settings("site_index_page")
    END IF
  ELSE
    'Set the module
    ModuleRequest = Request
  END IF
ELSE
  'Load default settings
  SELECT CASE Settings("site_index_type")
    CASE "page"
      PageName = Settings("site_index_page")
    CASE "module"
      ModuleRequest = Settings("site_index_module")
  END SELECT
END IF

Changes to modules/users.bas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
6
7
8




9
10
11
12
13
14
15








-
-
-
-







'Users module file

#INCLUDE "modules.bi"

CONST AS STRING ModuleName = "users"
DIM SHARED ModulePath AS STRING
ModulePath = "modules" + PATH_DELIMITER + ModuleName + PATH_DELIMITER

'ArrayIndex = UBOUND(CompiledModules) + 1
'REDIM PRESERVE CompiledModules(ArrayIndex)
'CompiledModules(ArrayIndex) = "users"

DIM SHARED AS STRING SessionContent, UserData
CONST AS STRING SessionName = "iguana-token"

'Load the session content into a variable
SessionContent = ReadFile(TempPath + "sessions" + PATH_DELIMITER + SHA256(GetCookie(SessionName)) + ".txt")

FUNCTION ReadSession(Key AS STRING) AS STRING
41
42
43
44
45
46
47
48
49
50

51
52
53
54

55
56
57
58
59
60
61
62
63
37
38
39
40
41
42
43



44




45


46
47
48
49
50
51
52







-
-
-
+
-
-
-
-
+
-
-







END FUNCTION

SUB LoadUsersInterface()
  DIM AS STRING Action, FileContent, TempContent, SessionFile, Result
  DIM AS STRING StoredPassword, Salt, NewSalt, UserAlias, UserEmail, UserToken, UserFile
  DIM AS SHORT SaltLen, TokenLen

  IF CINT(Settings("fancy_url")) THEN
    IF UriPart(1) <> "" THEN
      Action = UriPart(1)
  'Set action
    END IF
  ELSE
    IF QueryString("action") <> "" THEN
      Action = QueryString("action")
  Action = GetURLParam("action", 2)
    END IF
  END IF

  IF Action <> "" THEN
    SELECT CASE Action
      CASE "login"
        SiteTitle = Language("module_users_login")
        Result = LoadTplFile(ModulePath, "login.html")
        UserAlias = ValidateChar(Post("user-alias"))
374
375
376
377
378
379
380





363
364
365
366
367
368
369
370
371
372
373
374







+
+
+
+
+
      CASE "user"
        ReadUserData = SplitVar(UserData, "user_" + Value, LINE_ENDING)
      CASE ELSE
        ReadUserData = Key
    END SELECT
  END IF
END FUNCTION

IF ModuleRequest = ModuleName THEN
  LoadModule = ProcPtr(LoadUsersInterface)
  ModuleVars = ProcPtr(ReadUserData)
END IF