Giter VIP home page Giter VIP logo

spring-ldap's Introduction

Spring LDAP

Join the chat at https://gitter.im/spring-projects/spring-ldap

Build Status

Revved up by Develocity

Code of Conduct

This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to [email protected].

INTRODUCTION

Spring LDAP is a library to simplify LDAP programming in Java, built on the same principles as Spring Jdbc.

The LdapTemplate class encapsulates all the plumbing work involved in traditional LDAP programming, such as creating, looping through NamingEnumerations, handling Exceptions and cleaning up resources. This leaves the programmer to handle the important stuff - where to find data (DNs and Filters) and what to do with it (map to and from domain objects, bind, modify, unbind, etc.), in the same way that JdbcTemplate relieves the programmer of all but the actual SQL and how the data maps to the domain model.

In addition to this, Spring LDAP provides Exception translation from NamingExceptions to an unchecked exception hierarchy, as well as several utilities for working with filters, LDAP paths and attributes.

For detailed information on the project, please refer to the reference documentation and javadocs. See the changelog for detailed information on changes in the latest version.

MAVEN USERS

All major releases of this library are available in the central Maven repository. The following components are available:

  • spring-ldap-core - the core Spring LDAP library
  • spring-ldap-core-tiger - the Spring LDAP Java 5 support library
  • spring-ldap-test - support classes that help LDAP with integration testing
  • spring-ldap-ldif-core - the Spring LDAP LDIF parsing library
  • spring-ldap-ldif-batch - the Spring Batch integration layer for the LDIF parsing library
  • spring-ldap-odm - The Object-Directory Mapping (ODM) framework

To include e.g. the spring-ldap-core component in your project, use the following dependency tag:

<dependency>
  <groupId>org.springframework.ldap</groupId>
  <artifactId>spring-ldap-core</artifactId>
  <version>2.3.2.RELEASE</version>
</dependency>

Milestone releases (such as release candidates) are available from the Spring framework milestone repo:

<repository>
  <id>spring-milestone</id>
  <name>Spring Portfolio Milestone Repository</name>
  <url>https://maven.springframework.org/milestone</url>
</repository>

Snapshot builds produced by the CI builds are available from the Spring framework snapshot repo:

<repository>
  <id>spring-milestone</id>
  <name>Spring Portfolio Milestone Repository</name>
  <url>https://maven.springframework.org/snapshot</url>
</repository>

In order to e.g. try out the latest build snapshot of the core module, include the repository above and use the following dependency tag:

<dependency>
  <groupId>org.springframework.ldap</groupId>
  <artifactId>spring-ldap-core</artifactId>
  <version>2.0.M1.CI-SNAPSHOT</version>
</dependency>

Note that while all milestone and snapshot builds have passed the (quite extensive) test suite, the artifacts here are obviously still work in progress. Feel free to use them for trying out new functionality and bug fixes for an upcoming version. Please report any problems or bugs in the issue tracker.

ADDITIONAL RESOURCES

spring-ldap's People

Contributors

andrei-ivanov avatar antoine777 avatar bryant1410 avatar dertobsch avatar eddumelendez avatar github-actions[bot] avatar gitter-badger avatar haarolean avatar jgrandja avatar jprinet avatar jzheaux avatar kiliankrause avatar kimsaabyepedersen avatar kwin avatar marcusdacoregio avatar marthursson avatar mfijas avatar mitch-mueller avatar nebhale avatar orlandosso avatar palfvin avatar parkerm avatar perry2of5 avatar rwinch avatar sjohnr avatar spring-builds avatar spring-operator avatar thepetrov avatar thomasdarimont avatar wilkinsona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spring-ldap's Issues

LDAP-34: Move itest-targets.xml to common-build

Ulrik Sandberg(Migrated from LDAP-34) said:

Both spring-ldap and sandbox have identical copies of itest-targets.xml, mainly because we shared common-build with other projects previously. Now we can move those to common-build and perhaps also get rid of some unnecessary overrides in the build.xml files.

LDAP-39: Provide utility method for simple authentication

Ulrik Sandberg(Migrated from LDAP-39) said:

A popular request is that Spring LDAP should provide a simple authentication mechanism for those that don’t need the full power of Acegi Security. One approach that seems to work is this (taken from the forum http://forum.springframework.org/showthread.php?t=29063):

public boolean checkPassword(String login, String password) {
log.debug(“LdapServiceDao::checkPassword()”);

```
// Construction du DN
DistinguishedName dn = new DistinguishedName(“ou=People,dc=univ,dc=fr”);
dn.append(new DistinguishedName(getUserDn(login)));

// Connexion manuelle
LdapContextSource ctxSource = new LdapContextSource();
ctxSource.setUrl(url);
ctxSource.setUserName(dn.encode());
ctxSource.setPassword(password);
ctxSource.setPooled(false);
try {
ctxSource.afterPropertiesSet();
ctxSource.getReadWriteContext();
return true;
}
catch(Exception e) {
return false;
}
}
```

LDAP-15: DirContextAdapter.setAttribute()

Jasper Blues(Migrated from LDAP-15) said:

DirContextAdapter.setAttributeValue(String, Object) and setAttributeValues(String, Object[]) add the attribute to DirContextAdapter.attrs or DirContextAdapter.updateAttrs (depending on updateMode) while setAttribute() does not.

Hence, calling setAttribute does not result in a ModificationItem.

LDAP-7: Implement destroySubContext

Ulrik Sandberg(Migrated from LDAP-7) said:

The destroySubContext operation should be implemented. There are two variants of it: void destroySubcontext(Name name) Destroys the named context and removes it from the namespace. void destroySubcontext(String name) Destroys the named context and removes it from the namespace.

Recursive delete should also be handled.

LDAP-2: Support multi-valued distinguished names

Ulrik Sandberg(Migrated from LDAP-2) said:

The RFC2253 specifies that a distinguished name should be able to have multi-valued RDNs separated by a ‘+’ sign, like “cn=Rod+sn=Johnson”, for example. There is a working parser written in C# here: http://www.codeproject.com/cs/internet/dnparser.asp

LDAP-13: DirContextAdapter.getModificationItems() returns password when password unchanged

Jasper Blues(Migrated from LDAP-13) said:

Hello,
- We have a Person.java pojo containing a password property of type byte[]. The password property is set to and from the Sun Directory Server using a ContextMapper/ContextAssembler implementation.
- Problem: DirContextAdapter.getModificationsItems() always returns the password attribute as an updated attribute. This is due to byte arrays having a different hashcode despite identical content. Therefore b1[].equals(b2[]) returns false.

This could be a problem say if:
- Service subscriber 1 gets a handle to a Person pojo
- Service subscriber 2 gets a handle to a Person pojo, updates password attribute and saves.
- Service subscriber 1 updates “golden rating” attribute and saves. The new password is blown away.

Suggested Solution: Perhaps DirContextAdapter.isChanged() should use Arrays.equals(byte[], byte[]) for attributes of type byte[].

Best Regards,
Jasper

LDAP-47: Code example in section 4.1 of the documentation is incorrect

Michael Watson(Migrated from LDAP-47) said:

The last few lines of example 4.1 and 4.2 are incorrect. They are currently:

4.1
NameClassPairCallbackHandler handler =
ldapTemplate.new AttributesMapperCallbackHandler(new PersonAttributesMapper());

```
return ldapTemplate.search(executor, handler);
```

4.2
NameClassPairCallbackHandler handler =
ldapTemplate.new ContextMapperCallbackHandler(new PersonContextMapper());

```
return ldapTemplate.search(executor, handler);
```

They should be:

4.1
CollectingNameClassPairCallbackHandler handler =
ldapTemplate.new AttributesMapperCallbackHandler(new PersonAttributesMapper());

```
ldapTemplate.search(executor, handler);
return handler.getList();
```

4.2
CollectingNameClassPairCallbackHandler handler =
ldapTemplate.new ContextMapperCallbackHandler(new PersonContextMapper());

```
ldapTemplate.search(executor, handler);
return handler.getList();
```

Thanks to Ulrik Sandberg for the correct code.

LDAP-30: BadLdapGrammarException: RDN could not be parsed fully

Domagoj Madunic(Migrated from LDAP-30) said:

While trying to perform a simple search on InetOrgPersonObjects, via criteria uid=something

I encountered the following error:

org.acegisecurity.ldap.LdapDataAccessException: Failed to fetch user for username: dmadunic; nested exception is org.springframework.ldap.UncategorizedLdapExceptio n: Operation failed; nested exception is javax.naming.NamingException: problem generating object using object factory [Root exception is org.springframework.ldap.BadLdapGrammarException: RDN could not be parsed fully, remaining ‘c’]; remaining name ‘ou=croz,ou=Users’
org.springframework.ldap.UncategorizedLdapExceptio n: Operation failed; nested exception is javax.naming.NamingException: problem generating object using object factory [Root exception is org.springframework.ldap.BadLdapGrammarException: RDN could not be parsed fully, remaining ‘c’]; remaining name ‘ou=croz,ou=Users’
javax.naming.NamingException: problem generating object using object factory. Root exception is org.springframework.ldap.BadLdapGrammarException: RDN could not be parsed fully, remaining ‘c’
at org.springframework.ldap.support.LdapEncoder.nameD ecode(LdapEncoder.java:226)
at org.springframework.ldap.support.LdapRdnComponent. (LdapRdnComponent.java:69)
at org.springframework.ldap.support.DnParserImpl.attr ibuteTypeAndValue(DnParserImpl.java:112)
at org.springframework.ldap.support.DnParserImpl.rdn( DnParserImpl.java:62)
at org.springframework.ldap.support.DnParserImpl.dn(D nParserImpl.java:27)
at org.springframework.ldap.support.DistinguishedName .parse(DistinguishedName.java:130)
at org.springframework.ldap.support.DistinguishedName .(DistinguishedName.java:89)
at org.springframework.ldap.support.DirContextAdapter .(DirContextAdapter.java:131)
at org.springframework.ldap.support.DefaultDirObjectF actory.getObjectInstance(DefaultDirObjectFactory.j ava:56)
at javax.naming.spi.DirectoryManager.createObjectFrom Factories(DirectoryManager.java:228)
at javax.naming.spi.DirectoryManager.getObjectInstanc e(DirectoryManager.java:207)
at com.sun.jndi.ldap.LdapSearchEnumeration.createItem (LdapSearchEnumeration.java:118)
at com.sun.jndi.ldap.LdapNamingEnumeration.nextAux(Ld apNamingEnumeration.java:272)
at com.sun.jndi.ldap.LdapNamingEnumeration.nextImpl(L dapNamingEnumeration.java:252)
at com.sun.jndi.ldap.LdapNamingEnumeration.next(LdapN amingEnumeration.java:200)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:271)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:231)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:561)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:475)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:423)
at org.springframework.ldap.LdapTemplate.search(LdapT emplate.java:444)

This error occurs only with Ldap entires which have DN with national characters! When search is performed for entry with DN without national characters all goes well!

LDAP-14: Exceptions not Serializable

Jasper Blues(Migrated from LDAP-14) said:

Hello

We have a remote service utilizing Spring-Ldap. We’d like to be able to return exceptions to the service caller, however they’re not Serializable

Perhaps it is the wrapped NamingException that is not Serializable. My preference is for the exceptions to be serializable (perhaps there are other points of view), therefore I’d suggest to wrap the stack trace and message from NamingException and discard the non-Serializable part.

Regards,
Jasper

LDAP-50: BadLdapGrammarException when a group or principal contains a '\' in its name

Justin Koke(Migrated from LDAP-50) said:

Hi Guys,

Here is the relevant issue that we have created in Crowd: http://jira.atlassian.com/browse/CWD-183

A quick summary:

If a group contains a ‘\’ we get the following exception:
javax.naming.NamingException: problem generating object using object factory [Root exception is org.springframework.ldap.BadLdapGrammarException: Failed to parse DN; nested exception is org.springframework.ldap.support.TokenMgrError: Lexical error at line 1, column 22. Encountered: “\” (92), after : ""]; remaining name ‘dc=ad,dc=atlassian,dc=com’
at com.sun.jndi.ldap.LdapSearchEnumeration.createItem(LdapSearchEnumeration.java:111)
at com.sun.jndi.ldap.LdapNamingEnumeration.nextAux(LdapNamingEnumeration.java:256)
at com.sun.jndi.ldap.LdapNamingEnumeration.nextImpl(LdapNamingEnumeration.java:236)
at com.sun.jndi.ldap.LdapNamingEnumeration.next(LdapNamingEnumeration.java:184)
at org.springframework.ldap.LdapTemplate.search(LdapTemplate.java:271)

If a group contains a ‘/’ we get this exception:
org.springframework.ldap.UncategorizedLdapException: Operation failed; nested exception is javax.naming.NamingException: [LDAP: error code 1 – 000020D6: SvcErr: DSID-031006CC, problem 5012 (DIR_ERROR), data 0]; remaining name ‘cn=Website Feedback/Support, ou=Groups, dc=ad, dc=atlassian, dc=com’
javax.naming.NamingException: [LDAP: error code 1 – 000020D6: SvcErr: DSID-031006CC, problem 5012 (DIR_ERROR), data 0
remaining name ‘cn=Website Feedback/Support, ou=Groups, dc=ad, dc=atlassian, dc=com’
at com.sun.jndi.ldap.LdapCtx.mapErrorCode(LdapCtx.java:3025)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2931)
at com.sun.jndi.ldap.LdapCtx.processReturnCode(LdapCtx.java:2737)
at com.sun.jndi.ldap.LdapCtx.c_lookup(LdapCtx.java:993)
at com.sun.jndi.toolkit.ctx.ComponentContext.c_resolveIntermediate_nns(ComponentContext.java:152)
at com.sun.jndi.toolkit.ctx.AtomicContext.c_resolveIntermediate_nns(AtomicContext.java:342)
at com.sun.jndi.toolkit.ctx.ComponentContext.p_resolveIntermediate(ComponentContext.java:381)
at com.sun.jndi.toolkit.ctx.ComponentDirContext.p_search(ComponentDirContext.java:360)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:338)
at com.sun.jndi.toolkit.ctx.PartialCompositeDirContext.search(PartialCompositeDirContext.java:321)
at javax.naming.directory.InitialDirContext.search(InitialDirContext.java:248)
at org.springframework.ldap.LdapTemplate$4.executeSearch(LdapTemplate.java:227)

If you could shed any light onto this or point us in the right direction we will continue to investigate.

Cheers,
Justin

LDAP-24: Make person sample handle groups

Ulrik Sandberg(Migrated from LDAP-24) said:

The person sample currently uses Spring MVC for displaying a simple search result, from where the user can view or delete the entries, depending on the user’s privileges. The sample should be able to handle access groups, as it is the standard way of assigning privileges in LDAP. This will increase the number of search-result-view-edit flows in the applications. In order to simplify the handling of flows, the sample app should also be converted to Spring WebFlow 1.0. In doing so, we get re-usable flows that are described in readable XML.

LDAP-40: Documentation error

Mayank Kumar(Migrated from LDAP-40) said:

Document – Single Page HTML reference.

In section 2.1, example 2.2

the line of code – “private class PersonAttributesMapper implements AttributesMapper() {”

should be changed to – “private class PersonAttributesMapper implements AttributesMapper {”

The braces after the AttributesMapper is incorrect.

LDAP-41: Documentation error 2

Mayank Kumar(Migrated from LDAP-41) said:

Document – Single Page HTML Reference

Example 2.2 in Section 2.1

Original Code -

public List getAllPersons() { return ldapTemplate.search("", “(objectclass=person)”, new PersonAttributesMapper(); }

Should be changed to

public List getAllPersons() {
return ldapTemplate.search("", “(objectclass=person)”, new PersonAttributesMapper());
}

The closing bracket for the ldapTemplate.search() method is missing.

LDAP-36: Ldap Person example using OpenLDAP

Julio cesar(Migrated from LDAP-36) said:

Hi,

What changes do I have to make to the ldap-person example run in openLDAP instead of ApacheDS?

thank you,
Julio Cesar


Basically it should be sufficient to comment the line in src/main/webapp/WEB-INF/applicationContext.xml which imports apacheDsContext.xml and edit ldap.properties in the same directory to point to the appropriate server.

Some data is expected to be present in the target LDAP server, defined in src/main/java/setup_data.ldif.


Mattias Arthursson
Jayway AB (www.jayway.se)
Spring-LDAP project member


Yeah, I´ve done exactly that, but it didn´t worked. It gives me “Bad credential” error. My steps:
1. Comment import(apacheDS)
2. Populate openLDAP with base_data.ldif and setup_data.ldif
3. Replace user(cn=Manager) and password(secret).
4. Run…
5. “Bad Credentials”

Julio Cesar


Ah, right, you’ll need to change in applicationContext-acegi-security.xml to run against your OpenLDAP server as well (in ContextFactory definition). That’s nasty – it should be taken from the properties file. Might I ask you to post a Jira issue so we don’t lose track of that problem.


Mattias Arthursson
Jayway AB (www.jayway.se)

  1. Spring-LDAP project member

LDAP-26: PagedResultsRequestControl failing when used with AD

adam goode(Migrated from LDAP-26) said:

Bug raised in response to following post on the spring ldap forum http://forum.springframework.org/showthread.php?t=32330

In an AD environment when using the Paged Results functionality after successfully retrieving and iterating over the returned results upto the set paged results size, the last call to results.hasMore() throws a PartialResultsException with a message of “Unprocessesed continuation reference”

This then causes the processor.postProcess(ctx) call to be missed meaning a cookie is never set to anything apart from null, meaning no more results can be returned. (this is all within the ldaptemplate::search(SearchExecutor se, NameClassPairCallbackHandler handler,DirContextProcessor processor) function)

Reply to original post on the forums indicates this is an issue with the way the exception handling works for that exception.

Same result is seen in both 1.1.1 and 1.1.2

LDAP-38: Provide utility method for retrieving supported controls from the directory server

Ulrik Sandberg(Migrated from LDAP-38) said:

The following ldapsearch gets all supported controls from the server:

% ldapsearch -s base “(objectclass=*)” supportedcontrol
supportedcontrol=2.16.840.1.113730.3.4.2
supportedcontrol=1.3.18.0.2.10.5

Perhaps it could be useful with a utility method that returned this information. In plain JNDI, the above ldapsearch is coded like this:

```
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY, “com.sun.jndi.ldap.LdapCtxFactory”);
env.put(Context.PROVIDER_URL, “ldap://localhost:389/”);

InitialDirContext ctx = new InitialDirContext(env);
Attributes attrs = ctx.getAttributes("", new String[] { “supportedcontrol” });

Attribute attr = attrs.get(“supportedcontrol”);
for (int i = 0; i < attr.size(); +i) {
System.out.println(attr.getID()
“=”+attr.get(i));
}
```

LDAP-37: Controls[] java.lang.NullPointerException when performing PagedResultsRequestControl search

Justen Stepka(Migrated from LDAP-37) said:

http://forum.springframework.org/showthread.php?p=96427#post96427


        Control[] requestControls = ldapContext.getRequestControls();
        Control newControl = createRequestControl();

```
    Control[] newControls = new Control[requestControls.length + 1];
    for (int i = 0; i < requestControls.length; i++) {
        newControls[i] = requestControls[i];
    }
```

new Control(int) needs to perform a null pointer check.


LDAP-48: Code example in section 2.1 of the documentation is incorrect

Michael Watson(Migrated from LDAP-48) said:

The code for the PersonAttributesMapper in example 2.2 is:

private class PersonAttributesMapper implements AttributesMapper() { public Object mapFromAttributes(Attributes attrs) throws NamingException { Person person = new Person(); person.setFullName((String)attrs.get(“cn”).get()); person.setLastName((String)attrs.get(“sn”).get()); person.setDescription((String)attrs.get(“description”).get()); return person; } }

The () after the implements AttributesMapper causes a problem and should be removed.

It might also be worth mentioning at some point that this code causes all the attributes to be returned (not just the ones being mapped) and that you can use the setReturnedAttributes method on the SearchControls class to only return the attributes you need. Would be very helpful to LDAP noobs like myself.

LDAP-28: Pre-encoded search filters

Justen Stepka(Migrated from LDAP-28) said:

Currently all of the search filters require everything to be entered as a key/value pair. Add a filter that allows to the user to specify a filter, common when reading configuration files:

(objectClass=user)(!(objectClass=computer))

Attached is the implementation we are using for Crowd.

LDAP-46: DirContextAdapter.getModificatioItems() doesnt ignore case when collecting values to be removed and added.

Vikash Trivedi(Migrated from LDAP-46) said:

DirContextAdapter.getModicationItems() calls collectModifications() to collect the modification items. The section handling multi-valued attributes uses CollectionUtils to return a new list that will contain a substraction of the old values from the new values, but the substraction doesnt handle case insensitivity thus resulting in a list of items that require to be added which already exist in the Directory Server with a different case and resulting in an ATTRIBUTE_ALREADY_EXISIT error. See below:
else {
// Collect all modifications to attribute individually (this also
// covers additions to a previously non-existant attribute).
Collection oldValues = new LinkedList();
Collection newValues = new LinkedList();

```
collectAttributeValues(oldValues, currentAttribute);
collectAttributeValues(newValues, changedAttr);
Collection myModifications = new LinkedList();

Collection addedValues = CollectionUtils.subtract(newValues, oldValues); // WILL ALSO RETURN VALUES TO BE ADDED THAT ARE ALREADY IN LDAP IF CASE IS DIFFERENT. Collection removedValues = CollectionUtils.subtract(oldValues, newValues); // WILL ALSO RETURN VALUES TO BE ADDED THAT ARE ALREADY IN LDAP IF CASE IS DIFFERENT. collectModifications(DirContext.ADD_ATTRIBUTE, changedAttr, addedValues, myModifications); collectModifications(DirContext.REMOVE_ATTRIBUTE, changedAttr, removedValues, myModifications); if (myModifications.isEmpty()) { // This means that the attributes are not equal, but the // actual values are the same – thus the order must have // changed. This should result in a REPLACE_ATTRIBUTE operation. myModifications.add(new ModificationItem( DirContext.REPLACE_ATTRIBUTE, changedAttr)); }

```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.