Shembull: ACL sistem me enumerated constants

package main

import "fmt"

const (
    rView = 1 << iota
    rCreate
    rRetrieve
    rUpdate
    rDelete
    rStats
    rLogs
)

func main() {
    Acl := rView | rDelete | rLogs | rStats

    fmt.Println("User's privileges")
    fmt.Printf("View: %v\n", Acl&rView != 0)
    fmt.Printf("Create: %v\n", Acl&rCreate != 0)
    fmt.Printf("Retrieve: %v\n", Acl&rRetrieve != 0)
    fmt.Printf("Update: %v\n", Acl&rUpdate != 0)
    fmt.Printf("Delete: %v\n", Acl&rDelete != 0)
    fmt.Printf("Stats: %v\n", Acl&rStats != 0)
    fmt.Printf("Logs: %v\n", Acl&rLogs != 0)

    if Acl&rDelete != 0 {
        fmt.Println("You can delete the post")
    }
}
https://play.golang.org/p/ukaaV5ggRdQ

Rezultati:

User's privileges
View: true
Create: false
Retrieve: false
Update: false
Delete: true
Stats: true
Logs: true
You can delete the post

Me këtë program, do t’i shfrytëzojmë bitat e konstantave të enumeruara si flag për privilegje të caktuara:

    View: 00000001 ( 1)
  Create: 00000010 ( 2)
Retrieve: 00000100 ( 4)
  Update: 00001000 ( 8)
  Delete: 00010000 (16)
   Stats: 00100000 (32)
    Logs: 01000000 (64)

Në rreshtin 16, variablit acl i japim vlerë asisoj që i cekim privilegjet e dëshiruara duke i ndarë me operatorin OR (|), me çka në fakt formohet një numër me bita të vlerës 1 në pozitat që i korrrespondojnë një privilegji të caktuar.

Kështu, për t’i caktuar një përdoruesi privilegjet rView | rDelete | rLogs | rStats formohet numri binar 01110001 apo 113 decimal.

Kur diku në aplikacion na duhet të verifikojmë nëse përdoruesi e ka NDONJËRIN prej privilegjeve, atëherë variablit që përmban privilegjet e tij (variabli Acl në këtë rast) duhet në njëfarë mënyre ta krahasojmë me privilegjin individual që na intereson, p.sh. a ka të drejtë ai përdorues të fshijë postime.

Për ta realizuar këtë, ndaj variablit Acl veprojmë me operatorin & dhe konstantën e privilegjit që na intereson, pastaj shikojmë nëse nuk është zero:

if (Acl&rDelete != 0) {
    // Fshije postimin
}

Çka në fakt ndodh këtu? Nëse variabli Acl përmban bit me vlerë 1 për privilegjin e fshirjes, edhe konstanta për privilegjin e fshirjes (rDelete) përmban bit me vlerë 1 në po atë pozitë.

Për Acl := rView | rDelete | rLogs | rStats, vlera binare është 01110001, ndërsa për rDelete është 00010000. Shohim se biti i pestë nga e djathta ka vlerën 1 edhe te variabli Acl edhe te konstanta rDelete.

01110001
AND
00010000
=
00010000

Meqenëse variabli Acl dhe konstanta rDelete në bitin e njëjtë kanë 1, rezultati nuk mund të jetë baras me zero; prandaj dhe verifikojmë nëse rezultati i shprehjes Acl&rDelete nuk është zero:

    if Acl&rDelete != 0 {
        fmt.Println("You can update the post")
    }

Pra, me këtë shprehje konstatojmë nëse privilegji për fshirje është i përfshirë në privilegjet e caktuara për këtë përdorues.

Shprehjen e krahasimit e bartim në një funksion në vete, variablin Acl e deklarojmë jashtë blloqeve të funksioneve ashtu që të jetë i qasshëm për funksionet, dhe kështu e fitojmë një kod më elegant:

package main

import "fmt"

const (
    rView = 1 << iota
    rCreate
    rRetrieve
    rUpdate
    rDelete
    rStats
    rLogs
)

var Acl int

func main() {
    Acl = rView | rDelete | rLogs | rStats

    if has(rDelete) {
        fmt.Println("You can delete the post")
    }
}

func has(privilege int) bool {
    return Acl&privilege != 0
}
https://play.golang.org/p/_SFceaBThf2

Rezultati:

You can delete the post
All Rights Reserved Theme by 404 THEME.