Skip to content

Auth overview

INFO

AuthBuilder mirrors SQLBuilder but injects data-scope rules. Actual permission logic lives in your app via dialects and factories.

Terms

  • Word — a scope meaning (e.g. “own rows”, “my org”, “homeroom teacher”).
  • Visitor — who the rule applies to (user, dept, group); known at startup.
  • Resource — menu, button, feature; known at startup.

Built-in keywords: AuthUser, AuthPost, AuthOrg, AuthWord, AuthGoods.

Core types (override in red in original doc)

TypeRole
AuthorBuilderConfigure and run permission wiring
AuthFactoryFactory for keyword entities
AuthDialectLoad/parse users, orgs, posts, words from your schema
PipelineDialectTurn scope codes into prepared word bags
WordBagDialectHolds WordGroupBag groups (OR between groups)
WordGroupBagAND/OR inside a group
WordTranslatorDynamic semantics

Helpers

  • Childable — child collections
  • CodeRange — hierarchical code ranges
  • ItemRange — flat id sets

Example

c#
duty.onEmpty((vf) =>
    {
        if (!string.IsNullOrWhiteSpace(manCode)) { 
            kit.whereIn("a.KB_TaskOID", (m) =>
            {
                m.select("m.KB_Task_FK")
                    .from("KB_TaskManType m")
                    .where("m.KM_Code", manCode);
                if (role != "")
                {
                    m.where("m.KM_Type", role);
                }
            });                    
        }
        return "";
    })
    .onParseWord((word, range) => {
        if (word.scopeCode == "t01")
        {
                kit.whereIn("a.D_OrgOID", (mc) =>
                {
                    mc.select("dw.HH_Org_FK")
                    .from("kb_deptworkor dw")
                    .where("dw.Dw_Code", _userManager.Account);
                });
        }
        return null;
    })
    .useManVisit(manCode)
    .useWordPara("{manCode}", manCode)
    .useOrgVisit(entity.KB_OrgOID)
    .onBuildLiveWord((child, k) => {
        if (child.key == "{taskBase}") {
            child.ApplyToSQL(k);
        }
        else if (child.key == "{taskOrg}" && !string.IsNullOrEmpty(entity.KB_OrgOID))
        {
            kit.whereIn("a.KB_TaskOID", (org) =>
            {
                org.select("o.KB_Task_FK")
                    .from("KB_TaskOrgType o left join ucml_organize uo on uo.Varchar1 = o.KO_Code");
                child.ApplyToSQL(org);
            });
            return;
        }
    })
    .useOrgIsField("a.KB_OrgOID")
    .useOrgLikeField("a.KB_OrgCode")
    .useUseIsField("a.SYS_Created")
    .doBuild();

API sketch

Filtering stage

c#
useGoods(long id=0,string code="",string type="", string group = "2",string name="")
useWordPara(string key,object val)

Build stage — org

c#
whereOrgIs(Func<AuthOrg, string> doOrgFilter)
whereOrgLike(Func<AuthOrg, string> doOrgFilter)
whereOrgIn(Func<List<AuthOrg>, string> doOrgFilter)
whereOrgOne(Func<AuthOrg, bool, string> doOrgFilter)
whereOrgBag(Func<CodeRange<AuthOrg>, string> doOrgFilter)
useOrgOIDFK(string fk)
useOrgCode(string classCodeField)

Users / posts

c#
whereUserIn(Func<List<AuthUser>, string> userFilter)
whereUserIs(Func<AuthUser, string> userFilter)
useUseOIDFK(string fk)
wherePostIs(Func<AuthPost, string> doPostFilter)
wherePostIn(Func<List<AuthPost>, string> doPostFilter)
wherePostLike(Func<AuthPost, string> doPostFilter)
wherePost(Func<AuthPost, bool, string> doPostFilter)

Events

c#
onEmpty(Func<AuthorBuilder<RealDialect>,string> whenRoleIsEmpty)
onLoadedWords(Action<RealDialect> action)
onParseWord(Func<AuthWord, RealDialect, string> parser)
onBuildLiveWord(Action<ConditionGroup, SQLBuilder> registerBuilder)

Members

  • AuthUser authUser
  • WordBagDialect wordBag
  • AuthGoodsBag goodsBag
  • List<AuthWord> dataScopes

Extension (e.g. U8)

c#
public static SQLBuilder useResp(this SQLBuilder kit, ClientUserInfo userManager, Action<RespBuilder> buildAuth)

DutyBuilder — full example

See Chinese doc for the long useDuty sample with useMenu, useVCLink, onloadRole, onParseWord, onBuildLiveWord, onEmpty, whereOrgIn, etc.

Simplified menu-only filter

c#
    .useDuty(_userManager, (duty) =>
    {   
        duty.useMenu(manSeePageId)
            .useLoginVisitBag(true)
            .useUseIsField("a.CON_EMP_NUM")
            .useOrgIsField("b.UCML_OrganizeOID")
            .useOrgLikeField("b.Varchar1")
            .onEmpty((duty) => {
                kit.whereLikeLeft("b.Varchar1", myCode);
                return "";
            })
            .doBuild();
    })

Model

User permission = Resource + Visitor + Words.
Core library handles the pipeline; your project subclasses AuthorBuilder / AuthDialect (e.g. DutyBuilder / DutyLoader).